Changeset 440 for java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java
- Timestamp:
- 10/21/15 02:55:11 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java
r438 r440 20 20 import org.eclipse.emf.ecore.EStructuralFeature; 21 21 import org.eclipse.emf.ecore.resource.Resource; 22 import org.eclipse.emf.ecore.resource.ResourceSet; 22 23 import org.eclipse.emf.ecore.resource.impl.ResourceImpl; 23 24 import org.eclipse.xtext.resource.EObjectDescription; 24 25 import org.eclipse.xtext.resource.IEObjectDescription; 26 import org.eclipse.xtext.resource.IResourceDescription; 27 import org.eclipse.xtext.scoping.IGlobalScopeProvider; 25 28 import org.eclipse.xtext.scoping.IScope; 26 29 import org.eclipse.xtext.scoping.Scopes; … … 30 33 import com.framsticks.framclipse.framScript.Block; 31 34 import com.framsticks.framclipse.framScript.Code; 35 import com.framsticks.framclipse.framScript.Expdef; 36 import com.framsticks.framclipse.framScript.ForEachStatement; 37 import com.framsticks.framclipse.framScript.ForStatement; 32 38 import com.framsticks.framclipse.framScript.FramScriptFactory; 33 39 import com.framsticks.framclipse.framScript.Function; 34 40 import com.framsticks.framclipse.framScript.GotoStatment; 41 import com.framsticks.framclipse.framScript.Header; 42 import com.framsticks.framclipse.framScript.IncludeDeclaration; 35 43 import com.framsticks.framclipse.framScript.Invocation; 36 44 import com.framsticks.framclipse.framScript.LabeledStatement; 37 45 import com.framsticks.framclipse.framScript.Model; 46 import com.framsticks.framclipse.framScript.PropertyIncludeDeclaration; 38 47 import com.framsticks.framclipse.framScript.ProposableFunctionImpl; 39 48 import com.framsticks.framclipse.framScript.ProposableVariableDeclarationImpl; 40 49 import com.framsticks.framclipse.framScript.QualifiedExpression; 50 import com.framsticks.framclipse.framScript.Show; 41 51 import com.framsticks.framclipse.framScript.Statement; 42 52 import com.framsticks.framclipse.framScript.VariableDeclaration; 43 53 import com.framsticks.framclipse.framScript.VariableDeclarations; 44 54 import com.framsticks.framclipse.framScript.VariableRef; 55 import com.framsticks.framclipse.resource.FramScriptResourceDescriptionManager; 45 56 import com.framsticks.framclipse.script.ConstantProvider; 46 57 import com.framsticks.framclipse.script.ExpressionTraverser; … … 54 65 * This class contains custom scoping description. 55 66 * 56 * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping 57 * on how and when to use it 58 * 67 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping 68 * on how and when to use it. 59 69 */ 60 70 public class FramScriptScopeProvider extends AbstractDeclarativeScopeProvider { 61 71 62 72 private final ConstantProvider provider; 63 73 64 74 private final ExpressionTraverser traverser; 65 75 76 @Inject 77 private IGlobalScopeProvider globalScopeProvider; 78 79 @Inject 80 private FramScriptResourceDescriptionManager descriptionManager; 81 66 82 private Resource resource; 67 83 68 84 private Map<String, IScope> typesScopes = Maps.newHashMap(); 69 85 private Map<Type, IScope> functionScopes = Maps.newHashMap(); 70 86 private Map<Type, IScope> fieldScopes = Maps.newHashMap(); 71 87 88 private FramScriptImportUriResolver resolver = new FramScriptImportUriResolver(); 89 72 90 @Inject 73 91 public FramScriptScopeProvider(ConstantProvider provider, ExpressionTraverser traverser) { … … 77 95 initTypes(); 78 96 } 79 97 98 @Override 99 public IScope getScope(EObject context, EReference reference) { 100 if (reference.getEContainingClass().getName().equals("VariableRef") && 101 reference.getName().equals("var")) { 102 if (context instanceof VariableRef) { 103 QualifiedExpression parent = getParent((VariableRef) context); 104 if (parent != null) { 105 return getScope(parent, reference); 106 } 107 EObject object = context; 108 while (object != null && !(object.eContainer() instanceof Block || 109 object.eContainer() instanceof ForStatement || 110 object.eContainer() instanceof ForEachStatement)) { 111 object = object.eContainer(); 112 } 113 Statement statement = (Statement) object; 114 EObject blockOrFor = object.eContainer(); 115 116 if (blockOrFor instanceof Block) { 117 Block block = (Block) blockOrFor; 118 return Scopes.scopeFor(precedingDeclarations(block, statement), 119 nextValidScope(block, reference)); 120 } else 121 return getScope(blockOrFor, reference); 122 } else if (context.eContainer() instanceof Block) { 123 Block block = (Block) context.eContainer(); 124 List<VariableDeclaration> vars = precedingDeclarations(block, (Statement)context); 125 IScope outerScope = Scopes.scopeFor(vars, nextValidScope(block, reference)); 126 if (context instanceof Block) { 127 return outerScope; 128 } 129 return new SimpleScope(outerScope, 130 super.getScope(context, reference).getAllElements()); 131 } 132 } 133 return super.getScope(context, reference); 134 } 135 136 private IScope nextValidScope(EObject context, EReference ref) { 137 if (ref.getEContainingClass().getName().equals("VariableRef") && 138 ref.getName().equals("var")) { 139 if (context instanceof Block) { 140 EObject parent = context.eContainer(); 141 if (parent == null) { // may happen in .inc files. 142 return scope_VariableRef_var((Model)context, ref); 143 } 144 if (!(parent instanceof Block)) { 145 return getScope(parent, ref); 146 } 147 } 148 } 149 return getScope(context, ref); 150 } 151 152 private List<VariableDeclaration> precedingDeclarations(Block block, Statement statement){ 153 List<VariableDeclaration> vars = Lists.newArrayList(); 154 for (Statement stmt : block.getStatements()) { 155 // Everything after the statement is out of scope. 156 if (stmt == statement) { 157 break; 158 } else if (stmt instanceof VariableDeclarations) { 159 vars.addAll(((VariableDeclarations) stmt).getVars()); 160 } 161 } 162 return vars; 163 } 164 80 165 protected void initTypes() { 81 166 List<Function> allFunctions = Lists.newArrayList(); … … 116 201 scope = scope_Invocation_function(getFunction(inv), ref); 117 202 } 118 scope = filterByArgumentsCount(scope, inv.getArgs().size()); 119 return scope; 203 Show show = getShow(inv); 204 IScope showScope = show == null ? IScope.NULLSCOPE : 205 new SimpleScope(filterByArgumentsCount(getScope(show, ref), inv.getArgs().size())); 206 return new SimpleScope(showScope, filterByArgumentsCount(scope, inv.getArgs().size())); 120 207 } 121 208 … … 132 219 } 133 220 134 private IScope filterByArgumentsCount(IScope scope, int size) { 221 protected IScope scope_Invocation_function(Show show, EReference ref) { 222 return addAliases(new SimpleScope(showExpdefIncludes(show, ref))); 223 } 224 225 /* 226 * Make sure scope contains only function descriptions. 227 */ 228 private List<IEObjectDescription> filterByArgumentsCount(IScope scope, int size) { 135 229 List<IEObjectDescription> filtered = Lists.newArrayList(); 136 230 for (IEObjectDescription desc : scope.getAllElements()) { … … 140 234 } 141 235 } 142 return new SimpleScope(filtered);143 } 144 236 return filtered; 237 } 238 145 239 private IScope addAliases(IScope scope) { 146 240 Iterable<IEObjectDescription> contents = scope.getAllElements(); … … 155 249 } 156 250 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 251 protected IScope scope_VariableRef_var(QualifiedExpression var, EReference ref) { 167 252 Type type = traverser.getLastType(var); 168 253 IScope scope = fieldScopes.get(type); 169 return scope != null ? scope : IScope.NULLSCOPE; 170 } 171 254 return new SimpleScope(nextValidScope(var.eContainer(), ref), 255 scope != null ? scope.getAllElements() : new ArrayList<IEObjectDescription>()); 256 } 257 172 258 protected IScope scope_VariableRef_var(Block block, EReference ref) { 259 // Scope for Blocks is constructed earlier in getScope, so we stop here. 260 return IScope.NULLSCOPE; 261 } 262 263 protected IScope scope_VariableRef_var(ForStatement fs, EReference ref) { 173 264 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 265 Statement init = fs.getInit(); 266 if (init instanceof VariableDeclarations) { 267 vars.addAll(((VariableDeclarations)init).getVars()); 268 } 269 return Scopes.scopeFor(vars, getScope(fs.eContainer(), ref)); 270 } 271 272 protected IScope scope_VariableRef_var(ForEachStatement fes, EReference ref) { 273 List<VariableDeclaration> vars = Lists.newArrayList(); 274 if (fes.getDecl() == null) 275 return getScope(fes.eContainer(), ref); 276 else { 277 vars.add(fes.getDecl()); 278 return Scopes.scopeFor(vars, getScope(fes.eContainer(), ref)); 279 } 280 } 281 282 /* 283 * Blocks are handled specially in getScope, 284 * and scope_VariableRef_var(Block, EReference) returns IScope.NULLSCOPE, 285 * which breaks the chain of scopes, 286 * so we have to ensure each unspecified scope_VariableRef_var call 287 * is redirected to getScope in this class, instead of super.getScope. 288 */ 289 protected IScope scope_VariableRef_var(EObject ctx, EReference ref) { 290 EObject parent = ctx.eContainer(); 291 if (parent == null) 292 return IScope.NULLSCOPE; 293 else 294 return getScope(parent, ref); 295 } 296 182 297 protected IScope scope_VariableRef_var(Function f, EReference ref) { 183 298 List<VariableDeclaration> vars = Lists.newArrayList(); … … 185 300 return Scopes.scopeFor(vars, getScope(f.eContainer(), ref)); 186 301 } 187 302 188 303 protected IScope scope_VariableRef_var(Code code, EReference ref) { 189 304 List<VariableDeclaration> vars = Lists.newArrayList(); … … 193 308 return Scopes.scopeFor(vars, getScope(code.eContainer(), ref)); 194 309 } 195 310 311 private List<IEObjectDescription> showExpdefIncludes(Show show, EReference ref) { 312 ArrayList<IEObjectDescription> result = Lists.newArrayList(); 313 // Get expdef header 314 Header expdefHeader= null; 315 for (Header h : show.getHeaders()) { 316 if ("expdef:".equals(h.getName())) { 317 expdefHeader = h; 318 break; 319 } 320 } 321 if (expdefHeader == null) 322 return result; 323 // Find resource by name 324 ResourceSet resourceSet = show.eResource().getResourceSet(); 325 String expdefFile = resolver.resolve(expdefHeader); 326 Resource expdefResource = findResourceByName(resourceSet, expdefFile); 327 if (expdefResource == null) 328 return result; 329 // Mine include directives 330 ArrayList<String> included = Lists.newArrayList(); 331 Expdef expdef = (Expdef) expdefResource.getContents().get(0); 332 for (PropertyIncludeDeclaration pid : expdef.getPropertyImports()) 333 included.add(pid.getImportURI()); 334 for (IncludeDeclaration id : expdef.getCode().getIncludes()) 335 included.add(id.getImportURI()); 336 // Get globals 337 for (String filename : included) { 338 Resource includedResource = findResourceByName(resourceSet, filename); 339 if (includedResource == null) { 340 String showURI = show.eResource().getURI().toString(); 341 URI includeURI = URI.createURI(showURI.subSequence( 342 0, showURI.lastIndexOf("/")+1) + filename); 343 includedResource = resourceSet.getResource( 344 includeURI, true); 345 if (includedResource == null) 346 continue; 347 } 348 IResourceDescription resourceDescription = 349 descriptionManager.getResourceDescription(includedResource); 350 result.addAll(Lists.newArrayList(resourceDescription.getExportedObjectsByType(ref.getEReferenceType()))); 351 } 352 return result; 353 } 354 355 private Resource findResourceByName(ResourceSet resourceSet, 356 String filename) { 357 for (Resource res : resourceSet.getResources()) { 358 if (res.getURI().toString().endsWith("/" + filename)) { 359 return res; 360 } 361 } 362 return null; 363 } 364 196 365 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()); 366 IScope outerScope = globalScopeProvider.getScope(model.eResource(), ref, null); 367 if (model instanceof Show) { 368 outerScope = new SimpleScope(outerScope, showExpdefIncludes((Show)model, ref)); 369 } 370 String ext = getExtension(model); 371 if ("inc".equals(ext)) // There is no description for .inc in XML, 372 ext = "script"; // so we pretend it is a .script. 373 IScope types = typesScopes.get(ext); 374 return new SimpleScope(outerScope, types.getAllElements()); 200 375 } 201 376 … … 211 386 return Scopes.scopeFor(labels); 212 387 } 213 388 389 protected IScope scope_Property(Show show, EReference ref) { 390 return new SimpleScope(delegateGetScope(show, ref), showExpdefIncludes(show, ref)); 391 } 392 393 protected IScope scope_State(Show show, EReference ref) { 394 return new SimpleScope(delegateGetScope(show, ref), showExpdefIncludes(show, ref)); 395 } 396 214 397 private Function createFunction(Element element) { 215 398 Function function = new ProposableFunctionImpl(element); … … 233 416 return global; 234 417 } 235 418 236 419 private VariableDeclaration createVariableDeclaration(String name) { 237 420 VariableDeclaration var = FramScriptFactory.eINSTANCE.createVariableDeclaration(); … … 240 423 return var; 241 424 } 242 425 243 426 private QualifiedExpression getParent(QualifiedExpression expr) { 244 427 EStructuralFeature feature = expr.eContainingFeature(); 245 428 if (feature.equals(QUALIFIED_EXPRESSION__CHILD)) { 246 429 return (QualifiedExpression) expr.eContainer(); 247 } else if (feature.equals(QUALIFIED_EXPRESSION__PARENT) 430 } else if (feature.equals(QUALIFIED_EXPRESSION__PARENT) 248 431 || feature.equals(ARRAY_ELEMENT_EXPRESSION__ARRAY)) { 249 432 return getParent((QualifiedExpression) expr.eContainer()); … … 252 435 } 253 436 } 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 437 262 438 private Function getFunction(EObject object) { 263 439 while (object != null && !(object instanceof Function)) { … … 266 442 return (Function) object; 267 443 } 268 444 445 private Show getShow(EObject object) { 446 while (object != null && !(object instanceof Show)) { 447 object = object.eContainer(); 448 } 449 return (Show) object; 450 } 451 269 452 private String getExtension(EObject object) { 270 453 return object.eResource().getURI().fileExtension(); 271 454 } 272 455 273 456 }
Note: See TracChangeset
for help on using the changeset viewer.