Scoping Tips and Tricks
-
Upload
sebastian-zarnekow -
Category
Software
-
view
209 -
download
0
Transcript of Scoping Tips and Tricks
IN COMPUTER PROGRAMMING, THE SCOPE OF A NAME BINDING – AN ASSOCIATION OF A NAME TO AN ENTITY, SUCH AS A VARIABLE – IS THE PART OF A COMPUTER PROGRAM WHERE THE BINDING IS VALID: WHERE THE NAME CAN BE USED TO REFER TO THE ENTITY. IN OTHER PARTS OF THE PROGRAM THE NAME MAY REFER TO A DIFFERENT ENTITY (IT MAY HAVE A DIFFERENT BINDING), OR TO NOTHING AT ALL (IT MAY BE UNBOUND). THE SCOPE OF A BINDING IS ALSO KNOWN AS THE VISIBILITY OF AN ENTITY, PARTICULARLY IN OLDER OR MORE TECHNICAL LITERATURE – THIS IS FROM THE PERSPECTIVE OF THE REFERENCED ENTITY, NOT THE REFERENCING NAME. [..] THE TERM "SCOPE" IS ALSO USED TO REFER TO THE SET OF ALL ENTITIES THAT ARE VISIBLE OR NAMES THAT ARE VALID WITHIN A PORTION OF THE PROGRAM OR AT A GIVEN POINT IN A PROGRAM, WHICH IS MORE CORRECTLY REFERRED TO AS CONTEXT OR ENVIRONMENT.
http://en.wikipedia.org/wiki/Scope_%28computer_science%29
IN COMPUTER PROGRAMMING, THE SCOPE OF A NAME BINDING – AN ASSOCIATION OF A NAME TO AN ENTITY, SUCH AS A VARIABLE – IS THE PART OF A COMPUTER PROGRAM WHERE THE BINDING IS VALID: WHERE THE NAME CAN BE USED TO REFER TO THE ENTITY. IN OTHER PARTS OF THE PROGRAM THE NAME MAY REFER TO A DIFFERENT ENTITY (IT MAY HAVE A DIFFERENT BINDING), OR TO NOTHING AT ALL (IT MAY BE UNBOUND). THE SCOPE OF A BINDING IS ALSO KNOWN AS THE VISIBILITY OF AN ENTITY, PARTICULARLY IN OLDER OR MORE TECHNICAL LITERATURE – THIS IS FROM THE PERSPECTIVE OF THE REFERENCED ENTITY, NOT THE REFERENCING NAME. [..] THE TERM "SCOPE" IS ALSO USED TO REFER TO THE SET OF ALL ENTITIES THAT ARE VISIBLE OR NAMES THAT ARE VALID WITHIN A PORTION OF THE PROGRAM OR AT A GIVEN POINT IN A PROGRAM, WHICH IS MORE CORRECTLY REFERRED TO AS CONTEXT OR ENVIRONMENT.
http://en.wikipedia.org/wiki/Scope_%28computer_science%29
IScope and its Clients
Linking:getSingleElement(QualifiedName)
ContentAssist:getAllElements()
Serialization:getElements(EObject)
IScope DisassembledMultimap-like Structure
Two Different Keys
Multimap<QualifiedName, IEObjectDescription>
Multimap<EObject, IEObjectDescription>
Typically Stacked
Shadowing Semantics
Multimaps from FOP View
Multimap<K, V>
~= Map<K, Collection<V>>
~= get(K): Collection<V>
~= (K) -> V*
IScope from FOP View
{ (QualifiedName) -> IEObjectDescription*, (EObject) -> IEObjectDescription* () -> IEObjectDescription*}
IScopeProvidergetScope(EObject ctx, EReference ref):IScope
EObject ctx
Linking: Owner of Reference
Content Assist: Best Known Container
EReference ref
Reflective representation, e.g. TYPE__SUPER_TYPE for Type.getSuperType()
Embrace (QN)->IEODDecorate the Produced Scope, e.greturn new SimpleScope(orig) {..}
Override #getSingleElement(QualifiedName)
Decorate the IEObjectDescriptionreturn new AliasedEObjectDescription {..}
Perform Side-Effect on #getEObjectOrProxy
Validation Meets Scoping
Don’t Limit Content of Scope ‘Arbitrarily’
Include Potentially Invalid Descriptions
Improve User Experience (Navigation, Error Messages)
Add Error or Warning, if Description is Invalidctx.eResource().getErrors().add(..)
Validation Meets Scopingpublic class ErrorAddingDescription extends AliasedEObjectDescription { ErrorAddingDescription(EObject ctx, IEObjectDescription desc) {..} @Override public EObject getEObjectOrProxy() { ctx.eResource().getErrors().add( new EObjectDiagnosticImpl(..)) return super.getEObjectOrProxy(); } }
Detect Unused Locals
Mark Local Declarations as Unused
Local Vars
Import Declarations
Potentially Expensive Validation
Install EMF Adapter on Used Instances
public class MarkAsUsedDescription extends AliasedEObjectDescription { MarkAsUsedDescription(EObject ctx, IEObjectDescription desc) { .. } @Override public EObject getEObjectOrProxy() { EObject result = super.getEObjectOrProxy(); if (result.eResource() == ctx.eResource()) UsageMarkerAdapter.markAsUsed(result); return result; } }
Detect Unused Locals
@Checkpublic void markAsUnused(LocalVar var) { if (UsageMarkerAdapter.isUnused(var)) { addWarning(var, ..) } }
Detect Unused Locals
Avoid Follow-up Errors
Encountered EMF Proxy During getScope(..)
Often Follow-Up Error Situation
Return Scope with Dummy Description
Don’t Produce Unnecessary Errors
Avoid Subsequent Resolution Attempts
public class ErrorScope implements IScope { ErrorScope(EObject ctx, EReference ref) { .. } public IEObjectDescription getSingleElement( QualifiedName name) { return new ErrorDescription(name, ctx, ref); } .. }
Avoid Follow-up Errors
Avoid Follow-up Errorspublic class ErrorDescription extends AliasedEObjectDescription { ErrorDescription(QualifiedName name, EObject ctx, EReference ref) { .. } @Override public EObject getEObjectOrProxy() { return (EObject) ctx.eGet(ref, false); // simplified } }
Dynamic Scopes
Dynamic Languages Allow to Refer Anything
Returns Dynamic Description if Name is Unknown
Record Obtained Descriptions for Later Reuse
Special Case of ErrorScope
This is not the context you’re looking forgetScope(EObject ctx, EReference ref)
Content Assist Works on Invalid Documents
Parser Produces Trees rather than a Forest
Best Effort Context Computation
Beware of ClassCastException in getScope(..)
Don’t Enumerate the WorldAvoid eResource().getResourceSet()
and eAllContents()
Embrace the Defaults
Index Queries
Local Resource Contents is Indexed & Cached
Cache Scopes if Necessary (e.g. MapBasedScope)
!
Get Rid of Reflective API
Extendo.e.x.s.impl.DelegatingScopeProvider
Implement #getScope(..) based on EReferenceif (ref == MyDslPackage.Literals…)
Generally Faster & Easier to Debug
Avoid Loading the WorldPut Necessary Information Into Index
User Data Makes Great Filter-Criteria
Index Objects with Aliases / Multiple Names
Use AliasedEObjectDescription for Local Synonyms
If you invoke getEObjectOrProxy() you’re doing it wrong. Usually.