summaryrefslogtreecommitdiffstats
path: root/rba.tool.editor/src/rba/tool/editor/scoping/RBAModelScopeProvider.xtend
blob: 8fe190fa17f1d50ba401e8242b8851020a9012b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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;
	}

}