List of usage examples for org.eclipse.jdt.internal.compiler.lookup MethodBinding problemId
public int problemId()
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite, boolean inStaticContext) { ReferenceBinding currentType = receiverType; boolean receiverTypeIsInterface = receiverType.isInterface(); ObjectVector found = new ObjectVector(3); CompilationUnitScope unitScope = compilationUnitScope(); unitScope.recordTypeReferences(argumentTypes); if (receiverTypeIsInterface) { unitScope.recordTypeReference(receiverType); MethodBinding[] receiverMethods = receiverType.getMethods(selector, argumentTypes.length); if (receiverMethods.length > 0) found.addAll(receiverMethods); findMethodInSuperInterfaces(receiverType, selector, found, invocationSite); currentType = getJavaLangObject(); }// w w w . j a v a2 s.c o m // superclass lookup long complianceLevel = compilerOptions().complianceLevel; boolean isCompliant14 = complianceLevel >= ClassFileConstants.JDK1_4; boolean isCompliant15 = complianceLevel >= ClassFileConstants.JDK1_5; ReferenceBinding classHierarchyStart = currentType; MethodVerifier verifier = environment().methodVerifier(); while (currentType != null) { unitScope.recordTypeReference(currentType); currentType = (ReferenceBinding) currentType.capture(this, invocationSite == null ? 0 : invocationSite.sourceEnd()); MethodBinding[] currentMethods = currentType.getMethods(selector, argumentTypes.length); int currentLength = currentMethods.length; if (currentLength > 0) { if (isCompliant14 && (receiverTypeIsInterface || found.size > 0)) { nextMethod: for (int i = 0, l = currentLength; i < l; i++) { // currentLength can be modified inside the loop MethodBinding currentMethod = currentMethods[i]; if (currentMethod == null) continue nextMethod; if (receiverTypeIsInterface && !currentMethod.isPublic()) { // only public methods from Object are visible to interface receiverTypes currentLength--; currentMethods[i] = null; continue nextMethod; } // if 1.4 compliant, must filter out redundant protected methods from superclasses // protected method need to be checked only - default access is already dealt with in #canBeSeen implementation // when checking that p.C -> q.B -> p.A cannot see default access members from A through B. // if ((currentMethod.modifiers & AccProtected) == 0) continue nextMethod; // BUT we can also ignore any overridden method since we already know the better match (fixes 80028) for (int j = 0, max = found.size; j < max; j++) { MethodBinding matchingMethod = (MethodBinding) found.elementAt(j); MethodBinding matchingOriginal = matchingMethod.original(); MethodBinding currentOriginal = matchingOriginal .findOriginalInheritedMethod(currentMethod); if (currentOriginal != null && verifier.isParameterSubsignature(matchingOriginal, currentOriginal)) { if (isCompliant15) { if (matchingMethod.isBridge() && !currentMethod.isBridge()) continue nextMethod; // keep inherited methods to find concrete method over a bridge method } currentLength--; currentMethods[i] = null; continue nextMethod; } } } } if (currentLength > 0) { // append currentMethods, filtering out null entries if (currentMethods.length == currentLength) { found.addAll(currentMethods); } else { for (int i = 0, max = currentMethods.length; i < max; i++) { MethodBinding currentMethod = currentMethods[i]; if (currentMethod != null) found.add(currentMethod); } } } } currentType = currentType.superclass(); } // if found several candidates, then eliminate those not matching argument types int foundSize = found.size; MethodBinding[] candidates = null; int candidatesCount = 0; MethodBinding problemMethod = null; boolean searchForDefaultAbstractMethod = isCompliant14 && !receiverTypeIsInterface && (receiverType.isAbstract() || receiverType.isTypeVariable()); if (foundSize > 0) { // argument type compatibility check for (int i = 0; i < foundSize; i++) { MethodBinding methodBinding = (MethodBinding) found.elementAt(i); MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite); if (compatibleMethod != null) { if (compatibleMethod.isValidBinding()) { if (foundSize == 1 && compatibleMethod.canBeSeenBy(receiverType, invocationSite, this)) { // return the single visible match now if (searchForDefaultAbstractMethod) return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, compatibleMethod); unitScope.recordTypeReferences(compatibleMethod.thrownExceptions); return compatibleMethod; } if (candidatesCount == 0) candidates = new MethodBinding[foundSize]; candidates[candidatesCount++] = compatibleMethod; } else if (problemMethod == null) { problemMethod = compatibleMethod; } } } } // no match was found if (candidatesCount == 0) { if (problemMethod != null) { switch (problemMethod.problemId()) { case ProblemReasons.TypeArgumentsForRawGenericMethod: case ProblemReasons.TypeParameterArityMismatch: return problemMethod; } } // abstract classes may get a match in interfaces; for non abstract // classes, reduces secondary errors since missing interface method // error is already reported MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null); if (interfaceMethod != null) return interfaceMethod; if (found.size == 0) return null; if (problemMethod != null) return problemMethod; // still no match; try to find a close match when the parameter // order is wrong or missing some parameters // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=69471 // bad guesses are foo(), when argument types have been supplied // and foo(X, Y), when the argument types are (int, float, Y) // so answer the method with the most argType matches and least parameter type mismatches int bestArgMatches = -1; MethodBinding bestGuess = (MethodBinding) found.elementAt(0); // if no good match so just use the first one found int argLength = argumentTypes.length; foundSize = found.size; nextMethod: for (int i = 0; i < foundSize; i++) { MethodBinding methodBinding = (MethodBinding) found.elementAt(i); TypeBinding[] params = methodBinding.parameters; int paramLength = params.length; int argMatches = 0; next: for (int a = 0; a < argLength; a++) { TypeBinding arg = argumentTypes[a]; for (int p = a == 0 ? 0 : a - 1; p < paramLength && p < a + 1; p++) { // look one slot before & after to see if the type matches if (params[p] == arg) { argMatches++; continue next; } } } if (argMatches < bestArgMatches) continue nextMethod; if (argMatches == bestArgMatches) { int diff1 = paramLength < argLength ? 2 * (argLength - paramLength) : paramLength - argLength; int bestLength = bestGuess.parameters.length; int diff2 = bestLength < argLength ? 2 * (argLength - bestLength) : bestLength - argLength; if (diff1 >= diff2) continue nextMethod; } bestArgMatches = argMatches; bestGuess = methodBinding; } return new ProblemMethodBinding(bestGuess, bestGuess.selector, argumentTypes, ProblemReasons.NotFound); } // tiebreak using visibility check int visiblesCount = 0; if (receiverTypeIsInterface) { if (candidatesCount == 1) { unitScope.recordTypeReferences(candidates[0].thrownExceptions); return candidates[0]; } visiblesCount = candidatesCount; } else { for (int i = 0; i < candidatesCount; i++) { MethodBinding methodBinding = candidates[i]; if (methodBinding.canBeSeenBy(receiverType, invocationSite, this)) { if (visiblesCount != i) { candidates[i] = null; candidates[visiblesCount] = methodBinding; } visiblesCount++; } } switch (visiblesCount) { case 0: MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null); if (interfaceMethod != null) return interfaceMethod; return new ProblemMethodBinding(candidates[0], candidates[0].selector, candidates[0].parameters, ProblemReasons.NotVisible); case 1: if (searchForDefaultAbstractMethod) return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, candidates[0]); unitScope.recordTypeReferences(candidates[0].thrownExceptions); return candidates[0]; default: break; } } if (complianceLevel <= ClassFileConstants.JDK1_3) { ReferenceBinding declaringClass = candidates[0].declaringClass; return !declaringClass.isInterface() ? mostSpecificClassMethodBinding(candidates, visiblesCount, invocationSite) : mostSpecificInterfaceMethodBinding(candidates, visiblesCount, invocationSite); } // check for duplicate parameterized methods if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { for (int i = 0; i < visiblesCount; i++) { MethodBinding candidate = candidates[i]; if (candidate instanceof ParameterizedGenericMethodBinding) candidate = ((ParameterizedGenericMethodBinding) candidate).originalMethod; if (candidate.hasSubstitutedParameters()) { for (int j = i + 1; j < visiblesCount; j++) { MethodBinding otherCandidate = candidates[j]; if (otherCandidate.hasSubstitutedParameters()) { if (otherCandidate == candidate || (candidate.declaringClass == otherCandidate.declaringClass && candidate.areParametersEqual(otherCandidate))) { return new ProblemMethodBinding(candidates[i], candidates[i].selector, candidates[i].parameters, ProblemReasons.Ambiguous); } } } } } } if (inStaticContext) { MethodBinding[] staticCandidates = new MethodBinding[visiblesCount]; int staticCount = 0; for (int i = 0; i < visiblesCount; i++) if (candidates[i].isStatic()) staticCandidates[staticCount++] = candidates[i]; if (staticCount == 1) return staticCandidates[0]; if (staticCount > 1) return mostSpecificMethodBinding(staticCandidates, staticCount, argumentTypes, invocationSite, receiverType); } MethodBinding mostSpecificMethod = mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite, receiverType); if (searchForDefaultAbstractMethod) { // search interfaces for a better match if (mostSpecificMethod.isValidBinding()) // see if there is a better match in the interfaces - see AutoBoxingTest 99, LookupTest#81 return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, mostSpecificMethod); // see if there is a match in the interfaces - see LookupTest#84 MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null); if (interfaceMethod != null && interfaceMethod.isValidBinding() /* else return the same error as before */) return interfaceMethod; } return mostSpecificMethod; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
public MethodBinding getImplicitMethod(char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { boolean insideStaticContext = false; boolean insideConstructorCall = false; boolean insideTypeAnnotation = false; MethodBinding foundMethod = null;// w w w. j a v a 2 s . c o m MethodBinding foundProblem = null; boolean foundProblemVisible = false; Scope scope = this; int depth = 0; // in 1.4 mode (inherited visible shadows enclosing) CompilerOptions options; boolean inheritedHasPrecedence = (options = 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; insideStaticContext |= methodScope.isStatic; insideConstructorCall |= methodScope.isConstructorCall; insideTypeAnnotation = methodScope.insideTypeAnnotation; break; case CLASS_SCOPE: ClassScope classScope = (ClassScope) scope; ReferenceBinding receiverType = classScope.enclosingReceiverType(); if (!insideTypeAnnotation) { // retrieve an exact visible match (if possible) // compilationUnitScope().recordTypeReference(receiverType); not needed since receiver is the source type MethodBinding methodBinding = classScope.findExactMethod(receiverType, selector, argumentTypes, invocationSite); if (methodBinding == null) methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite); if (methodBinding != null) { // skip it if we did not find anything if (foundMethod == null) { if (methodBinding.isValidBinding()) { if (!methodBinding.isStatic() && (insideConstructorCall || insideStaticContext)) { if (foundProblem != null && foundProblem.problemId() != ProblemReasons.NotVisible) return foundProblem; // takes precedence return new ProblemMethodBinding(methodBinding, // closest match methodBinding.selector, methodBinding.parameters, insideConstructorCall ? ProblemReasons.NonStaticReferenceInConstructorInvocation : ProblemReasons.NonStaticReferenceInStaticContext); } if (inheritedHasPrecedence || receiverType == methodBinding.declaringClass || (receiverType.getMethods(selector)) != Binding.NO_METHODS) { // found a valid method in the 'immediate' scope (i.e. not inherited) // OR in 1.4 mode (inherited visible shadows enclosing) // OR the receiverType implemented a method with the correct name // return the methodBinding if it is not declared in a superclass of the scope's binding (that is, inherited) if (foundProblemVisible) { return foundProblem; } if (depth > 0) { invocationSite.setDepth(depth); invocationSite.setActualReceiverType(receiverType); } // special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type) if (argumentTypes == Binding.NO_PARAMETERS && CharOperation.equals(selector, TypeConstants.GETCLASS) && methodBinding.returnType.isParameterizedType()/*1.5*/) { return environment().createGetClassMethod(receiverType, methodBinding, this); } return methodBinding; } if (foundProblem == null || foundProblem.problemId() == ProblemReasons.NotVisible) { if (foundProblem != null) foundProblem = null; // only remember the methodBinding if its the first one found // remember that private methods are visible if defined directly by an enclosing class if (depth > 0) { invocationSite.setDepth(depth); invocationSite.setActualReceiverType(receiverType); } foundMethod = methodBinding; } } else { // methodBinding is a problem method if (methodBinding.problemId() != ProblemReasons.NotVisible && methodBinding.problemId() != ProblemReasons.NotFound) return methodBinding; // return the error now if (foundProblem == null) { foundProblem = methodBinding; // hold onto the first not visible/found error and keep the second not found if first is not visible } if (!foundProblemVisible && methodBinding.problemId() == ProblemReasons.NotFound) { MethodBinding closestMatch = ((ProblemMethodBinding) methodBinding).closestMatch; if (closestMatch != null && closestMatch.canBeSeenBy(receiverType, invocationSite, this)) { foundProblem = methodBinding; // hold onto the first not visible/found error and keep the second not found if first is not visible foundProblemVisible = true; } } } } else { // found a valid method so check to see if this is a hiding case if (methodBinding.problemId() == ProblemReasons.Ambiguous || (foundMethod.declaringClass != methodBinding.declaringClass && (receiverType == methodBinding.declaringClass || receiverType.getMethods(selector) != Binding.NO_METHODS))) // ambiguous case -> must qualify the method (javac generates an ambiguous error instead) // otherwise if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited) // NOTE: Unlike fields, a non visible method hides a visible method return new ProblemMethodBinding(methodBinding, // closest match selector, argumentTypes, ProblemReasons.InheritedNameHidesEnclosingName); } } } insideTypeAnnotation = false; depth++; insideStaticContext |= receiverType.isStatic(); // 1EX5I8Z - accessing outer fields within a constructor call is permitted // in order to do so, we change the flag as we exit from the type, not the method // itself, because the class scope is used to retrieve the fields. MethodScope enclosingMethodScope = scope.methodScope(); insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall; break; case COMPILATION_UNIT_SCOPE: break done; } scope = scope.parent; } if (insideStaticContext && options.sourceLevel >= ClassFileConstants.JDK1_5) { if (foundProblem != null) { if (foundProblem.declaringClass != null && foundProblem.declaringClass.id == TypeIds.T_JavaLangObject) return foundProblem; // static imports lose to methods from Object if (foundProblem.problemId() == ProblemReasons.NotFound && foundProblemVisible) { return foundProblem; // visible method selectors take precedence } } // at this point the scope is a compilation unit scope & need to check for imported static methods CompilationUnitScope unitScope = (CompilationUnitScope) scope; unitScope.faultInImports(); // field constants can cause static imports to be accessed before they're resolved ImportBinding[] imports = unitScope.imports; if (imports != null) { ObjectVector visible = null; boolean skipOnDemand = false; // set to true when matched static import of method name so stop looking for on demand methods for (int i = 0, length = imports.length; i < length; i++) { ImportBinding importBinding = imports[i]; if (importBinding.isStatic()) { Binding resolvedImport = importBinding.resolvedImport; MethodBinding possible = null; if (importBinding.onDemand) { if (!skipOnDemand && resolvedImport instanceof ReferenceBinding) // answers closest approximation, may not check argumentTypes or visibility possible = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes, invocationSite, true); } else { if (resolvedImport instanceof MethodBinding) { MethodBinding staticMethod = (MethodBinding) resolvedImport; if (CharOperation.equals(staticMethod.selector, selector)) // answers closest approximation, may not check argumentTypes or visibility possible = findMethod(staticMethod.declaringClass, selector, argumentTypes, invocationSite, true); } else if (resolvedImport instanceof FieldBinding) { // check to see if there are also methods with the same name FieldBinding staticField = (FieldBinding) resolvedImport; if (CharOperation.equals(staticField.name, selector)) { // must find the importRef's type again since the field can be from an inherited type char[][] importName = importBinding.reference.tokens; TypeBinding referencedType = getType(importName, importName.length - 1); if (referencedType != null) // answers closest approximation, may not check argumentTypes or visibility possible = findMethod((ReferenceBinding) referencedType, selector, argumentTypes, invocationSite, true); } } } if (possible != null && possible != foundProblem) { if (!possible.isValidBinding()) { if (foundProblem == null) foundProblem = possible; // answer as error case match } else if (possible.isStatic()) { MethodBinding compatibleMethod = computeCompatibleMethod(possible, argumentTypes, invocationSite); if (compatibleMethod != null) { if (compatibleMethod.isValidBinding()) { if (compatibleMethod.canBeSeenBy(unitScope.fPackage)) { if (visible == null || !visible.contains(compatibleMethod)) { ImportReference importReference = importBinding.reference; if (importReference != null) { importReference.bits |= ASTNode.Used; } if (!skipOnDemand && !importBinding.onDemand) { visible = null; // forget previous matches from on demand imports skipOnDemand = true; } if (visible == null) visible = new ObjectVector(3); visible.add(compatibleMethod); } } else if (foundProblem == null) { foundProblem = new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, ProblemReasons.NotVisible); } } else if (foundProblem == null) { foundProblem = compatibleMethod; } } else if (foundProblem == null) { foundProblem = new ProblemMethodBinding(possible, selector, argumentTypes, ProblemReasons.NotFound); } } } } } if (visible != null) { MethodBinding[] temp = new MethodBinding[visible.size]; visible.copyInto(temp); foundMethod = mostSpecificMethodBinding(temp, temp.length, argumentTypes, invocationSite, null); } } } if (foundMethod != null) { invocationSite.setActualReceiverType(foundMethod.declaringClass); return foundMethod; } if (foundProblem != null) return foundProblem; return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound); }
From source file:org.eclipse.objectteams.otdt.internal.codeassist.SelectionOnMethodSpec.java
License:Open Source License
@Override public void resolveFinished() { MethodBinding binding = this.resolvedMethod; // tolerate some error cases if (binding == null || !(binding.isValidBinding() || binding.problemId() == ProblemReasons.NotVisible || binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName || binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation || binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext)) { throw new SelectionNodeFound(); } else {/* www . j a va 2s .c o m*/ //{ObjectTeams: //method is part of a role if (binding.declaringClass.isRole()) { // method is copy inherited: use the original binding: if (binding.copyInheritanceSrc != null) throw new SelectionNodeFound(binding.copyInheritanceSrc); } //haebor} } throw new SelectionNodeFound(this.resolvedMethod); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend.java
License:Open Source License
@Override protected TypeBinding findMethodBinding(BlockScope scope) { // check: is a tsuper call legal in the current context? AbstractMethodDeclaration context = scope.methodScope().referenceMethod(); if (context == null || !CharOperation.equals(this.selector, context.selector) || context.binding.parameters.length != this.argumentTypes.length) { scope.problemReporter().tsuperCallsWrongMethod(this); return null; }// ww w .j ava 2 s .c o m ReferenceBinding receiverRole; if (!(this.actualReceiverType instanceof ReferenceBinding) || !(receiverRole = (ReferenceBinding) this.actualReceiverType).isSourceRole()) { scope.problemReporter().tsuperOutsideRole(context, this, this.actualReceiverType); return null; } ReferenceBinding[] tsuperRoleBindings = receiverRole.roleModel.getTSuperRoleBindings(); if (tsuperRoleBindings.length == 0) { scope.problemReporter().tsuperCallWithoutTsuperRole(receiverRole, this); return null; } // context is OK, start searching: this.tsuperReference.resolveType(scope); // qualified tsuper? => directly search within the designated tsuper role: if (this.tsuperReference.qualification != null) { TypeBinding tsuperRole = this.tsuperReference.resolvedType; if (tsuperRole == null || !tsuperRole.isRole()) return null; this.binding = scope.getMethod(tsuperRole, this.selector, this.argumentTypes, this); if (!this.binding.isValidBinding() && ((ProblemMethodBinding) this.binding).declaringClass == null) this.binding.declaringClass = (ReferenceBinding) tsuperRole; resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope); return this.binding.returnType; } // no qualification => search all tsupers by priority: MethodBinding bestMatch = null; for (int i = tsuperRoleBindings.length - 1; i >= 0; i--) { ReferenceBinding tsuperRole = tsuperRoleBindings[i]; MethodBinding candidate = scope.getMethod(tsuperRole, this.selector, this.argumentTypes, this); if (candidate.isValidBinding()) { if (scope.parameterCompatibilityLevel(candidate, this.argumentTypes) != Scope.COMPATIBLE) { scope.problemReporter().tsuperCallsWrongMethod(this); return candidate.returnType; } this.binding = candidate; resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope); return this.binding.returnType; } if (bestMatch == null || (bestMatch.problemId() == ProblemReasons.NotFound && candidate.problemId() != ProblemReasons.NotFound)) bestMatch = candidate; } if (bestMatch == null) bestMatch = new ProblemMethodBinding(this.selector, this.argumentTypes, ProblemReasons.NotFound); if (bestMatch.declaringClass == null) bestMatch.declaringClass = (ReferenceBinding) this.tsuperReference.resolvedType; this.binding = bestMatch; return this.binding.returnType; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend.java
License:Open Source License
@Override public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { // for code gen we need to add the marker arg... int len = this.binding.parameters.length; TypeBinding[] extendedParameters = new TypeBinding[len + 1]; System.arraycopy(this.binding.parameters, 0, extendedParameters, 0, len); char[] tSuperMarkName = TSuperHelper.getTSuperMarkName(this.tsuperReference.resolvedType.enclosingType()); extendedParameters[len] = currentScope.getType(tSuperMarkName); // ... and find the copied method binding MethodBinding codegenBinding = currentScope.getMethod(this.actualReceiverType, this.selector, extendedParameters, this); if (codegenBinding.problemId() == ProblemReasons.NotFound) { // tsuper.m() may in fact refer to tsuper.super.m(). // try to find the method as super.tsuper() instead: ReferenceBinding superRole = ((ReferenceBinding) this.receiver.resolvedType).superclass(); codegenBinding = getAlternateMethod(currentScope, superRole, extendedParameters); if (codegenBinding == null) codegenBinding = getAlternateMethod(currentScope, superRole, this.binding.parameters); if (codegenBinding == null) throw new InternalCompilerError("cannot find real method binding for tsuper call!"); //$NON-NLS-1$ this.receiver = new SuperReference(this.receiver.sourceStart, this.receiver.sourceEnd); this.receiver.resolvedType = superRole; this.receiver.constant = Constant.NotAConstant; this.actualReceiverType = superRole; }//from w ww .j a va 2s . co m MethodBinding tsuperMethod = this.binding; this.binding = codegenBinding; try { super.generateCode(currentScope, codeStream, valueRequired); } finally { this.binding = tsuperMethod; } if (valueRequired && this.binding.isCallin()) { if (this.resolvedType != null && this.resolvedType.isValidBinding()) { if (this.resolvedType.isBaseType()) { // something like: ((Integer)result).intValue() char[][] boxtypeName = AstGenerator.boxTypeName((BaseTypeBinding) this.resolvedType); codeStream.checkcast(currentScope.getType(boxtypeName, 3)); codeStream.generateUnboxingConversion(this.resolvedType.id); } else { // (RefType)result codeStream.checkcast(this.resolvedType); } } } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend.java
License:Open Source License
private MethodBinding getAlternateMethod(Scope scope, ReferenceBinding superRole, TypeBinding[] extendedArgumentTypes) { MethodBinding alternateMethod = scope.getMethod(superRole, this.selector, extendedArgumentTypes, this); if (alternateMethod.problemId() == ProblemReasons.NotVisible) { return alternateMethod; // want to see this error as IProblem.IndirectTSuperInvisible, cf. ProblemReporter.invalidMethod }/*from w w w.j ava 2 s . co m*/ MethodBinding alternateSrc = alternateMethod.copyInheritanceSrc; // TODO(SH): binary verbatim copies (no marker arg) are not recognized as copies! if (alternateSrc != null && isRoleOfSuperTeam(alternateSrc.declaringClass, scope)) return alternateMethod; return null; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding.java
License:Open Source License
/** Get the problemId of the first erroneous method binding or NoError. */ public int problemId() { if (this._roleMethodBinding != null && !this._roleMethodBinding.isValidBinding()) return this._roleMethodBinding.problemId(); if (this._baseMethods != null) for (MethodBinding method : this._baseMethods) if (!method.isValidBinding()) return method.problemId(); if (this._baseField != null) return this._baseField.problemId(); return ProblemReasons.NoError; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CalloutImplementor.java
License:Open Source License
/** This method drives the creation of a callout implementation for one callout mapping. */ private MethodDeclaration createCallout(CalloutMappingDeclaration calloutMappingDeclaration, boolean needBody, boolean isInferred) { CallinCalloutScope calloutScope = calloutMappingDeclaration.scope; calloutMappingDeclaration.updateTSuperMethods(); // This binding is part of the interface part of a role: MethodBinding roleMethodBinding = calloutMappingDeclaration.getRoleMethod(); if (roleMethodBinding == null) // CLOVER: never true in jacks suite {// w w w . j a v a 2 s . c o m // problemreporting already done in find-Base/Role-MethodBinding assert (calloutMappingDeclaration.ignoreFurtherInvestigation); return null; } if (!roleMethodBinding.isValidBinding()) { if (roleMethodBinding.problemId() != ProblemReasons.NotFound) { // CLOVER: never true in jacks suite calloutMappingDeclaration.tagAsHavingErrors(); // hopefully error has been reported! return null; } else { // shorthand style callout // help sourceMethod() below to find another callout method MethodBinding existingMethod = calloutScope.enclosingSourceType().getExactMethod( roleMethodBinding.selector, roleMethodBinding.parameters, calloutScope.compilationUnitScope()); if (existingMethod != null) roleMethodBinding = existingMethod; } } MethodDeclaration roleMethodDeclaration = null; if (TypeBinding.equalsEquals(roleMethodBinding.declaringClass, calloutScope.enclosingSourceType())) roleMethodDeclaration = (MethodDeclaration) roleMethodBinding.sourceMethod(); // have a binding but no declaration for method? -> requires creation of declaration boolean foundRoleDecl = roleMethodDeclaration != null; MethodBinding overriddenTSuper = null; // The following code allows to use tsuper in parameter mappings // (see 3.2.32-otjld-tsuper-access-1) if (foundRoleDecl && roleMethodDeclaration.isCopied // foundRoleDecl => (roleMethodDeclaration != null) && (roleMethodDeclaration.modifiers & AccAbstract) == 0 && !TSuperHelper.isTSuper(roleMethodDeclaration.binding)) { // mapping conflicts with an implicitly inherited method. // make the latter a tsuper version, now. overriddenTSuper = roleMethodBinding; // save a clone of the method binding before adding the marker arg, for use below. roleMethodBinding = new MethodBinding(roleMethodBinding, roleMethodBinding.declaringClass); // clone TSuperHelper.addMarkerArg(roleMethodDeclaration, roleMethodDeclaration.binding.copyInheritanceSrc.declaringClass.enclosingType()); foundRoleDecl = false; // re-create the method; } if (!foundRoleDecl) { roleMethodDeclaration = createAbstractRoleMethodDeclaration(roleMethodBinding, calloutMappingDeclaration); if (overriddenTSuper != null) roleMethodDeclaration.binding.addOverriddenTSuper(overriddenTSuper); } else { roleMethodDeclaration.isReusingSourceMethod = true; // foundRoleDecl => (roleMethodDeclaration != null) // mark existing method as generated by the callout mapping: roleMethodDeclaration.isMappingWrapper = WrapperKind.CALLOUT; // match locator may want to know this for the interface part, too: // (SH: unsure, if this is really needed, but it doesn't hurt either ;-) if (roleMethodDeclaration.interfacePartMethod != null) { roleMethodDeclaration.interfacePartMethod.isReusingSourceMethod = true; roleMethodDeclaration.interfacePartMethod.isMappingWrapper = WrapperKind.CALLOUT; } } if (calloutMappingDeclaration.hasSignature) { // Adjust arguments: Argument[] args = calloutMappingDeclaration.roleMethodSpec.arguments; if (args != null) { for (int i = 0; i < args.length; i++) { // if we already have a declaration and if we have signatures // in the mapping declaration, use the argument names from the // method mapping rather than those from the original declaration // (needed for parameter mapping!). if (foundRoleDecl) roleMethodDeclaration.arguments[i].updateName(args[i].name); // also link best names of arguments of roleMethodSpec and actual wrapper // ( requires wrapper argument to be bound, do this first. // Note that all args must be bound in order!). roleMethodDeclaration.arguments[i].bind(roleMethodDeclaration.scope, args[i].binding.type, false); args[i].binding.setBestNameFromStat(roleMethodDeclaration.arguments[i]); } } } if (roleMethodDeclaration != null) // try again { // Note: do not query the binding (as isAbstract() would do). // Binding may have corrected modifiers, but take the raw modifiers. if (!roleMethodDeclaration.isCopied && !roleMethodDeclaration.isGenerated && (roleMethodDeclaration.modifiers & AccAbstract) == 0) { // bad overriding of existing / non-existant methods is handled in MethodMappingResolver already roleMethodDeclaration.ignoreFurtherInvestigation = true; // don't throw "abstract method.. can only be defined by abstract class" error calloutScope.problemReporter().calloutOverridesLocal(this._role.getAst(), calloutMappingDeclaration, roleMethodDeclaration.binding); return null; } // fix flags (even if not needing body): roleMethodDeclaration.isCopied = false; int flagsToRemove = AccAbstract | ExtraCompilerModifiers.AccSemicolonBody | AccNative; roleMethodDeclaration.modifiers &= ~flagsToRemove; roleMethodDeclaration.binding.modifiers &= ~flagsToRemove; roleMethodDeclaration.isGenerated = true; // even if not generated via AstGenerator. if (needBody && calloutMappingDeclaration.binding.isValidBinding()) { // defer generation of statements: final CalloutMappingDeclaration mappingDeclaration = calloutMappingDeclaration; MethodModel methodModel = MethodModel.getModel(roleMethodDeclaration); if (isInferred) methodModel._inferredCallout = mappingDeclaration; methodModel.setStatementsGenerator(new AbstractStatementsGenerator() { public boolean generateStatements(AbstractMethodDeclaration methodDecl) { createCalloutMethodBody((MethodDeclaration) methodDecl, mappingDeclaration); return true; } }); } else if (calloutMappingDeclaration.ignoreFurtherInvestigation) { roleMethodDeclaration.binding.bytecodeMissing = true; // will not be generated, so don't complain later. } } else // roleMethodDeclaration still null { // CLOVER: never reached in jacks suite ;-) throw new InternalCompilerError("OT-Compiler Error: couldn't create method declaration for callout! " //$NON-NLS-1$ + calloutMappingDeclaration.toString()); } return roleMethodDeclaration; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CalloutImplementor.java
License:Open Source License
/** * Creates method in interface or class-part of _role. * @param templateBinding this method is used as a template for the method that * will be created.// w ww . ja v a2 s . c o m * @param calloutBindingDeclaration * @param part CLASS or INTERFACE * @return an empty method declaration */ private MethodDeclaration createAbstractRoleMethodDeclarationPart(MethodBinding templateBinding, CalloutMappingDeclaration calloutBindingDeclaration, int modifiers, int part) { assert (templateBinding != null); AstGenerator gen = new AstGenerator(calloutBindingDeclaration.sourceStart, calloutBindingDeclaration.sourceEnd); TypeBinding returnType; if (calloutBindingDeclaration.roleMethodSpec.returnType != null) // if this one is given, it might be instantiated: returnType = calloutBindingDeclaration.roleMethodSpec.returnType.resolvedType; else // this one should exist in any case: returnType = calloutBindingDeclaration.roleMethodSpec.resolvedMethod.returnType; MethodDeclaration newMethod = gen.method(calloutBindingDeclaration.compilationResult, modifiers, // start from these, adapt below. returnType, templateBinding.selector, copyArguments(gen, calloutBindingDeclaration.scope, templateBinding.parameters, calloutBindingDeclaration.roleMethodSpec)); newMethod.typeParameters = getTypeParameters(calloutBindingDeclaration.hasSignature, templateBinding, calloutBindingDeclaration.roleMethodSpec, gen); if (templateBinding.problemId() == ProblemReasons.NotFound) { // this is a short hand callout declaration: MethodSpec baseMethodSpec = calloutBindingDeclaration.baseMethodSpec; if (baseMethodSpec != null) { // null if missing in source code (e.g. during completion) if (baseMethodSpec.isStatic()) newMethod.modifiers |= AccStatic; if (baseMethodSpec.resolvedMethod != null) { newMethod.thrownExceptions = AstClone.copyExceptions(baseMethodSpec.resolvedMethod, gen); } } } else { newMethod.thrownExceptions = AstClone.copyExceptions(templateBinding, gen); } newMethod.isMappingWrapper = WrapperKind.CALLOUT; if (part == INTERFACE) { // generated callout method must also be added to the interface-part since // role-splitting already happened // Note: Interface part has the access modifiers! newMethod.modifiers |= ExtraCompilerModifiers.AccSemicolonBody | AccAbstract; AstEdit.addMethod(this._role.getInterfaceAst(), newMethod); } else // == CLASS { if ((modifiers & AccPrivate) != 0) { // don't advertize in ifc // FIXME(SH): need to generate bridge methdods? } else if (calloutBindingDeclaration.binding.inferred.isAdvertisedInInterface()) { // only if actually advertised in the ifc-part // generated callout method must be public in the classPart. // access control is done only via the interface part. MethodModel.getModel(newMethod).storeModifiers(newMethod.modifiers); newMethod.modifiers &= ~(AccProtected); newMethod.modifiers |= AccPublic; } // abstract will be cleared once we are done. AstEdit.addMethod(this._role.getAst(), newMethod); } calloutBindingDeclaration.updateRoleMethod(newMethod.binding); return newMethod; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.MethodMappingResolver.java
License:Open Source License
/** * Resolve everything about a callin binding except for argument mappings if present. * Reports as many errors as can be found. * @return true if no error occurred/* w w w . ja v a 2 s. c om*/ */ private boolean resolveCalloutMapping(CalloutMappingDeclaration calloutMappingDeclaration) { if (calloutMappingDeclaration.scope == null) { // severe error assert calloutMappingDeclaration.hasErrors(); return false; } // main resolving task: // A callout-with-signatures should always resolve its base method, // because that base method could determine the static flag. calloutMappingDeclaration.resolveMethodSpecs(this._role, this._role.getBaseTypeBinding(), this.resolveBaseMethods || calloutMappingDeclaration.hasSignature); // This binding is part of the interface part of a role: MethodBinding roleMethodBinding = calloutMappingDeclaration.roleMethodSpec.resolvedMethod; calloutMappingDeclaration.binding._roleMethodBinding = roleMethodBinding; if (this.resolveBaseMethods) { MethodSpec baseMethodSpec = calloutMappingDeclaration.baseMethodSpec; if (baseMethodSpec != null) { if (baseMethodSpec.resolvedMethod != null) { calloutMappingDeclaration.binding._baseMethods = new MethodBinding[] { baseMethodSpec.resolvedMethod }; } else if (baseMethodSpec instanceof FieldAccessSpec && ((FieldAccessSpec) baseMethodSpec).resolvedField != null) { calloutMappingDeclaration.binding._baseField = ((FieldAccessSpec) baseMethodSpec).resolvedField; } else { calloutMappingDeclaration.binding._baseMethods = Binding.NO_METHODS; calloutMappingDeclaration.tagAsHavingErrors(); } } } if (roleMethodBinding != null && (roleMethodBinding.isValidBinding() || (roleMethodBinding.problemId() == ProblemReasons.NotFound && calloutMappingDeclaration.hasSignature))) // short-hand, method will be generated { // store the methodMapping in a map indexed by the role method's name&signature // for later duplication check. String methodKey = String .valueOf(CharOperation.concat(roleMethodBinding.selector, roleMethodBinding.signature())); List<CalloutMappingDeclaration> mappings = this._foundRoleMethods.get(methodKey); if (mappings == null) { mappings = new LinkedList<CalloutMappingDeclaration>(); this._foundRoleMethods.put(methodKey, mappings); } mappings.add(calloutMappingDeclaration); } return !calloutMappingDeclaration.hasErrors(); }