Skip to content

Commit

Permalink
don't assume that all of lang.structure is indexed
Browse files Browse the repository at this point in the history
  • Loading branch information
dslmeinte committed Jul 2, 2019
1 parent 789cb46 commit bca313c
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 50 deletions.
2 changes: 1 addition & 1 deletion mps-inspector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>nl.dslconsultancy.mps</groupId>
<artifactId>mps-inspector</artifactId>
<version>0.2.0</version>
<version>0.2.1</version>
<packaging>jar</packaging>

<name>MPS Inspector</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ fun Language.structureModelPath(): Path = path.parent.resolve("models").resolve(

fun Language.structure(): Structure {
if (cachedStructure == null) {
cachedStructure = modelXmlFromDisk(structureModelPath()).asStructure()
try {
cachedStructure = modelXmlFromDisk(structureModelPath()).asStructure()
} catch (e: Exception) {
System.err.println("could not read structure model XML file for language '$name'; due to:")
System.err.println(e.message)
e.printStackTrace(System.err)
}
}
return cachedStructure!!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ fun modelXmlWithoutNodesFromDisk(path: Path): ModelXmlWithoutNodes = xmlFromDisk

fun ModelXml.metaConcepts(): List<MetaConceptXml> = registry?.languages?.flatMap { it.metaConcepts } ?: emptyList()

fun Iterable<MetaConceptXml>.named(name: String): MetaConceptXml = single { it.name.lastSection() == name }
fun Iterable<MetaConceptXml>.named(name: String): MetaConceptXml? = firstOrNull { it.name.lastSection() == name }

fun Iterable<MetaConceptXml>.byIndex(index: String): MetaConceptXml = single { it.index == index }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fun ModelXml.asStructure(): Structure {
val metaConcepts = metaConcepts()
val memois = hashMapOf<String, Any>()
val modelXml = this
val supported = listOf("ConceptDeclaration", "InterfaceConceptDeclaration").map { metaConcepts.named(it).index }
val supported = listOf("ConceptDeclaration", "InterfaceConceptDeclaration").mapNotNull { metaConcepts.named(it) }.map { it.index }
return Structure(
elements = modelXml.nodes.filter { supported.contains(it.concept) }.map { it.fromXml(metaConcepts, memois) as StructuralElement }
)
Expand All @@ -23,58 +23,67 @@ private fun NodeXml.fromXml(metaConcepts: List<MetaConceptXml>, memois: Map<Stri

fun isDeprecated(): Boolean =
nodeXml
.theseChildren(metaConcepts.named("BaseConcept").children.named("smodelAttribute"))
.theseChildren(metaConcepts.named("BaseConcept")?.children?.named("smodelAttribute"))
.any { metaConcepts.byIndex(it.concept).name.endsWith("DeprecatedNodeAnnotation") }

val metaConcept = metaConcepts.byIndex(nodeXml.concept)

val abstractConceptDeclaration = metaConcepts.named("AbstractConceptDeclaration")!!
val iNamedConcept = metaConcepts.named("INamedConcept")!!

return when (metaConcept.name.lastSection()) {
"ConceptDeclaration" -> memois.of(nodeXml to Concept(
name = nodeXml.thisProperty(metaConcepts.named("INamedConcept").properties.named("name"))!!,
isInterface = false,
rootable = nodeXml.thisProperty(metaConcepts.named("ConceptDeclaration").properties.named("rootable")).orEmpty() == "true",
alias = nodeXml.thisProperty(metaConcepts.named("AbstractConceptDeclaration").properties.named("conceptAlias")),
shortDescription = nodeXml.thisProperty(metaConcepts.named("AbstractConceptDeclaration").properties.named("conceptShortDescription")),
deprecated = isDeprecated()
)).apply {
extends = nodeXml.thisReference(metaConcepts.named("ConceptDeclaration").references.named("extends"))?.resolve
implements = nodeXml.theseChildren(metaConcepts.named("ConceptDeclaration").children.named("implements")).mapNotNull {
it.thisReference(
metaConcepts.named("InterfaceConceptReference").references.named("intfc")
)?.resolve
"ConceptDeclaration" -> {
val conceptDeclaration = metaConcepts.named("ConceptDeclaration")!!
memois.of(nodeXml to Concept(
name = nodeXml.thisProperty(iNamedConcept.properties.named("name"))!!,
isInterface = false,
rootable = nodeXml.thisProperty(conceptDeclaration.properties.named("rootable")).orEmpty() == "true",
alias = nodeXml.thisProperty(abstractConceptDeclaration.properties.named("conceptAlias")),
shortDescription = nodeXml.thisProperty(abstractConceptDeclaration.properties.named("conceptShortDescription")),
deprecated = isDeprecated()
)).apply {
extends = nodeXml.thisReference(conceptDeclaration.references.named("extends"))?.resolve
implements = nodeXml.theseChildren(conceptDeclaration.children.named("implements")).mapNotNull {
it.thisReference(
metaConcepts.named("InterfaceConceptReference")?.references?.named("intfc")
)?.resolve
}
features = listOf(
nodeXml.theseChildren(abstractConceptDeclaration.children.named("propertyDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature },
nodeXml.theseChildren(abstractConceptDeclaration.children.named("linkDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature }
).flatten()
}
features = listOf(
nodeXml.theseChildren(metaConcepts.named("AbstractConceptDeclaration").children.named("propertyDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature },
nodeXml.theseChildren(metaConcepts.named("AbstractConceptDeclaration").children.named("linkDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature }
).flatten()
}
"InterfaceConceptDeclaration" -> memois.of(nodeXml to Concept(
name = nodeXml.thisProperty(metaConcepts.named("INamedConcept").properties.named("name"))!!,
name = nodeXml.thisProperty(iNamedConcept.properties.named("name"))!!,
isInterface = true,
rootable = false,
alias = nodeXml.thisProperty(metaConcepts.named("AbstractConceptDeclaration").properties.named("conceptAlias")),
shortDescription = nodeXml.thisProperty(metaConcepts.named("AbstractConceptDeclaration").properties.named("conceptShortDescription")),
alias = nodeXml.thisProperty(abstractConceptDeclaration.properties.named("conceptAlias")),
shortDescription = nodeXml.thisProperty(abstractConceptDeclaration.properties.named("conceptShortDescription")),
deprecated = isDeprecated()
)).apply {
implements = nodeXml.theseChildren(metaConcepts.named("InterfaceConceptDeclaration").children.named("extends")).mapNotNull {
implements = nodeXml.theseChildren(metaConcepts.named("InterfaceConceptDeclaration")?.children?.named("extends")).mapNotNull {
it.thisReference(
metaConcepts.named("InterfaceConceptReference").references.named("intfc")
metaConcepts.named("InterfaceConceptReference")?.references?.named("intfc")
)?.resolve
}
features = listOf(
nodeXml.theseChildren(metaConcepts.named("AbstractConceptDeclaration").children.named("propertyDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature },
nodeXml.theseChildren(metaConcepts.named("AbstractConceptDeclaration").children.named("linkDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature }
nodeXml.theseChildren(abstractConceptDeclaration.children.named("propertyDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature },
nodeXml.theseChildren(abstractConceptDeclaration.children.named("linkDeclaration")).map { it.fromXml(metaConcepts, memois) as Feature }
).flatten()
}
"LinkDeclaration" -> memois.of(nodeXml to Link(
name = thisProperty(metaConcepts.named("LinkDeclaration").properties.named("role"))!!,
deprecated = isDeprecated(),
reference = thisProperty(metaConcepts.named("LinkDeclaration").properties.named("metaClass"))!! == "reference",
cardinality = thisProperty(metaConcepts.named("LinkDeclaration").properties.named("sourceCardinality")) ?: "0..1",
targetType = thisReference(metaConcepts.named("LinkDeclaration").references.named("target"))!!.resolve!!
))
"LinkDeclaration" -> {
val linkDeclaration = metaConcepts.named("LinkDeclaration")!!
memois.of(nodeXml to Link(
name = thisProperty(linkDeclaration.properties.named("role"))!!,
deprecated = isDeprecated(),
reference = thisProperty(linkDeclaration.properties.named("metaClass"))!! == "reference",
cardinality = thisProperty(linkDeclaration.properties.named("sourceCardinality")) ?: "0..1",
targetType = thisReference(linkDeclaration.references.named("target"))!!.resolve!!
))
}
"PropertyDeclaration" -> memois.of(nodeXml to Property(
name = nodeXml.thisProperty(metaConcepts.named("INamedConcept").properties.named("name"))!!,
name = nodeXml.thisProperty(iNamedConcept.properties.named("name"))!!,
deprecated = isDeprecated()
))
else -> throw Error("concept without Kotlin class: ${metaConcept.name}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.nio.file.Paths
import kotlin.test.Test
import kotlin.test.assertEquals

fun NodeXml.fromXml(concepts: List<MetaConceptXml>, memois: Map<String, Any>): Any {
private fun NodeXml.fromXml(concepts: List<MetaConceptXml>, memois: Map<String, Any>): Any {
val nodeXml = this
val precomputed = memois[nodeXml.id]
if (precomputed != null) {
Expand All @@ -15,30 +15,30 @@ fun NodeXml.fromXml(concepts: List<MetaConceptXml>, memois: Map<String, Any>): A
val concept = concepts.byIndex(nodeXml.concept)
return when (concept.name.lastSection()) {
"JsonArray" -> memois.of(nodeXml to JsonArray()).apply {
items = nodeXml.theseChildren(concepts.named("JsonArray").children.named("items")).map { it.fromXml(concepts, memois) as IJsonValue }
items = nodeXml.theseChildren(concepts.named("JsonArray")!!.children.named("items")).map { it.fromXml(concepts, memois) as IJsonValue }
}
"JsonBoolean" -> memois.of(nodeXml to JsonBoolean(
value = nodeXml.thisProperty(concepts.named("JsonBoolean").properties.named("value")) == "true"
value = nodeXml.thisProperty(concepts.named("JsonBoolean")!!.properties.named("value")) == "true"
))
"JsonFile" -> memois.of(nodeXml to JsonFile(
name = nodeXml.thisProperty(concepts.named("INamedConcept").properties.named("name"))!!
name = nodeXml.thisProperty(concepts.named("INamedConcept")!!.properties.named("name"))!!
)).apply {
contents = nodeXml.theseChildren(concepts.named("JsonFile").children.named("contents")).firstOrNull()?.fromXml(concepts, memois) as IJsonValue
contents = nodeXml.theseChildren(concepts.named("JsonFile")!!.children.named("contents")).firstOrNull()?.fromXml(concepts, memois) as IJsonValue
}
"JsonNull" -> memois.of(nodeXml to IJsonValue.JsonNull)
"JsonNumber" -> memois.of(nodeXml to JsonNumber(
value = nodeXml.thisProperty(concepts.named("JsonNumber").properties.named("value"))!!
value = nodeXml.thisProperty(concepts.named("JsonNumber")!!.properties.named("value"))!!
))
"JsonObject" -> memois.of(nodeXml to JsonObject()).apply {
pairs = nodeXml.theseChildren(concepts.named("JsonObject").children.named("pairs")).map { it.fromXml(concepts, memois) as JsonPair }
pairs = nodeXml.theseChildren(concepts.named("JsonObject")!!.children.named("pairs")).map { it.fromXml(concepts, memois) as JsonPair }
}
"JsonPair" -> memois.of(nodeXml to JsonPair(
name = nodeXml.thisProperty(concepts.named("INamedConcept").properties.named("name"))!!
name = nodeXml.thisProperty(concepts.named("INamedConcept")!!.properties.named("name"))!!
)).apply {
value = nodeXml.theseChildren(concepts.named("JsonPair").children.named("value")).firstOrNull()?.fromXml(concepts, memois) as IJsonValue
value = nodeXml.theseChildren(concepts.named("JsonPair")!!.children.named("value")).firstOrNull()?.fromXml(concepts, memois) as IJsonValue
}
"JsonString" -> memois.of(nodeXml to JsonString(
value = nodeXml.thisProperty(concepts.named("JsonString").properties.named("value"))!!
value = nodeXml.thisProperty(concepts.named("JsonString")!!.properties.named("value"))!!
))
else -> throw Error("concept without Kotlin class: ${concept.name}")
}
Expand Down
12 changes: 12 additions & 0 deletions mps-inspector/src/test/resources/tryOnOwn.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
{
"languageName": "JsonSchema",
"generationPath": "src/generated"
},
{
"languageName": "WSDL",
"generationPath": "src/generated"
},
{
"languageName": "XSD",
"generationPath": "src/generated"
},
{
"languageName": "XmlWithExtension",
"generationPath": "src/generated"
}
]
}
6 changes: 3 additions & 3 deletions mps-open-source/.mps/modules.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MPSProject">
<component>
<projectModules>
<modulePath path="$PROJECT_DIR$/solutions/Examples/Examples.msd" folder="" />
<modulePath path="$PROJECT_DIR$/languages/Json/Json.mpl" folder="" />
<modulePath path="$PROJECT_DIR$/languages/JsonSchema/JsonSchema.mpl" folder="" />
<modulePath path="$PROJECT_DIR$/solutions/runtime.lib/runtime.lib.msd" folder="" />
<modulePath path="$PROJECT_DIR$/languages/WSDL/WSDL.mpl" folder="" />
<modulePath path="$PROJECT_DIR$/languages/XSD/XSD.mpl" folder="" />
<modulePath path="$PROJECT_DIR$/languages/XmlWithExtension/XmlWithExtension.mpl" folder="" />
<modulePath path="$PROJECT_DIR$/solutions/Examples/Examples.msd" folder="" />
<modulePath path="$PROJECT_DIR$/solutions/runtime.lib/runtime.lib.msd" folder="" />
</projectModules>
</component>
</project>

0 comments on commit bca313c

Please sign in to comment.