List of usage examples for org.eclipse.jdt.internal.compiler.lookup MethodScope referenceMethod
public AbstractMethodDeclaration referenceMethod()
From source file:com.codenvy.ide.ext.java.server.internal.core.util.HandleFactory.java
License:Open Source License
/** * Create handle by adding child to parent obtained by recursing into parent scopes. *//* w ww . j av a 2 s .c o m*/ private IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit, HashSet existingElements, HashMap knownScopes) { IJavaElement newElement = (IJavaElement) knownScopes.get(scope); if (newElement != null) return newElement; switch (scope.kind) { case Scope.COMPILATION_UNIT_SCOPE: newElement = unit; break; case Scope.CLASS_SCOPE: IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); switch (parentElement.getElementType()) { case IJavaElement.COMPILATION_UNIT: newElement = ((ICompilationUnit) parentElement) .getType(new String(scope.enclosingSourceType().sourceName)); break; case IJavaElement.TYPE: newElement = ((IType) parentElement).getType(new String(scope.enclosingSourceType().sourceName)); break; case IJavaElement.FIELD: case IJavaElement.INITIALIZER: case IJavaElement.METHOD: IMember member = (IMember) parentElement; if (member.isBinary()) { return null; } else { newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1); // increment occurrence count if collision is detected if (newElement != null) { while (!existingElements.add(newElement)) ((SourceRefElement) newElement).occurrenceCount++; } } break; } if (newElement != null) { knownScopes.put(scope, newElement); } break; case Scope.METHOD_SCOPE: IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); MethodScope methodScope = (MethodScope) scope; if (methodScope.isInsideInitializer()) { // inside field or initializer, must find proper one TypeDeclaration type = methodScope.referenceType(); int occurenceCount = 1; int length = type.fields == null ? 0 : type.fields.length; for (int i = 0; i < length; i++) { FieldDeclaration field = type.fields[i]; if (field.declarationSourceStart <= elementPosition && elementPosition <= field.declarationSourceEnd) { switch (field.getKind()) { case AbstractVariableDeclaration.FIELD: case AbstractVariableDeclaration.ENUM_CONSTANT: newElement = parentType.getField(new String(field.name)); break; case AbstractVariableDeclaration.INITIALIZER: newElement = parentType.getInitializer(occurenceCount); break; } break; } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) { occurenceCount++; } } } else { // method element AbstractMethodDeclaration method = methodScope.referenceMethod(); newElement = parentType.getMethod(new String(method.selector), Util.typeParameterSignatures(method)); if (newElement != null) { knownScopes.put(scope, newElement); } } break; case Scope.BLOCK_SCOPE: // standard block, no element per se newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); break; } return newElement; }
From source file:org.eclipse.che.jdt.internal.core.util.HandleFactory.java
License:Open Source License
/** * Create handle by adding child to parent obtained by recursing into parent scopes. *//* ww w . j a v a2 s .c om*/ public IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit, HashSet existingElements, HashMap knownScopes) { IJavaElement newElement = (IJavaElement) knownScopes.get(scope); if (newElement != null) return newElement; switch (scope.kind) { case Scope.COMPILATION_UNIT_SCOPE: newElement = unit; break; case Scope.CLASS_SCOPE: IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); switch (parentElement.getElementType()) { case IJavaElement.COMPILATION_UNIT: newElement = ((ICompilationUnit) parentElement) .getType(new String(scope.enclosingSourceType().sourceName)); break; case IJavaElement.TYPE: newElement = ((IType) parentElement).getType(new String(scope.enclosingSourceType().sourceName)); break; case IJavaElement.FIELD: case IJavaElement.INITIALIZER: case IJavaElement.METHOD: IMember member = (IMember) parentElement; if (member.isBinary()) { return null; } else { newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1); // increment occurrence count if collision is detected if (newElement != null) { while (!existingElements.add(newElement)) ((SourceRefElement) newElement).occurrenceCount++; } } break; } if (newElement != null) { knownScopes.put(scope, newElement); } break; case Scope.METHOD_SCOPE: if (scope.isLambdaScope()) { parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); LambdaExpression expression = (LambdaExpression) scope.originalReferenceContext(); if (expression.resolvedType != null && expression.resolvedType.isValidBinding() && !(expression.descriptor instanceof ProblemMethodBinding)) { // chain in lambda element only if resolved properly. //newElement = new org.eclipse.jdt.internal.core.SourceLambdaExpression((JavaElement) parentElement, expression) // .getMethod(); newElement = LambdaFactory.createLambdaExpression((JavaElement) parentElement, expression) .getMethod(); knownScopes.put(scope, newElement); return newElement; } return parentElement; } IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); MethodScope methodScope = (MethodScope) scope; if (methodScope.isInsideInitializer()) { // inside field or initializer, must find proper one TypeDeclaration type = methodScope.referenceType(); int occurenceCount = 1; int length = type.fields == null ? 0 : type.fields.length; for (int i = 0; i < length; i++) { FieldDeclaration field = type.fields[i]; if (field.declarationSourceStart <= elementPosition && elementPosition <= field.declarationSourceEnd) { switch (field.getKind()) { case AbstractVariableDeclaration.FIELD: case AbstractVariableDeclaration.ENUM_CONSTANT: newElement = parentType.getField(new String(field.name)); break; case AbstractVariableDeclaration.INITIALIZER: newElement = parentType.getInitializer(occurenceCount); break; } break; } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) { occurenceCount++; } } } else { // method element AbstractMethodDeclaration method = methodScope.referenceMethod(); newElement = parentType.getMethod(new String(method.selector), Util.typeParameterSignatures(method)); if (newElement != null) { knownScopes.put(scope, newElement); } } break; case Scope.BLOCK_SCOPE: // standard block, no element per se newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes); break; } return newElement; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
final Binding getTypeOrPackage(char[] name, int mask, boolean needResolve) { Scope scope = this; ReferenceBinding foundType = null;/*w w w. j av a2s. co m*/ boolean insideStaticContext = false; boolean insideTypeAnnotation = false; if ((mask & Binding.TYPE) == 0) { Scope next = scope; while ((next = scope.parent) != null) scope = next; } else { boolean inheritedHasPrecedence = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4; done: while (true) { // done when a COMPILATION_UNIT_SCOPE is found switch (scope.kind) { case METHOD_SCOPE: MethodScope methodScope = (MethodScope) scope; AbstractMethodDeclaration methodDecl = methodScope.referenceMethod(); if (methodDecl != null) { if (methodDecl.binding != null) { TypeVariableBinding typeVariable = methodDecl.binding.getTypeVariable(name); if (typeVariable != null) return typeVariable; } else { // use the methodDecl's typeParameters to handle problem cases when the method binding doesn't exist TypeParameter[] params = methodDecl.typeParameters(); for (int i = params == null ? 0 : params.length; --i >= 0;) if (CharOperation.equals(params[i].name, name)) if (params[i].binding != null && params[i].binding.isValidBinding()) return params[i].binding; } } insideStaticContext |= methodScope.isStatic; insideTypeAnnotation = methodScope.insideTypeAnnotation; //$FALL-THROUGH$ case BLOCK_SCOPE: ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only if (localType != null) { if (foundType != null && foundType != localType) return new ProblemReferenceBinding(new char[][] { name }, foundType, ProblemReasons.InheritedNameHidesEnclosingName); return localType; } break; case CLASS_SCOPE: SourceTypeBinding sourceType = ((ClassScope) scope).referenceContext.binding; if (scope == this && (sourceType.tagBits & TagBits.TypeVariablesAreConnected) == 0) { // type variables take precedence over the source type, ex. class X <X> extends X == class X <Y> extends Y // but not when we step out to the enclosing type TypeVariableBinding typeVariable = sourceType.getTypeVariable(name); if (typeVariable != null) return typeVariable; if (CharOperation.equals(name, sourceType.sourceName)) return sourceType; insideStaticContext |= sourceType.isStatic(); break; } // member types take precedence over type variables if (!insideTypeAnnotation) { // 6.5.5.1 - member types have precedence over top-level type in same unit ReferenceBinding memberType = findMemberType(name, sourceType); if (memberType != null) { // skip it if we did not find anything if (memberType.problemId() == ProblemReasons.Ambiguous) { if (foundType == null || foundType.problemId() == ProblemReasons.NotVisible) // supercedes any potential InheritedNameHidesEnclosingName problem return memberType; // make the user qualify the type, likely wants the first inherited type return new ProblemReferenceBinding(new char[][] { name }, foundType, ProblemReasons.InheritedNameHidesEnclosingName); } if (memberType.isValidBinding()) { if (sourceType == memberType.enclosingType() || inheritedHasPrecedence) { if (insideStaticContext && !memberType.isStatic() && sourceType.isGenericType()) return new ProblemReferenceBinding(new char[][] { name }, memberType, ProblemReasons.NonStaticReferenceInStaticContext); // found a valid type in the 'immediate' scope (i.e. not inherited) // OR in 1.4 mode (inherited visible shadows enclosing) if (foundType == null || (inheritedHasPrecedence && foundType.problemId() == ProblemReasons.NotVisible)) return memberType; // if a valid type was found, complain when another is found in an 'immediate' enclosing type (i.e. not inherited) if (foundType.isValidBinding() && foundType != memberType) return new ProblemReferenceBinding(new char[][] { name }, foundType, ProblemReasons.InheritedNameHidesEnclosingName); } } if (foundType == null || (foundType.problemId() == ProblemReasons.NotVisible && memberType.problemId() != ProblemReasons.NotVisible)) // only remember the memberType if its the first one found or the previous one was not visible & memberType is... foundType = memberType; } } TypeVariableBinding typeVariable = sourceType.getTypeVariable(name); if (typeVariable != null) { if (insideStaticContext) // do not consider this type modifiers: access is legite within same type return new ProblemReferenceBinding(new char[][] { name }, typeVariable, ProblemReasons.NonStaticReferenceInStaticContext); return typeVariable; } insideStaticContext |= sourceType.isStatic(); insideTypeAnnotation = false; if (CharOperation.equals(sourceType.sourceName, name)) { if (foundType != null && foundType != sourceType && foundType.problemId() != ProblemReasons.NotVisible) return new ProblemReferenceBinding(new char[][] { name }, foundType, ProblemReasons.InheritedNameHidesEnclosingName); return sourceType; } break; case COMPILATION_UNIT_SCOPE: break done; } scope = scope.parent; } if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible) return foundType; } // at this point the scope is a compilation unit scope CompilationUnitScope unitScope = (CompilationUnitScope) scope; HashtableOfObject typeOrPackageCache = unitScope.typeOrPackageCache; if (typeOrPackageCache != null) { Binding cachedBinding = (Binding) typeOrPackageCache.get(name); if (cachedBinding != null) { // can also include NotFound ProblemReferenceBindings if we already know this name is not found if (cachedBinding instanceof ImportBinding) { // single type import cached in faultInImports(), replace it in the cache with the type ImportReference importReference = ((ImportBinding) cachedBinding).reference; if (importReference != null) { importReference.bits |= ASTNode.Used; } if (cachedBinding instanceof ImportConflictBinding) typeOrPackageCache.put(name, cachedBinding = ((ImportConflictBinding) cachedBinding).conflictingTypeBinding); // already know its visible else typeOrPackageCache.put(name, cachedBinding = ((ImportBinding) cachedBinding).resolvedImport); // already know its visible } if ((mask & Binding.TYPE) != 0) { if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible && cachedBinding.problemId() != ProblemReasons.Ambiguous) return foundType; // problem type from above supercedes NotFound type but not Ambiguous import case if (cachedBinding instanceof ReferenceBinding) return cachedBinding; // cached type found in previous walk below } if ((mask & Binding.PACKAGE) != 0 && cachedBinding instanceof PackageBinding) return cachedBinding; // cached package found in previous walk below } } // ask for the imports + name if ((mask & Binding.TYPE) != 0) { ImportBinding[] imports = unitScope.imports; if (imports != null && typeOrPackageCache == null) { // walk single type imports since faultInImports() has not run yet nextImport: for (int i = 0, length = imports.length; i < length; i++) { ImportBinding importBinding = imports[i]; if (!importBinding.onDemand) { // GROOVY start /* old { if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) { } new */ if (CharOperation.equals(getSimpleName(importBinding), name)) { // GROOVY end Binding resolvedImport = unitScope.resolveSingleImport(importBinding, Binding.TYPE); if (resolvedImport == null) continue nextImport; if (resolvedImport instanceof TypeBinding) { ImportReference importReference = importBinding.reference; if (importReference != null) importReference.bits |= ASTNode.Used; return resolvedImport; // already know its visible } } } } } // check if the name is in the current package, skip it if its a sub-package PackageBinding currentPackage = unitScope.fPackage; unitScope.recordReference(currentPackage.compoundName, name); Binding binding = currentPackage.getTypeOrPackage(name); if (binding instanceof ReferenceBinding) { ReferenceBinding referenceType = (ReferenceBinding) binding; if ((referenceType.tagBits & TagBits.HasMissingType) == 0) { if (typeOrPackageCache != null) typeOrPackageCache.put(name, referenceType); return referenceType; // type is always visible to its own package } } // check on demand imports if (imports != null) { boolean foundInImport = false; ReferenceBinding type = null; for (int i = 0, length = imports.length; i < length; i++) { ImportBinding someImport = imports[i]; if (someImport.onDemand) { Binding resolvedImport = someImport.resolvedImport; ReferenceBinding temp = null; if (resolvedImport instanceof PackageBinding) { temp = findType(name, (PackageBinding) resolvedImport, currentPackage); } else if (someImport.isStatic()) { temp = findMemberType(name, (ReferenceBinding) resolvedImport); // static imports are allowed to see inherited member types if (temp != null && !temp.isStatic()) temp = null; } else { temp = findDirectMemberType(name, (ReferenceBinding) resolvedImport); } if (temp != type && temp != null) { if (temp.isValidBinding()) { // GROOVY - start - allow for imports expressed in source to override 'default' imports - GRECLIPSE-945 boolean conflict = true; // do we need to continue checking if (this.parent != null && foundInImport) { CompilationUnitScope cuScope = compilationUnitScope(); if (cuScope != null) { ReferenceBinding chosenBinding = cuScope.selectBinding(temp, type, someImport.reference != null); if (chosenBinding != null) { // The new binding was selected as a valid answer conflict = false; foundInImport = true; type = chosenBinding; } } } if (conflict) { // GROOVY - end ImportReference importReference = someImport.reference; if (importReference != null) { importReference.bits |= ASTNode.Used; } if (foundInImport) { // Answer error binding -- import on demand conflict; name found in two import on demand packages. temp = new ProblemReferenceBinding(new char[][] { name }, type, ProblemReasons.Ambiguous); if (typeOrPackageCache != null) typeOrPackageCache.put(name, temp); return temp; } type = temp; foundInImport = true; // GROOVY - start } // GROOVY - end } else if (foundType == null) { foundType = temp; } } } } if (type != null) { if (typeOrPackageCache != null) typeOrPackageCache.put(name, type); return type; } } } unitScope.recordSimpleReference(name); if ((mask & Binding.PACKAGE) != 0) { PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name); if (packageBinding != null) { if (typeOrPackageCache != null) typeOrPackageCache.put(name, packageBinding); return packageBinding; } } // Answer error binding -- could not find name if (foundType == null) { char[][] qName = new char[][] { name }; ReferenceBinding closestMatch = null; if ((mask & Binding.PACKAGE) != 0) { if (needResolve) { closestMatch = environment().createMissingType(unitScope.fPackage, qName); } } else { PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name); if (packageBinding == null || !packageBinding.isValidBinding()) { if (needResolve) { closestMatch = environment().createMissingType(unitScope.fPackage, qName); } } } foundType = new ProblemReferenceBinding(qName, closestMatch, ProblemReasons.NotFound); if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) { // only put NotFound type in cache if you know its not a package typeOrPackageCache.put(name, foundType); } } else if ((foundType.tagBits & TagBits.HasMissingType) != 0) { char[][] qName = new char[][] { name }; foundType = new ProblemReferenceBinding(qName, foundType, ProblemReasons.NotFound); if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) // only put NotFound type in cache if you know its not a package typeOrPackageCache.put(name, foundType); } return foundType; }
From source file:org.eclipse.objectteams.otdt.internal.codeassist.SelectionOnBaseCallMessageSend.java
License:Open Source License
public TypeBinding resolveType(BlockScope scope) { try {/*www . j a v a 2 s . co m*/ super.resolveType(scope); } catch (SelectionNodeFound snf) { if ((snf.binding instanceof MethodBinding) && MethodModel.isFakedMethod((MethodBinding) snf.binding)) { // fake method (e.g. basecall surrogate) is not valid, continue below } else { throw snf; } } MessageSend wrappee = this._sendOrig; // _wrappee might have been replaced with an Assignment. // tolerate some error cases if (wrappee.binding == null || !(wrappee.binding.isValidBinding() || wrappee.binding.problemId() == ProblemReasons.NotVisible || wrappee.binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName || wrappee.binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation || wrappee.binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext)) { throw new SelectionNodeFound(); } else { // wrappee.binding is the base call surrogate, find the proper enclosing method instead: MethodBinding callinMethod = null; MethodScope methodScope = scope.methodScope(); if (methodScope == null) throw new SelectionNodeFound(); MemberTypeBinding role = null; SourceTypeBinding site = scope.enclosingSourceType(); if (site.isLocalType()) { MethodDeclaration callinDecl = getOuterCallinMethod(methodScope); if (callinDecl == null) throw new SelectionNodeFound(); callinMethod = callinDecl.binding; role = (MemberTypeBinding) callinMethod.declaringClass; } else { callinMethod = methodScope.referenceMethod().binding; role = (MemberTypeBinding) site; } // find base methods bound in callin mappings which have callinMethod as their role method: MethodBinding[] baseBindings = findBaseMethodBindings(role, callinMethod); if (baseBindings == null || baseBindings.length == 0) { throw new SelectionNodeFound(); } else { throw new SelectionNodesFound(baseBindings); } } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend.java
License:Open Source License
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { flowInfo = super.analyseCode(currentScope, flowContext, flowInfo); MethodDeclaration callinMethod = getEnclosingCallinMethod(currentScope); LocalVariableBinding trackingVariable = callinMethod.baseCallTrackingVariable.binding; if (flowInfo.isDefinitelyAssigned(callinMethod.baseCallTrackingVariable)) currentScope.problemReporter().definitelyDuplicateBasecall(this._wrappee); else if (flowInfo.isPotentiallyAssigned(trackingVariable)) currentScope.problemReporter().potentiallyDuplicateBasecall(this._wrappee); else//from w ww . java2 s . co m flowInfo.markAsDefinitelyAssigned(trackingVariable); // check exceptions thrown by any bound base method: MethodScope methodScope = currentScope.methodScope(); if (methodScope != null) { MethodModel methodModel = methodScope.referenceMethod().binding.model; if (methodModel != null && methodModel._baseExceptions != null) { for (ReferenceBinding exceptionType : methodModel._baseExceptions) flowContext.checkExceptionHandlers(exceptionType, this, flowInfo, currentScope); } } if (this.isSuperAccess) // signal that the base call surrogate needs to handle super-access: MethodModel.addCallinFlag(currentScope.methodScope().referenceMethod(), IOTConstants.CALLIN_FLAG_BASE_SUPER_CALL); return flowInfo; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend.java
License:Open Source License
/** * If this base call resides in a local type retrieve the callin method enclosing that type. *//*from w w w. j a va 2 s . c o m*/ public static MethodDeclaration getOuterCallinMethod(MethodScope scope) { Scope parent = scope.parent; if (parent != null) { MethodScope outerMethodScope = parent.methodScope(); if (outerMethodScope == null) return null; AbstractMethodDeclaration outerMethod = outerMethodScope.referenceMethod(); if (outerMethod.isCallin()) return (MethodDeclaration) outerMethod; } return null; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies.java
License:Open Source License
/** * Perform several substitutions in method bodies. * (See TransformStatementsVisitor).//from ww w .jav a 2s . co m * * BinaryTypes: nothing to do. * * Recursion: NESTED_TEAMS. */ private static boolean establishStatementsTransformed(TypeModel clazz) { TypeDeclaration type = clazz.getAst(); if (type != null) { if (needMethodBodies(type)) { TransformStatementsVisitor transformer = new TransformStatementsVisitor(clazz.getWeavingScheme()); if ((type.bits & ASTNode.IsLocalType) != 0) { MethodScope methodScope = type.scope.methodScope(); if (methodScope != null) transformer.checkPushCallinMethod(methodScope.referenceMethod()); } type.traverse(transformer, type.scope.compilationUnitScope()); } else if (clazz.isTeam()) { if (type.memberTypes != null) { for (int i = 0; i < type.memberTypes.length; i++) { establishStatementsTransformed(type.memberTypes[i].getRoleModel()); } } } if (needMethodBodies(type) || type.isConverted) // converted types may contain local types but no other statements! { RecordLocalTypesVisitor recorder = new RecordLocalTypesVisitor(); recorder.recordLocalTypesFor(type); } } clazz.setState(ITranslationStates.STATE_STATEMENTS_TRANSFORMED); clazz.setMemberState(ITranslationStates.STATE_STATEMENTS_TRANSFORMED); return true; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementor.java
License:Open Source License
/** * the expression _OT$role.roleMethod(..) should not wrap its * return type anchored to the generated team anchor _OT$role, * because the method should actually be seen as being within * the scope of this role already, although, physically it is part of * the team.//from w w w.j av a2 s . c om * * @param scope use the scope to determine if we are acutally within * a callin wrapper. * @param receiver if this is _OT$role this is the role method call. * @return true if the return type should not be wrapped further. */ public static boolean avoidWrapRoleType(BlockScope scope, Expression receiver) { MethodScope methodScope = scope.methodScope(); if (methodScope != null) { // CLOVER: never false in jacks suite AbstractMethodDeclaration refMethod = methodScope.referenceMethod(); if (refMethod != null && refMethod.isMappingWrapper._callin()) { if (receiver instanceof SingleNameReference && CharOperation.equals(((SingleNameReference) receiver).token, CharOperation.concat(IOTConstants.OT_DOLLAR_NAME, IOTConstants.ROLE))) return true; } } return false; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java
License:Open Source License
/** * This method assumes that the enclosing type of scope can be used for * tthis anchors, i.e., types are used unqualified. * * @param scope determines tthis (NON-NULL). * @param typeToWrap/*from w w w . j av a 2s. c om*/ * @param typedNode * @return valid type, null (possibly after reporting error), or (unreported) problem */ public static TypeBinding maybeWrapUnqualifiedRoleType(Scope scope, TypeBinding typeToWrap, ASTNode typedNode) { /* external invocations (via maybeWrapUnqualifiedRoleType(TypeBinding, Scope, AstNode)?): * AllocationExpression.resolveType() new R R * ArrayAllocationExpression.resolveType() new R[] R * Assignment.resolveType() lhs = r type(r) * CastExpression.resolveType() (R)expr R * LocalDeclaration.resolve() R l = r R, type(r) * PotentialLiftExpression.resolveType() liftToR(b) R * RoleTypeReference.resolveType() this.R R * SingleNameReference.resolveType() n type(n) * ThisReference.resolveType() this type(this) * QualifiedThisReference.resolveType() Mid.this type(this) * other invocations: * MethodVerifier.areTypesEqual() * CopyInheritance.copyCastToMethods() * AbstractMethodMappingDeclaration.resolveMethodSpecs() * other internal invocation: * wrapTypesInMethodBindingSignature() * wrapTypesInMethodDeclSignature() * (via maybeWrapUnqualifiedRoleType(TypeBinding, Scope, AstNode)) * */ ReferenceBinding site = scope.enclosingSourceType(); MethodScope methodScope = scope.methodScope(); if (methodScope != null && methodScope.referenceMethod() != null && methodScope.referenceMethod().isMappingWrapper._callin() //{OTDyn && scope.compilerOptions().weavingScheme == WeavingScheme.OTRE) // this heuristic doesn't work for dyn weaving, FIXME(SH): check if still needed! // SH} { // in a callin wrapper, for visibility reasons, pretend we are in the // scope of the role (which is, where the declaration actually occurs): char[] selector = methodScope.referenceMethod().selector; int secondDollar = CharOperation.indexOf('$', selector, 4); // skip _OT$ char[] roleName = CharOperation.subarray(selector, 4, secondDollar); site = site.getMemberType(roleName); } return maybeWrapUnqualifiedRoleType(scope, site, typeToWrap, typedNode, scope.problemReporter()); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.RoleTypeCreator.java
License:Open Source License
/** * Try to resolve an argument or return type as an anchored type. * * PRE: Regular type resolution has already failed. * * Currently only handles references of two components: anchor and Type. * (for parameters this is probably OK?) * NO: TODO(SH): arguments could also be anchored to arbitrary expressions/paths! * * @param type type reference to be analyzed (resolvedType is null or invalid) * @param arguments the arguments of the current method * @param index position of the argument to be analyzed * == arguments.length means: analyzing return type. * @param scope scope of the current method. * @return a RoleTypeBinding or null (after reporting error) *///w ww.j a v a 2 s. c o m public static TypeBinding getTypeAnchoredToParameter(TypeReference type, Argument[] arguments, int index, MethodScope scope, CheckPoint cp) { // we only handle QualifiedTypeReferences of length 2, or QualifiedArrayTypeReferences. if (!(type instanceof QualifiedTypeReference)) { return null; // not better than before } QualifiedTypeReference argType = (QualifiedTypeReference) type; // look for anchor in argument list: VariableBinding anchor = null; char[] anchorName = argType.tokens[0]; int argPos; for (argPos = 0; argPos < index; argPos++) { Argument argument = arguments[argPos]; // ensure arguments are bound, which must happen in correct order. argument.bind(scope, argument.type.resolvedType, /*used*/false); if (CharOperation.equals(argument.name, anchorName)) // compare possible anchor { argument.binding.useFlag = LocalVariableBinding.USED; // used as anchor anchor = argument.binding; if (scope.classScope().referenceContext.isConverted) anchor.modifiers |= ClassFileConstants.AccFinal; // lost during conversion. break; } } if (anchor == null) { argPos = -1; // mark as not found in argument list anchor = findAnchorInScope(scope, anchorName); } if (anchor == null) return null; // not better than before. if (!anchor.isFinal()) { char[][] typeName = type.getTypeName(); scope.problemReporter().anchorPathNotFinal(argType, anchor, typeName[typeName.length - 1]); return null; } // defensive programming: if (anchor.type == null) return null; // anchor must be a team: if (!anchor.type.isTeam()) { if (!anchor.type.isValidBinding()) return null; //can't decide whether this is a valid team or not. reportAnchorIsNotATeam(scope, argType); return null; } // delegate for role type lookup: TypeBinding anchoredType = resolveOtherPathElements(scope, type, anchor, argType.tokens, 1, argType.dimensions()); if (anchoredType != null) { if (!anchoredType.isValidBinding()) { scope.problemReporter().invalidType(type, anchoredType); return null; } if (anchoredType.leafComponentType().isRoleType()) { // prepare for creating an AnchorListAttribute RoleTypeBinding leafRoleType = (RoleTypeBinding) anchoredType.leafComponentType(); leafRoleType._argumentPosition = argPos; final AbstractMethodDeclaration methodDecl = scope.referenceMethod(); leafRoleType._declaringMethod = new DependentTypeBinding.IMethodProvider() { public MethodBinding getMethod() { return methodDecl.binding; } }; } scope.referenceContext.compilationResult().rollBack(cp); scope.problemReporter().deprecatedPathSyntax(type); } return anchoredType; }