@@ -36,6 +36,7 @@ internal class ProcessedLanguageSet(dataList: List<LanguageData>) : IProcessedLa
36
36
private lateinit var uid2language: Map <String , ProcessedLanguage >
37
37
private lateinit var fqName2concept: Map <String , ProcessedConcept >
38
38
private lateinit var uid2concept: Map <String , ProcessedConcept >
39
+ private lateinit var conceptFqName2RootMetaProperties: MutableMap <String , MutableSet <String >>
39
40
40
41
init {
41
42
load(dataList)
@@ -62,6 +63,18 @@ internal class ProcessedLanguageSet(dataList: List<LanguageData>) : IProcessedLa
62
63
initIndexes()
63
64
resolveConceptReferences()
64
65
fixRoleConflicts()
66
+ propagateMetaProperties()
67
+ }
68
+
69
+ private fun propagateMetaProperties () {
70
+ conceptFqName2RootMetaProperties = mutableMapOf ()
71
+ val concepts = languages.flatMap { it.getConcepts() }
72
+ concepts.forEach { concept ->
73
+ val keys = concept.metaProperties.keys
74
+ // TODO the computation of rootConcept will visit some concepts multiple times across loop iterations; could potentially be optimized
75
+ val rootConcept = concept.getNonInterfaceRootConcept()
76
+ conceptFqName2RootMetaProperties.getOrPut(rootConcept.fqName()) { mutableSetOf () }.addAll(keys)
77
+ }
65
78
}
66
79
67
80
private fun initIndexes () {
@@ -137,6 +150,10 @@ internal class ProcessedLanguageSet(dataList: List<LanguageData>) : IProcessedLa
137
150
fun getLanguages (): List <ProcessedLanguage > {
138
151
return languages
139
152
}
153
+
154
+ fun getMetaPropertyRoots (fqConceptName : String ): Set <String > {
155
+ return conceptFqName2RootMetaProperties[fqConceptName] ? : emptySet()
156
+ }
140
157
}
141
158
142
159
internal class ProcessedLanguage (var name : String , var uid : String? ) {
@@ -162,7 +179,14 @@ internal class ProcessedLanguage(var name: String, var uid: String?) {
162
179
fun load (dataList : List <ConceptData >) {
163
180
for (data in dataList) {
164
181
addConcept(
165
- ProcessedConcept (data.name, data.uid, data.abstract, data.extends.map { ProcessedConceptReference (it) }.toMutableList(), data.deprecationMessage).also { concept ->
182
+ ProcessedConcept (
183
+ data.name,
184
+ data.uid,
185
+ data.abstract,
186
+ data.extends.map { ProcessedConceptReference (it) }.toMutableList(),
187
+ data.deprecationMessage,
188
+ data.metaProperties,
189
+ ).also { concept ->
166
190
concept.loadRoles(data)
167
191
},
168
192
)
@@ -220,6 +244,7 @@ internal class ProcessedConcept(
220
244
var abstract : Boolean ,
221
245
val extends : MutableList <ProcessedConceptReference >,
222
246
override var deprecationMessage : String? ,
247
+ val metaProperties : MutableMap <String , String >,
223
248
) : IProcessedDeprecatable {
224
249
lateinit var language: ProcessedLanguage
225
250
private val roles: MutableList <ProcessedRole > = ArrayList ()
@@ -253,6 +278,17 @@ internal class ProcessedConcept(
253
278
fun getAllSuperConcepts (): Sequence <ProcessedConcept > = getAllSuperConcepts_().distinct()
254
279
fun getAllSuperConceptsAndSelf (): Sequence <ProcessedConcept > = getAllSuperConceptsAndSelf_().distinct()
255
280
fun getDuplicateSuperConcepts () = getAllSuperConcepts_().groupBy { it }.filter { it.value.size > 1 }.map { it.key }
281
+
282
+ fun getNonInterfaceSuperConcept () = getDirectSuperConcepts().firstOrNull()
283
+ fun getNonInterfaceRootConcept (): ProcessedConcept {
284
+ var current: ProcessedConcept ? = this
285
+ var result = this
286
+ while (current != null ) {
287
+ result = current
288
+ current = current.getNonInterfaceSuperConcept()
289
+ }
290
+ return result
291
+ }
256
292
}
257
293
258
294
internal sealed class ProcessedRole (
0 commit comments