summaryrefslogtreecommitdiffstats
path: root/rba.tool.editor/src/rba/tool/editor/scoping
diff options
context:
space:
mode:
authorKenji Hosokawa <khosokawa@jp.adit-jv.com>2021-08-03 18:42:39 +0900
committerKenji Hosokawa <khosokawa@jp.adit-jv.com>2021-08-06 19:32:38 +0900
commitbe4f78978faba3d3ceb88df02a7f93a2e09ff1e0 (patch)
tree1f3f1a96251ac4f655c8a96fc33d5d4ee779cd06 /rba.tool.editor/src/rba/tool/editor/scoping
parent71ca7c6cab863767ef30c8bd05b2bbfda8731cb5 (diff)
Initial commit
Bug-AGL: SPEC-4033 Signed-off-by: Kenji Hosokawa <khosokawa@jp.adit-jv.com>
Diffstat (limited to 'rba.tool.editor/src/rba/tool/editor/scoping')
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/IExpressionScope.xtend22
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/RBAModelExpressionScope.xtend22
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/RBAModelImportedNamespaceAwareLocalScopeProvider.xtend42
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/RBAModelScopeProvider.xtend85
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/internal/IMemberFeatureScopes.xtend12
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberFieldScopes.xtend31
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationRegistry.xtend68
-rw-r--r--rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationScopes.xtend27
8 files changed, 309 insertions, 0 deletions
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/IExpressionScope.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/IExpressionScope.xtend
new file mode 100644
index 0000000..12f7ca4
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/IExpressionScope.xtend
@@ -0,0 +1,22 @@
+package rba.tool.editor.scoping
+
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.scoping.IScope
+
+interface IExpressionScope {
+
+ enum Anchor {
+ UNKNOWN,
+ CONSTRAINT
+ }
+
+ def IScope getFeatureScope(EObject model, IExpressionScope.Anchor anchor);
+
+ IExpressionScope NULL = new NullExpressionScope();
+
+ class NullExpressionScope implements IExpressionScope {
+ override getFeatureScope(EObject model, IExpressionScope.Anchor anchor) {
+ return IScope.NULLSCOPE;
+ }
+ }
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelExpressionScope.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelExpressionScope.xtend
new file mode 100644
index 0000000..90bdf3b
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelExpressionScope.xtend
@@ -0,0 +1,22 @@
+package rba.tool.editor.scoping
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.scoping.IScope
+import rba.tool.editor.scoping.internal.RBAModelMemberFieldScopes
+import rba.tool.editor.scoping.internal.RBAModelMemberOperationScopes
+
+@Singleton
+class RBAModelExpressionScope implements IExpressionScope {
+
+ @Inject private RBAModelMemberFieldScopes filedScopeCreator;
+ @Inject private RBAModelMemberOperationScopes operationScopeCreator;
+
+ override getFeatureScope(EObject model, IExpressionScope.Anchor anchor) {
+ var IScope result = filedScopeCreator.createFeatureScope(model);
+ result = operationScopeCreator.createFeatureScope(model, anchor, result);
+ return result;
+ }
+
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelImportedNamespaceAwareLocalScopeProvider.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelImportedNamespaceAwareLocalScopeProvider.xtend
new file mode 100644
index 0000000..3dad349
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelImportedNamespaceAwareLocalScopeProvider.xtend
@@ -0,0 +1,42 @@
+package rba.tool.editor.scoping
+
+import java.util.Iterator
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.emf.ecore.util.EcoreUtil
+import org.eclipse.xtext.resource.IEObjectDescription
+import org.eclipse.xtext.scoping.Scopes
+import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider
+import org.eclipse.xtext.scoping.impl.MultimapBasedSelectable
+import org.eclipse.xtext.xbase.lib.Functions.Function1
+import rba.core.RBACorePackage
+import rba.core.Variable
+
+class RBAModelImportedNamespaceAwareLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
+
+ private Function1<? super IEObjectDescription, Boolean> variableFilter = [ description |
+ description.EClass !== RBACorePackage.Literals.VARIABLE
+ ];
+
+ override protected getResourceScope(Resource res, EReference reference) {
+ val context = res.getContents().get(0);
+ var globalScope = getGlobalScope(res, reference, variableFilter);
+ val normalizers = getImplicitImports(isIgnoreCase(reference));
+ if(!normalizers.isEmpty()) {
+ globalScope = createImportScope(globalScope, normalizers, null, reference.getEReferenceType(), isIgnoreCase(reference));
+ }
+ return getResourceScope(globalScope, context, reference);
+ }
+
+ override protected internalGetAllDescriptions(Resource resource) {
+ val allContents = new Iterable<EObject>() {
+ override Iterator<EObject> iterator() {
+ return EcoreUtil.getAllContents(resource, false).filter(c|!(c instanceof Variable));
+ }
+ };
+ val allDescriptions = Scopes.scopedElementsFor(allContents, qualifiedNameProvider);
+ return new MultimapBasedSelectable(allDescriptions);
+ }
+
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelScopeProvider.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelScopeProvider.xtend
new file mode 100644
index 0000000..8fe190f
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelScopeProvider.xtend
@@ -0,0 +1,85 @@
+/*
+ * generated by Xtext 2.12.0
+ */
+package rba.tool.editor.scoping
+
+import java.util.ArrayList
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.xtext.EcoreUtil2
+import org.eclipse.xtext.scoping.IScope
+import org.eclipse.xtext.scoping.Scopes
+import rba.core.AbstractProperty
+import rba.core.ComplexExpression
+import rba.core.Content
+import rba.core.ContentState
+import rba.core.Expression
+import rba.core.LambdaExpression
+import rba.core.ObjectReference
+import rba.core.RBACorePackage
+import rba.core.Scene
+import rba.core.State
+import rba.tool.editor.rbaEditorModel.MemberFeatureReference
+
+/**
+ * This class contains custom scoping description.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
+ * on how and when to use it.
+ */
+class RBAModelScopeProvider extends AbstractRBAModelScopeProvider {
+
+ override getScope(EObject context, EReference reference) {
+ val scope = super.getScope(context, reference);
+
+ if(reference == RBACorePackage.Literals.OBJECT_REFERENCE__REF_OBJECT) {
+ if(context instanceof MemberFeatureReference) {
+ var Expression expression = (context as MemberFeatureReference).operand.get(0);
+ if(expression !== null) {
+ if(!(expression instanceof ObjectReference)) {
+ return IScope.NULLSCOPE;
+ }
+ val rootElement = (expression as ObjectReference).refObject;
+ if(rootElement instanceof Scene) {
+ val candidates = EcoreUtil2.getAllContentsOfType(rootElement, AbstractProperty);
+ return Scopes.scopeFor(candidates);
+ } else if(rootElement instanceof Content) {
+ val candidates = #[ContentState].map(clazz|EcoreUtil2.getAllContentsOfType(rootElement, clazz).filter(c|c.eContainer === rootElement)).flatten;
+ return Scopes.scopeFor(candidates);
+ } else if(rootElement instanceof State) {
+ val candidates = EcoreUtil2.getAllContentsOfType(rootElement, State).filter(c|c.eContainer === rootElement);
+ return Scopes.scopeFor(candidates);
+ }
+ }
+ } else if(context instanceof ObjectReference) {
+ val candidates = EcoreUtil2.getAllContainers(context).filter(Expression).map [ container |
+ val list = new ArrayList<EObject>();
+ if(container instanceof LambdaExpression) {
+ val lambda = container as LambdaExpression;
+ if(lambda.x !== null)
+ list.add(lambda.x);
+ if(lambda.letStatements !== null && lambda.letStatements.size > 0)
+ list.addAll(lambda.letStatements.map(l|l.variable));
+ if(lambda.bodyText !== null && lambda.bodyText.letStatements !== null && lambda.bodyText.letStatements.size > 0)
+ list.addAll(lambda.bodyText.letStatements.map(l|l.variable));
+ } else if(container instanceof ComplexExpression) {
+ val complex = container as ComplexExpression;
+ if(complex.letStatements !== null && complex.letStatements.size > 0)
+ list.addAll(complex.letStatements.map(l|l.variable));
+ } else {
+ if(container.letStatements !== null && container.letStatements.size > 0)
+ list.addAll(container.letStatements.map(l|l.variable));
+ }
+ return list;
+ ].flatten
+
+ if(candidates.size > 0) {
+ return Scopes.scopeFor(candidates, scope);
+ }
+ }
+ }
+
+ return scope;
+ }
+
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/internal/IMemberFeatureScopes.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/internal/IMemberFeatureScopes.xtend
new file mode 100644
index 0000000..5d6bba7
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/internal/IMemberFeatureScopes.xtend
@@ -0,0 +1,12 @@
+package rba.tool.editor.scoping.internal
+
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.scoping.IScope
+import rba.tool.editor.scoping.IExpressionScope
+
+interface IMemberFeatureScopes {
+
+ def IScope createFeatureScope(EObject model);
+
+ def IScope createFeatureScope(EObject model, IExpressionScope.Anchor anchor, IScope outer);
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberFieldScopes.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberFieldScopes.xtend
new file mode 100644
index 0000000..a2c9b6f
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberFieldScopes.xtend
@@ -0,0 +1,31 @@
+package rba.tool.editor.scoping.internal
+
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.EcoreUtil2
+import org.eclipse.xtext.scoping.IScope
+import org.eclipse.xtext.scoping.Scopes
+import rba.core.AbstractProperty
+import rba.core.Content
+import rba.core.ContentState
+import rba.core.Scene
+import rba.core.State
+import rba.tool.editor.scoping.IExpressionScope
+
+class RBAModelMemberFieldScopes implements IMemberFeatureScopes {
+
+ override createFeatureScope(EObject model) {
+ createFeatureScope(model, IExpressionScope.Anchor.UNKNOWN, IScope.NULLSCOPE);
+ }
+
+ override createFeatureScope(EObject model, IExpressionScope.Anchor anchor, IScope outer) {
+ if (model instanceof Scene) {
+ return Scopes.scopeFor(EcoreUtil2.getAllContentsOfType(model, AbstractProperty), outer);
+ } else if (model instanceof Content) {
+ return Scopes.scopeFor(EcoreUtil2.getAllContentsOfType(model, ContentState), outer);
+ } else if (model instanceof State) {
+ return Scopes.scopeFor(EcoreUtil2.getAllContentsOfType(model, State), outer);
+ } else {
+ return outer;
+ }
+ }
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationRegistry.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationRegistry.xtend
new file mode 100644
index 0000000..b641362
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationRegistry.xtend
@@ -0,0 +1,68 @@
+package rba.tool.editor.scoping.internal
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import java.util.Collections
+import java.util.Map
+import java.util.Set
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.GrammarUtil
+import org.eclipse.xtext.IGrammarAccess
+import org.eclipse.xtext.Keyword
+import org.eclipse.xtext.generator.parser.antlr.FirstSetComputer
+import org.eclipse.xtext.naming.QualifiedName
+import org.eclipse.xtext.resource.IEObjectDescription
+import rba.core.ExpressionType
+import rba.core.Operator
+import rba.core.RuleObject
+import rba.tool.editor.resource.RBAModelEObjectDescription
+import rba.tool.editor.scoping.IExpressionScope
+
+@Singleton
+class RBAModelMemberOperationRegistry {
+
+ private static Map<String, String> EMPTY_USERDATA = Collections.<String, String>emptyMap();
+ private static Pattern pattern = Pattern.compile("^ConfigurationParserRule_([A-Za-z]+)OperatorFor([A-Za-z]+)$");
+ private static String DESCRIPTION_KEY = "%s_%s";
+ private static String QUALIFIED_NAME = "%s()";
+
+ private final Map<String, Set<IEObjectDescription>> operations = newLinkedHashMap();
+
+ @Inject
+ public new(IGrammarAccess grammarAccess) {
+ registerOperations(grammarAccess);
+ }
+
+ def protected void registerOperations(IGrammarAccess grammarAccess) {
+ val multipleOperandParserRule = GrammarUtil.findRuleForName(grammarAccess.getGrammar(), "ConfigurationParserRule_OperatorWithMultipleOperand");
+ val multipleOperandConfiguration = FirstSetComputer.getFirstSet(multipleOperandParserRule.alternatives).filter(Keyword).toList;
+ val allConfigurations = GrammarUtil.allRules(grammarAccess.getGrammar()).filter(r|pattern.matcher(r.name).find);
+ for (configuration : allConfigurations) {
+ val Matcher matcher = pattern.matcher(configuration.name);
+ if (matcher.find) {
+ val descriptionKey = String.format(DESCRIPTION_KEY, matcher.group(1), matcher.group(2)).toUpperCase;
+ val descriptionEntries = newHashSet();
+ val keywords = FirstSetComputer.getFirstSet(configuration.alternatives).filter(Keyword);
+ for (keyword : keywords) {
+ descriptionEntries.add(
+ new RBAModelEObjectDescription(QualifiedName.create(String.format(QUALIFIED_NAME, keyword.value)), null, EMPTY_USERDATA,
+ #[if (multipleOperandConfiguration.contains(keyword)) -1 else 0, -50]));
+ }
+ operations.put(descriptionKey, descriptionEntries);
+ }
+ }
+ }
+
+ def public Set<IEObjectDescription> getOperations(EObject model, IExpressionScope.Anchor anchor) {
+ var ExpressionType expressionType = ExpressionType.BOOLEAN;
+ if (model instanceof RuleObject) {
+ expressionType = (model as RuleObject).expressionType;
+ } else if (model instanceof Operator) {
+ expressionType = (model as Operator).underlyingType;
+ }
+ return operations.get(String.format(DESCRIPTION_KEY, expressionType.getName(), anchor.name));
+ }
+
+}
diff --git a/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationScopes.xtend b/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationScopes.xtend
new file mode 100644
index 0000000..da833ec
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/scoping/internal/RBAModelMemberOperationScopes.xtend
@@ -0,0 +1,27 @@
+package rba.tool.editor.scoping.internal
+
+import com.google.inject.Inject
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.scoping.IScope
+import org.eclipse.xtext.scoping.impl.SimpleScope
+import rba.tool.editor.scoping.IExpressionScope
+
+class RBAModelMemberOperationScopes implements IMemberFeatureScopes {
+
+ private RBAModelMemberOperationRegistry operationRegistry;
+
+ @Inject
+ new(RBAModelMemberOperationRegistry operationRegistry) {
+ this.operationRegistry = operationRegistry;
+ }
+
+ override createFeatureScope(EObject model) {
+ return createFeatureScope(model, IExpressionScope.Anchor.UNKNOWN, IScope.NULLSCOPE);
+ }
+
+ override createFeatureScope(EObject model, IExpressionScope.Anchor anchor, IScope outer) {
+ val descriptions = operationRegistry.getOperations(model, anchor);
+ return new SimpleScope(outer, descriptions ?: newHashSet());
+ }
+
+}