source: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java @ 438

Last change on this file since 438 was 438, checked in by Mateusz Poszwa, 9 years ago

Ported Framclipse to Xtext 2.8.4

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1/*
2 * generated by Xtext
3 */
4package com.framsticks.framclipse.scoping;
5
6import static com.framsticks.framclipse.framScript.FramScriptPackage.Literals.ARRAY_ELEMENT_EXPRESSION__ARRAY;
7import static com.framsticks.framclipse.framScript.FramScriptPackage.Literals.QUALIFIED_EXPRESSION__CHILD;
8import static com.framsticks.framclipse.framScript.FramScriptPackage.Literals.QUALIFIED_EXPRESSION__PARENT;
9
10import java.util.ArrayList;
11import java.util.List;
12import java.util.Map;
13import java.util.Map.Entry;
14
15import org.eclipse.emf.common.util.EList;
16import org.eclipse.emf.common.util.TreeIterator;
17import org.eclipse.emf.common.util.URI;
18import org.eclipse.emf.ecore.EObject;
19import org.eclipse.emf.ecore.EReference;
20import org.eclipse.emf.ecore.EStructuralFeature;
21import org.eclipse.emf.ecore.resource.Resource;
22import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
23import org.eclipse.xtext.resource.EObjectDescription;
24import org.eclipse.xtext.resource.IEObjectDescription;
25import org.eclipse.xtext.scoping.IScope;
26import org.eclipse.xtext.scoping.Scopes;
27import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
28import org.eclipse.xtext.scoping.impl.SimpleScope;
29
30import com.framsticks.framclipse.framScript.Block;
31import com.framsticks.framclipse.framScript.Code;
32import com.framsticks.framclipse.framScript.FramScriptFactory;
33import com.framsticks.framclipse.framScript.Function;
34import com.framsticks.framclipse.framScript.GotoStatment;
35import com.framsticks.framclipse.framScript.Invocation;
36import com.framsticks.framclipse.framScript.LabeledStatement;
37import com.framsticks.framclipse.framScript.Model;
38import com.framsticks.framclipse.framScript.ProposableFunctionImpl;
39import com.framsticks.framclipse.framScript.ProposableVariableDeclarationImpl;
40import com.framsticks.framclipse.framScript.QualifiedExpression;
41import com.framsticks.framclipse.framScript.Statement;
42import com.framsticks.framclipse.framScript.VariableDeclaration;
43import com.framsticks.framclipse.framScript.VariableDeclarations;
44import com.framsticks.framclipse.framScript.VariableRef;
45import com.framsticks.framclipse.script.ConstantProvider;
46import com.framsticks.framclipse.script.ExpressionTraverser;
47import com.framsticks.framclipse.script.model.Element;
48import com.framsticks.framclipse.script.model.Type;
49import com.google.common.collect.Lists;
50import com.google.common.collect.Maps;
51import com.google.inject.Inject;
52
53/**
54 * This class contains custom scoping description.
55 *
56 * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping
57 * on how and when to use it
58 *
59 */
60public class FramScriptScopeProvider extends AbstractDeclarativeScopeProvider {
61       
62        private final ConstantProvider provider;
63       
64        private final ExpressionTraverser traverser;
65       
66        private Resource resource;
67       
68        private Map<String, IScope> typesScopes = Maps.newHashMap();
69        private Map<Type, IScope> functionScopes = Maps.newHashMap();
70        private Map<Type, IScope> fieldScopes = Maps.newHashMap();
71       
72        @Inject
73        public FramScriptScopeProvider(ConstantProvider provider, ExpressionTraverser traverser) {
74                this.provider = provider;
75                this.traverser = traverser;
76                this.resource = new ResourceImpl(URI.createURI("/"));
77                initTypes();
78        }
79       
80        protected void initTypes() {
81                List<Function> allFunctions = Lists.newArrayList();
82                List<VariableDeclaration> allFields = Lists.newArrayList();
83               
84                for (Entry<String, Map<String, Type>> entry : provider.getTypes().entrySet()) {
85                        List<VariableDeclaration> types = Lists.newArrayList();
86                        for (Type type : entry.getValue().values()) {
87                                types.add(createType(type));
88                               
89                                ArrayList<Function> functions = Lists.newArrayList();
90                                ArrayList<VariableDeclaration> fields = Lists.newArrayList();
91                                for (Element element : type.getElements()) {
92                                        if (element.isFunction()) {
93                                                functions.add(createFunction(element));
94                                        } else {
95                                                fields.add(createField(element));
96                                        }
97                                }
98                                functionScopes.put(type, Scopes.scopeFor(functions));
99                                fieldScopes.put(type, Scopes.scopeFor(fields));
100                                allFunctions.addAll(functions);
101                                allFields.addAll(fields);
102                        }
103                        typesScopes.put(entry.getKey(), Scopes.scopeFor(types));
104                }
105               
106                functionScopes.put(null, Scopes.scopeFor(allFunctions));
107                fieldScopes.put(null, Scopes.scopeFor(allFields));
108        }
109       
110        protected IScope scope_Invocation_function(Invocation inv, EReference ref) {
111                QualifiedExpression parent = getParent(inv);
112                IScope scope;
113                if (parent != null) {
114                        scope = scope_Invocation_function(parent, ref);
115                } else {
116                        scope = scope_Invocation_function(getFunction(inv), ref);
117                }
118                scope = filterByArgumentsCount(scope, inv.getArgs().size());
119                return scope;
120        }
121
122        protected IScope scope_Invocation_function(QualifiedExpression inv, EReference ref) {
123                Type type = traverser.getLastType(inv);
124                IScope scope = functionScopes.get(type);
125                return scope != null ? scope : IScope.NULLSCOPE;
126        }
127
128        protected IScope scope_Invocation_function(Function f, EReference ref) {
129                IScope scope = delegateGetScope(f, ref);
130                scope = addAliases(scope);
131                return scope;
132        }
133
134        private IScope filterByArgumentsCount(IScope scope, int size) {
135                List<IEObjectDescription> filtered = Lists.newArrayList();
136                for (IEObjectDescription desc : scope.getAllElements()) {
137                        Function function = (Function) desc.getEObjectOrProxy();
138                        if (function.getParams().size() == size) {
139                                filtered.add(desc);
140                        }
141                }
142                return new SimpleScope(filtered);
143        }
144       
145        private IScope addAliases(IScope scope) {
146                Iterable<IEObjectDescription> contents = scope.getAllElements();
147                List<IEObjectDescription> withAliases = Lists.newArrayList(contents);
148                for (IEObjectDescription desc : contents) {
149                        Function function = (Function) desc.getEObjectOrProxy();
150                        for (String string : function.getAliases()) {
151                                withAliases.add(EObjectDescription.create(string, function));
152                        }
153                }
154                return new SimpleScope(withAliases);
155        }
156
157        protected IScope scope_VariableRef_var(VariableRef var, EReference ref) {
158                QualifiedExpression parent = getParent(var);
159                if (parent != null) {
160                        return scope_VariableRef_var(parent, ref);
161                } else {
162                        return scope_VariableRef_var(getBlock(var), ref);
163                }
164        }
165
166        protected IScope scope_VariableRef_var(QualifiedExpression var, EReference ref) {
167                Type type = traverser.getLastType(var);
168                IScope scope = fieldScopes.get(type);
169                return scope != null ? scope : IScope.NULLSCOPE;
170        }
171       
172        protected IScope scope_VariableRef_var(Block block, EReference ref) {
173                List<VariableDeclaration> vars = Lists.newArrayList();
174                for (Statement stmt : block.getStatements()) {
175                        if (stmt instanceof VariableDeclarations) {
176                                vars.addAll(((VariableDeclarations) stmt).getVars());
177                        }
178                }
179                return Scopes.scopeFor(vars, getScope(block.eContainer(), ref));
180        }
181       
182        protected IScope scope_VariableRef_var(Function f, EReference ref) {
183                List<VariableDeclaration> vars = Lists.newArrayList();
184                vars.addAll(f.getParams());
185                return Scopes.scopeFor(vars, getScope(f.eContainer(), ref));
186        }
187       
188        protected IScope scope_VariableRef_var(Code code, EReference ref) {
189                List<VariableDeclaration> vars = Lists.newArrayList();
190                for (VariableDeclarations declarations : code.getGlobals()) {
191                        vars.addAll(declarations.getVars());
192                }
193                return Scopes.scopeFor(vars, getScope(code.eContainer(), ref));
194        }
195       
196        protected IScope scope_VariableRef_var(Model model, EReference ref) {
197//              IScope outerScope = delegateGetScope(model, ref).getOuterScope();
198                IScope types = typesScopes.get(getExtension(model));
199                return new SimpleScope(types.getAllElements());
200        }
201
202        protected IScope scope_GotoStatment_dest(GotoStatment stmt, EReference ref) {
203                Block code = getFunction(stmt).getCode();
204                List<LabeledStatement> labels = Lists.newArrayList();
205                for (TreeIterator<EObject> i = code.eAllContents(); i.hasNext();) {
206                        EObject object = i.next();
207                        if (object instanceof LabeledStatement) {
208                                labels.add((LabeledStatement) object);
209                        }
210                }
211                return Scopes.scopeFor(labels);
212        }
213       
214        private Function createFunction(Element element) {
215                Function function = new ProposableFunctionImpl(element);
216                EList<VariableDeclaration> params = function.getParams();
217                for (int i = 0; i < element.getArguments().size(); i++) {
218                        params.add(createVariableDeclaration(element.getArguments().get(i).getName(i)));
219                }
220                resource.getContents().add(function);
221                return function;
222        }
223
224        private VariableDeclaration createField(Element element) {
225                VariableDeclaration field = new ProposableVariableDeclarationImpl(element);
226                resource.getContents().add(field);
227                return field;
228        }
229
230        private VariableDeclaration createType(Type type) {
231                VariableDeclaration global = new ProposableVariableDeclarationImpl(type);
232                resource.getContents().add(global);
233                return global;
234        }
235       
236        private VariableDeclaration createVariableDeclaration(String name) {
237                VariableDeclaration var = FramScriptFactory.eINSTANCE.createVariableDeclaration();
238                var.setName(name);
239                resource.getContents().add(var);
240                return var;
241        }
242       
243        private QualifiedExpression getParent(QualifiedExpression expr) {
244                EStructuralFeature feature = expr.eContainingFeature();
245                if (feature.equals(QUALIFIED_EXPRESSION__CHILD)) {
246                        return (QualifiedExpression) expr.eContainer();
247                } else if (feature.equals(QUALIFIED_EXPRESSION__PARENT)
248                                || feature.equals(ARRAY_ELEMENT_EXPRESSION__ARRAY)) {
249                        return getParent((QualifiedExpression) expr.eContainer());
250                } else {
251                        return null;
252                }
253        }
254       
255        private Block getBlock(EObject object) {
256                while (object != null && !(object instanceof Block)) {
257                        object = object.eContainer();
258                }
259                return (Block) object;
260        }
261       
262        private Function getFunction(EObject object) {
263                while (object != null && !(object instanceof Function)) {
264                        object = object.eContainer();
265                }
266                return (Function) object;
267        }
268       
269        private String getExtension(EObject object) {
270                return object.eResource().getURI().fileExtension();
271        }
272       
273}
Note: See TracBrowser for help on using the repository browser.