![JAR search and dependency download from the Maven repository](/logo.png)
com.regnosys.rosetta.tests.util.ExpressionParser.xtend Maven / Gradle / Ivy
package com.regnosys.rosetta.tests.util
import com.regnosys.rosetta.rosetta.expression.RosettaExpression
import com.regnosys.rosetta.services.RosettaGrammarAccess
import java.io.StringReader
import org.eclipse.xtext.parser.IParseResult
import org.eclipse.xtext.parser.IParser
import static org.junit.jupiter.api.Assertions.*
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.diagnostics.IDiagnosticConsumer
import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer
import org.eclipse.xtext.nodemodel.INode
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.diagnostics.Severity
import org.eclipse.xtext.naming.QualifiedName
import com.regnosys.rosetta.rosetta.simple.Attribute
import java.util.Collection
import com.regnosys.rosetta.scoping.RosettaScopeProvider
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.scoping.IScope
import com.regnosys.rosetta.rosetta.RosettaModel
import javax.inject.Inject
import java.util.List
import org.eclipse.xtext.scoping.Scopes
import org.eclipse.xtext.linking.lazy.LazyLinker
import javax.inject.Provider
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.emf.common.util.URI
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.emf.ecore.util.InternalEList
import org.eclipse.xtext.linking.lazy.LazyLinkingResource
import org.eclipse.xtext.linking.impl.DefaultLinkingService
class ExpressionParser {
@Inject IParser parser
@Inject RosettaGrammarAccess grammar
@Inject ModelHelper modelHelper
@Inject Provider resourceProvider
@Inject RosettaStaticLinker linker
def RosettaExpression parseExpression(CharSequence expr) {
return parseExpression(expr, emptyList)
}
def RosettaExpression parseExpression(CharSequence expr, Collection extends CharSequence> attrs) {
return parseExpression(expr, defaultContext, attrs)
}
def RosettaExpression parseExpression(CharSequence expr, List context, Collection extends CharSequence> attrs) {
val attributes = attrs.map[parseAttribute(context)].toList
return parseExpression(expr, context, attributes)
}
def RosettaExpression parseExpression(CharSequence expr, Attribute... attributes) {
return parseExpression(expr, defaultContext, attributes)
}
def RosettaExpression parseExpression(CharSequence expr, List context, Attribute... attributes) {
val IParseResult result = parser.parse(grammar.rosettaCalcExpressionRule, new StringReader(expr.toString()))
assertFalse(result.hasSyntaxErrors)
val expression = result.rootASTElement as RosettaExpression
createResource("expr", expression, context)
link(expression, context, attributes)
return expression
}
def Attribute parseAttribute(CharSequence attr) {
return parseAttribute(attr, defaultContext)
}
def Attribute parseAttribute(CharSequence attr, List context) {
val IParseResult result = parser.parse(grammar.attributeRule, new StringReader(attr.toString()))
assertFalse(result.hasSyntaxErrors)
val attribute = result.rootASTElement as Attribute
createResource("attribute", attribute, context)
link(attribute, context, emptyList)
return attribute
}
private def Resource createResource(String name, EObject content, List context) {
val resourceSet = context.head.eResource.resourceSet
var nr = 0
var uniqueURI = URI.createURI("synthetic://" + name + nr++)
while (resourceSet.getResource(uniqueURI, false) !== null) {
uniqueURI = URI.createURI("synthetic://" + name + nr++)
}
val resource = resourceProvider.get()
resource.URI = uniqueURI
resource.contents.add(content)
resourceSet.resources.add(resource)
resource
}
private def List defaultContext() {
return newArrayList(modelHelper.testResourceSet.resources.map[contents.head as RosettaModel])
}
private def void link(EObject obj, List context, Collection extends EObject> globals) {
linker.setStateForNextLink(context, globals)
val consumer = new ListBasedDiagnosticConsumer
linker.linkModel(obj, consumer)
obj.eResource.errors.addAll(consumer.getResult(Severity.ERROR))
}
private static class RosettaContextBasedScopeProvider extends RosettaScopeProvider {
List context = emptyList
def void setContext(List context) {
this.context = context
}
override protected getImplicitImports(boolean ignoreCase) {
(super.getImplicitImports(ignoreCase) + context.map[name].toSet.map[createImportedNamespaceResolver(it + ".*", ignoreCase)]).toList
}
}
private static class RosettaStaticLinker extends LazyLinker {
@Inject
RosettaContextBasedScopeProvider scopeProvider
IScope staticScope = IScope.NULLSCOPE
def void setStateForNextLink(List context, Collection extends EObject> globals) {
scopeProvider.setContext(context)
staticScope = Scopes.scopeFor(globals)
}
private def void clearState() {
scopeProvider.setContext(emptyList)
staticScope = IScope.NULLSCOPE
}
override protected doLinkModel(EObject root, IDiagnosticConsumer consumer) {
// TODO: this is hacky
((root.eResource as LazyLinkingResource).linkingService as DefaultLinkingService).setScopeProvider(scopeProvider)
super.doLinkModel(root, consumer)
EcoreUtil2.resolveAll(root)
clearState
}
protected override void createAndSetProxy(EObject obj, INode node, EReference eRef) {
val varName = NodeModelUtils.getTokenText(node)
val staticElement = staticScope.getSingleElement(QualifiedName.create(varName))
if (staticElement !== null) {
val resolved = staticElement.getEObjectOrProxy()
if (eRef.isMany()) {
(obj.eGet(eRef, false) as InternalEList).addUnique(resolved)
} else {
obj.eSet(eRef, resolved);
}
} else {
super.createAndSetProxy(obj, node, eRef)
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy