List of usage examples for org.eclipse.jdt.internal.compiler.lookup MethodBinding isAbstract
public final boolean isAbstract()
From source file:lombok.eclipse.handlers.HandleVetoable.java
License:Apache License
@Override public void handle(final AnnotationValues<Vetoable> annotation, final Annotation source, final EclipseNode annotationNode) { new VetoableHandler<EclipseType, EclipseField, EclipseNode, ASTNode>(annotationNode, source) { @Override/*from w ww . j a va 2s.c o m*/ protected void addInterface(EclipseType type, String interfaceClassName) { EclipseUtil.addInterface(type.get(), interfaceClassName, source); } @Override protected EclipseType typeOf(EclipseNode node, ASTNode ast) { return EclipseType.typeOf(node, ast); } @Override protected EclipseField fieldOf(EclipseNode node, ASTNode ast) { return EclipseField.fieldOf(node, ast); } @Override protected boolean hasMethodIncludingSupertypes(EclipseType type, String methodName, TypeRef... argumentTypes) { return hasMethod(type.get().binding, methodName, type.editor().build(As.list(argumentTypes))); } private boolean hasMethod(final TypeBinding binding, final String methodName, List<ASTNode> argumentTypes) { if (binding instanceof ReferenceBinding) { ReferenceBinding rb = (ReferenceBinding) binding; MethodBinding[] availableMethods = rb.availableMethods(); for (MethodBinding method : Each.elementIn(availableMethods)) { if (method.isAbstract()) continue; /*if (!method.isPublic()) continue;*/ if (!methodName.equals(As.string(method.selector))) continue; if (argumentTypes.size() != As.list(method.parameters).size()) continue; // TODO check actual types.. return true; } ReferenceBinding superclass = rb.superclass(); ensureAllClassScopeMethodWereBuild(superclass); return hasMethod(superclass, methodName, argumentTypes); } return false; } @Override protected boolean isAnnotatedWith(EclipseType type, Class<? extends java.lang.annotation.Annotation> annotationClass) { Annotation[] annotations = type.get().annotations; if (annotations == null) return false; for (Annotation annotation : annotations) { if (annotation == null || annotation.type == null) continue; String annotationName = resolveAnnotationName(annotation.type.getTypeName()); if (annotationName.equals(annotationClass.getName())) return true; } return false; } @Override protected boolean isAnnotatedWith(final EclipseNode eclipseNode, final Class<? extends java.lang.annotation.Annotation> annotationClass) { final boolean[] result = new boolean[1]; result[0] = false; eclipseNode.traverse(new EclipseASTAdapter() { @Override public void visitAnnotationOnType(TypeDeclaration type, EclipseNode annotationNode, Annotation annotation) { Annotation[] annotations = type.annotations; if (annotations == null) { result[0] = false; } else { for (Annotation a : annotations) { if (a == null || a.type == null) continue; String annotationName = resolveAnnotationName(a.type.getTypeName()); if (annotationName.equals(annotationClass.getName())) { result[0] = true; break; } } } } }); return result[0]; } private String resolveAnnotationName(char[][] typeName) { StringBuilder b = new StringBuilder(); for (int i = 0; i < typeName.length; i++) { b.append(new String(typeName[i])); if (i < typeName.length - 1) b.append("."); } return b.toString(); } }.handle(); }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
public MethodBinding findExactMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { CompilationUnitScope unitScope = compilationUnitScope(); unitScope.recordTypeReferences(argumentTypes); MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, unitScope); if (exactMethod != null && exactMethod.typeVariables == Binding.NO_TYPE_VARIABLES && !exactMethod.isBridge()) { // in >= 1.5 mode, ensure the exactMatch did not match raw types if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) for (int i = argumentTypes.length; --i >= 0;) if (isPossibleSubtypeOfRawType(argumentTypes[i])) return null; // must find both methods for this case: <S extends A> void foo() {} and <N extends B> N foo() { return null; } // or find an inherited method when the exact match is to a bridge method unitScope.recordTypeReferences(exactMethod.thrownExceptions); if (exactMethod.isAbstract() && exactMethod.thrownExceptions != Binding.NO_EXCEPTIONS) return null; // may need to merge exceptions with interface method // special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type) if (receiverType.isInterface() || exactMethod.canBeSeenBy(receiverType, invocationSite, this)) { if (argumentTypes == Binding.NO_PARAMETERS && CharOperation.equals(selector, TypeConstants.GETCLASS) && exactMethod.returnType.isParameterizedType()/*1.5*/) { return environment().createGetClassMethod(receiverType, exactMethod, this); }/*from ww w . j a v a 2 s . c om*/ // targeting a generic method could find an exact match with variable return type if (invocationSite.genericTypeArguments() != null) { exactMethod = computeCompatibleMethod(exactMethod, argumentTypes, invocationSite); } return exactMethod; } } return null; }
From source file:org.eclipse.jdt.internal.compiler.lookup.Scope.java
License:Open Source License
protected final MethodBinding mostSpecificMethodBinding(MethodBinding[] visible, int visibleSize, TypeBinding[] argumentTypes, final InvocationSite invocationSite, ReferenceBinding receiverType) { int[] compatibilityLevels = new int[visibleSize]; for (int i = 0; i < visibleSize; i++) compatibilityLevels[i] = parameterCompatibilityLevel(visible[i], argumentTypes); InvocationSite tieBreakInvocationSite = new InvocationSite() { public TypeBinding[] genericTypeArguments() { return null; } // ignore genericTypeArgs public boolean isSuperAccess() { return invocationSite.isSuperAccess(); }//from w ww. j av a 2 s. co m public boolean isTypeAccess() { return invocationSite.isTypeAccess(); } public void setActualReceiverType(ReferenceBinding actualReceiverType) { /* ignore */} public void setDepth(int depth) { /* ignore */} public void setFieldIndex(int depth) { /* ignore */} public int sourceStart() { return invocationSite.sourceStart(); } public int sourceEnd() { return invocationSite.sourceStart(); } public TypeBinding expectedType() { return invocationSite.expectedType(); } }; MethodBinding[] moreSpecific = new MethodBinding[visibleSize]; int count = 0; for (int level = 0, max = VARARGS_COMPATIBLE; level <= max; level++) { nextVisible: for (int i = 0; i < visibleSize; i++) { if (compatibilityLevels[i] != level) continue nextVisible; max = level; // do not examine further categories, will either return mostSpecific or report ambiguous case MethodBinding current = visible[i]; MethodBinding original = current.original(); MethodBinding tiebreakMethod = current.tiebreakMethod(); for (int j = 0; j < visibleSize; j++) { if (i == j || compatibilityLevels[j] != level) continue; MethodBinding next = visible[j]; if (original == next.original()) { // parameterized superclasses & interfaces may be walked twice from different paths so skip next from now on compatibilityLevels[j] = -1; continue; } MethodBinding methodToTest = next; if (next instanceof ParameterizedGenericMethodBinding) { ParameterizedGenericMethodBinding pNext = (ParameterizedGenericMethodBinding) next; if (pNext.isRaw && !pNext.isStatic()) { // hold onto the raw substituted method } else { methodToTest = pNext.originalMethod; } } MethodBinding acceptable = computeCompatibleMethod(methodToTest, tiebreakMethod.parameters, tieBreakInvocationSite); /* There are 4 choices to consider with current & next : foo(B) & foo(A) where B extends A 1. the 2 methods are equal (both accept each others parameters) -> want to continue 2. current has more specific parameters than next (so acceptable is a valid method) -> want to continue 3. current has less specific parameters than next (so acceptable is null) -> go on to next 4. current and next are not compatible with each other (so acceptable is null) -> go on to next */ if (acceptable == null || !acceptable.isValidBinding()) continue nextVisible; if (!isAcceptableMethod(tiebreakMethod, acceptable)) continue nextVisible; // pick a concrete method over a bridge method when parameters are equal since the return type of the concrete method is more specific if (current.isBridge() && !next.isBridge()) if (tiebreakMethod.areParametersEqual(acceptable)) continue nextVisible; // skip current so acceptable wins over this bridge method } moreSpecific[i] = current; count++; } } if (count == 1) { for (int i = 0; i < visibleSize; i++) { if (moreSpecific[i] != null) { compilationUnitScope().recordTypeReferences(visible[i].thrownExceptions); return visible[i]; } } } else if (count == 0) { return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous); } // found several methods that are mutually acceptable -> must be equal // so now with the first acceptable method, find the 'correct' inherited method for each other acceptable method AND // see if they are equal after substitution of type variables (do the type variables have to be equal to be considered an override???) if (receiverType != null) receiverType = receiverType instanceof CaptureBinding ? receiverType : (ReferenceBinding) receiverType.erasure(); nextSpecific: for (int i = 0; i < visibleSize; i++) { MethodBinding current = moreSpecific[i]; if (current != null) { ReferenceBinding[] mostSpecificExceptions = null; MethodBinding original = current.original(); boolean shouldIntersectExceptions = original.declaringClass.isAbstract() && original.thrownExceptions != Binding.NO_EXCEPTIONS; // only needed when selecting from interface methods for (int j = 0; j < visibleSize; j++) { MethodBinding next = moreSpecific[j]; if (next == null || i == j) continue; MethodBinding original2 = next.original(); if (original.declaringClass == original2.declaringClass) break nextSpecific; // duplicates thru substitution if (!original.isAbstract()) { if (original2.isAbstract()) continue; // only compare current against other concrete methods original2 = original.findOriginalInheritedMethod(original2); if (original2 == null) continue nextSpecific; // current's declaringClass is not a subtype of next's declaringClass if (current.hasSubstitutedParameters() || original.typeVariables != Binding.NO_TYPE_VARIABLES) { if (!environment().methodVerifier().isParameterSubsignature(original, original2)) continue nextSpecific; // current does not override next } } else if (receiverType != null) { // should not be null if original isAbstract, but be safe TypeBinding superType = receiverType .findSuperTypeOriginatingFrom(original.declaringClass.erasure()); if (original.declaringClass == superType || !(superType instanceof ReferenceBinding)) { // keep original } else { // must find inherited method with the same substituted variables MethodBinding[] superMethods = ((ReferenceBinding) superType) .getMethods(original.selector, argumentTypes.length); for (int m = 0, l = superMethods.length; m < l; m++) { if (superMethods[m].original() == original) { original = superMethods[m]; break; } } } superType = receiverType.findSuperTypeOriginatingFrom(original2.declaringClass.erasure()); if (original2.declaringClass == superType || !(superType instanceof ReferenceBinding)) { // keep original2 } else { // must find inherited method with the same substituted variables MethodBinding[] superMethods = ((ReferenceBinding) superType) .getMethods(original2.selector, argumentTypes.length); for (int m = 0, l = superMethods.length; m < l; m++) { if (superMethods[m].original() == original2) { original2 = superMethods[m]; break; } } } if (original.typeVariables != Binding.NO_TYPE_VARIABLES) original2 = original.computeSubstitutedMethod(original2, environment()); if (original2 == null || !original.areParameterErasuresEqual(original2)) continue nextSpecific; // current does not override next if (original.returnType != original2.returnType) { if (next.original().typeVariables != Binding.NO_TYPE_VARIABLES) { if (original.returnType.erasure() .findSuperTypeOriginatingFrom(original2.returnType.erasure()) == null) continue nextSpecific; } else if (!current.returnType.isCompatibleWith(next.returnType)) { continue nextSpecific; } // continue with original 15.12.2.5 } if (shouldIntersectExceptions && original2.declaringClass.isInterface()) { if (current.thrownExceptions != next.thrownExceptions) { if (next.thrownExceptions == Binding.NO_EXCEPTIONS) { mostSpecificExceptions = Binding.NO_EXCEPTIONS; } else { if (mostSpecificExceptions == null) { mostSpecificExceptions = current.thrownExceptions; } int mostSpecificLength = mostSpecificExceptions.length; int nextLength = next.thrownExceptions.length; SimpleSet temp = new SimpleSet(mostSpecificLength); boolean changed = false; nextException: for (int t = 0; t < mostSpecificLength; t++) { ReferenceBinding exception = mostSpecificExceptions[t]; for (int s = 0; s < nextLength; s++) { ReferenceBinding nextException = next.thrownExceptions[s]; if (exception.isCompatibleWith(nextException)) { temp.add(exception); continue nextException; } else if (nextException.isCompatibleWith(exception)) { temp.add(nextException); changed = true; continue nextException; } else { changed = true; } } } if (changed) { mostSpecificExceptions = temp.elementSize == 0 ? Binding.NO_EXCEPTIONS : new ReferenceBinding[temp.elementSize]; temp.asArray(mostSpecificExceptions); } } } } } } if (mostSpecificExceptions != null && mostSpecificExceptions != current.thrownExceptions) { return new MostSpecificExceptionMethodBinding(current, mostSpecificExceptions); } return current; } } // if all moreSpecific methods are equal then see if duplicates exist because of substitution return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous); }
From source file:org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.java
License:Open Source License
public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) { if (this.scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_5) { return null; }/*from w w w . j a v a 2s.co m*/ if (isInterface()) return null; if (inheritedMethodToBridge.isAbstract() || inheritedMethodToBridge.isFinal() || inheritedMethodToBridge.isStatic()) { return null; } if (this.synthetics == null) this.synthetics = new HashMap[MAX_SYNTHETICS]; if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) { this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5); } else { // check to see if there is another equivalent inheritedMethod already added Iterator synthMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator(); while (synthMethods.hasNext()) { Object synthetic = synthMethods.next(); if (synthetic instanceof MethodBinding) { MethodBinding method = (MethodBinding) synthetic; if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector) && inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure() && inheritedMethodToBridge.areParameterErasuresEqual(method)) { return null; } } } } SyntheticMethodBinding accessMethod = null; SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL] .get(inheritedMethodToBridge); if (accessors == null) { accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, this); this.synthetics[SourceTypeBinding.METHOD_EMUL].put(inheritedMethodToBridge, accessors = new SyntheticMethodBinding[2]); accessors[0] = accessMethod; } else { if ((accessMethod = accessors[0]) == null) { accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, this); accessors[0] = accessMethod; } } return accessMethod; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration.java
License:Open Source License
@Override protected void checkModifiers(boolean haveBaseMethods, ReferenceBinding baseType) { boolean roleHasImplementation = false; MethodBinding roleMethod = this.roleMethodSpec.resolvedMethod; if (!roleMethod.isValidBinding()) return;// w w w . j a va 2s.c o m // update modifiers after tsuper has generated callout methods (perhaps giving implementation to abstract decl) if (roleMethod.isAbstract() && roleMethod.copyInheritanceSrc != null && !roleMethod.copyInheritanceSrc.isAbstract()) roleMethod.modifiers &= ~ClassFileConstants.AccAbstract; roleHasImplementation = !roleMethod.isAbstract() && !roleMethod.isDefaultMethod(); if (roleHasImplementation != isCalloutOverride()) { if (roleHasImplementation) { if (isCalloutMethod(roleMethod)) { if (TypeBinding.notEquals(roleMethod.declaringClass, this.scope.enclosingSourceType()) || roleMethod.copyInheritanceSrc != null) // "local" callouts (not copied) are treated in { // MethodMappingResolver.checkForDuplicateMethodMappings() this.scope.problemReporter().regularCalloutOverridesCallout(this, roleMethod); } } else { this.scope.problemReporter().regularCalloutOverrides(this); } } else // isCalloutOverride() but not really overriding { this.scope.problemReporter().abstractMethodBoundAsOverrideCallout(this); AbstractMethodDeclaration roleMethodDeclaration = roleMethod.sourceMethod(); if (roleMethodDeclaration != null) { roleMethodDeclaration.ignoreFurtherInvestigation = true; this.ignoreFurtherInvestigation = true; } } } if (roleMethod.isCallin()) { this.scope.problemReporter().calloutBindingCallin(this.roleMethodSpec); } if (hasErrors()) { // unsuccessful attempt to implement role method as callout, // mark the method as erroneous: if (this.roleMethodSpec.resolvedMethod != null && this.roleMethodSpec.resolvedMethod.isAbstract()) { AbstractMethodDeclaration methodDecl = this.roleMethodSpec.resolvedMethod.sourceMethod(); if (methodDecl != null) methodDecl.tagAsHavingErrors(); // prevent abstract-error } } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel.java
License:Open Source License
/** An interface method is always abstract, consult the class method, * if present to query staticness. */ public static boolean isAbstract(MethodBinding binding) { if (binding.declaringClass.isSynthInterface()) binding = getClassPartMethod(binding); if (binding == null) return true; // ifc method w/o a class part return binding.isAbstract(); }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance.java
License:Open Source License
/** * Copy a given method to the tsub-role. * Adds the new method to AST and performs initial creation of bindings. * @param method method to copy/*from w ww .j a va2 s. c o m*/ * @param targetRoleDecl target role class */ private static void copyMethod(MethodBinding method, TypeDeclaration targetRoleDecl) { boolean wasSynthetic = false; ReferenceBinding site = null; if ((method.modifiers & AccSynthetic) != 0) { wasSynthetic = true; // some, but not all, synthetics shall be generated with strong signatures as indicated by 'site': if (!SyntheticBaseCallSurrogate.isBaseCallSurrogateName(method.selector)) site = targetRoleDecl.binding; if (SyntheticRoleBridgeMethodBinding.isPrivateBridgeSelector(method.selector)) return; // will be generated anew } if (TypeContainerMethod.isTypeContainer(method)) return; // don't copy these dummy methods if (isCreator(method) || CharOperation.equals(IOTConstants._OT_GETBASE, method.selector) || CharOperation.prefixEquals(IOTConstants.CAST_PREFIX, method.selector) || CharOperation.prefixEquals(IOTConstants.GET_CLASS_PREFIX, method.selector)) return; // create/getBase/cast/getClass-methods are generated anew in each team. // (can only happen in a team that is a role of an outer team.) // Note: we don't use AccSynthetic on creators, because // Synthetic methods are not read from byte code. // FIXME(SH): this last note is not true any more. if (targetRoleDecl.isTeam() && (ReflectionGenerator.isReflectionMethod(method) || SerializationGenerator.isSerializationMethod(method))) return; if (MethodModel.isFakedMethod(method)) return; // will be generated anew (basecall-surrogate, rolefield-bridge) if (CharOperation.equals(IOTConstants.MIGRATE_TO_TEAM, method.selector)) return; // can only be used from the exact team // avoid copying twice (see copyGeneratedFeatures()): targetRoleDecl.getRoleModel().recordCopiedFeature(method); // some useful objects: ReferenceBinding srcRole = method.declaringClass; TypeDeclaration targetTeamDecl = targetRoleDecl.enclosingType; ReferenceBinding srcTeam = TeamModel.getEnclosingTeam(srcRole); ReferenceBinding tgtTeam = targetTeamDecl.binding; MethodBinding origin = (method.copyInheritanceSrc != null) ? method.copyInheritanceSrc : method; AbstractMethodDeclaration methodFound = findMethod(srcTeam, method, tgtTeam, targetRoleDecl); if (method.isConstructor()) { if (CharOperation.equals(srcRole.compoundName, IOTConstants.ORG_OBJECTTEAMS_TEAM_OTCONFINED)) { // must add default constructor explicitly, // since if we would copy the one from Team.__OT__Confined, // it would invoke the wrong super(). ConstructorDeclaration ctor = targetRoleDecl.createDefaultConstructor(true, true); targetRoleDecl.binding.resolveGeneratedMethod(ctor, false, origin); return; } else if (targetRoleDecl.getRoleModel()._refinesExtends) { // even if we can't copy the ctor, we need to mark // the current ctor as overriding the tsuper version. if (methodFound != null) methodFound.binding.addOverriddenTSuper(method); return; // extends is covariantly redefined, don't copy ctor! // attempts to invoke this tsuper ctor are caught in ExplicitConstructorCall.resolve(). } } // If method already exists in subteam, // + adjust method in subteam to the more general signature (here) // + extend copy with marker arg (below). // else give an exact copy. boolean reuseFoundMethod = false; if (methodFound != null) { // do not touch broken methods: // (methodFound might have no binding, // e.g., due to a missing import of return-type) if (methodFound.binding == null) return; if (methodFound.binding.copyInheritanceSrc == origin) return; // diamond inheritance: copying the same method from two different sources // tsuper method trumps previously inferred callout: if (methodFound.isMappingWrapper == WrapperKind.CALLOUT) { MethodModel model = methodFound.model; if (model != null && model._inferredCallout != null) { // reset callout related stuff: methodFound.isMappingWrapper = WrapperKind.NONE; model._inferredCallout = null; methodFound.statements = null; // setup as a copied method: methodFound.isCopied = true; methodFound.binding.copyInheritanceSrc = method; methodFound.sourceMethodBinding = method; reuseFoundMethod = true; } } // do this in any case so that ConstantPoolObjectMapper won't fail: methodFound.binding.addOverriddenTSuper(method); // abstract methods have no byte code to copy; // new method silently replaces abstract version: if (method.isAbstract()) { weakenSignature(methodFound, method); return; } if (method.isFinal()) { methodFound.scope.problemReporter().finalMethodCannotBeOverridden(methodFound.binding, method); return; } weakenSignature(methodFound, method); MethodBinding foundSrc = methodFound.binding.copyInheritanceSrc; if (foundSrc != null && foundSrc != origin) { // found a copied method which has a different origin, choose the more specific: // if incommensurable prefer the new copy (assuming it comes from *implicit* super team) if (!TeamModel.isMoreSpecificThan(foundSrc.declaringClass, origin.declaringClass)) { // more specific method overwrites previous linkage: methodFound.binding.setCopyInheritanceSrc(origin); methodFound.sourceMethodBinding = origin; methodFound.isTSuper = TSuperHelper.isTSuper(method); // TODO(SH): also update CopyInheritanceSrc-Attribute! if (!method.isAbstract()) { // not abstract any more, joining abstract and implemented methods: methodFound.modifiers &= ~(AccAbstract | AccSemicolonBody); methodFound.binding.modifiers &= ~(AccAbstract | AccSemicolonBody); // TODO(SH): might need multiple copyInheritanceSrc! // TODO(SH) need to adjust copiedInContext? } } return; } } AstGenerator gen = new AstGenerator(targetRoleDecl.sourceStart, targetRoleDecl.sourceEnd); gen.replaceableEnclosingClass = tgtTeam; final AbstractMethodDeclaration newMethodDecl; if (methodFound != null && reuseFoundMethod) { newMethodDecl = methodFound; } else { newMethodDecl = AstConverter.createMethod(method, site, targetRoleDecl.compilationResult, DecapsulationState.REPORTED, gen); if (methodFound != null) TSuperHelper.addMarkerArg(newMethodDecl, srcTeam); if (newMethodDecl.isConstructor()) { // comments (SH): // other phases may depend on this field (constructorCall) being set, // although it carries no real information. ConstructorDeclaration cd = (ConstructorDeclaration) newMethodDecl; cd.constructorCall = SuperReference.implicitSuperConstructorCall(); if (Lifting.isLiftingCtor(method) && method.parameters[0].isRole()) { // if baseclass is implicitely redefined use the strong type: ReferenceBinding newBase = targetRoleDecl.binding.baseclass(); if (TypeBinding.notEquals(newBase, method.parameters[0])) newMethodDecl.arguments[0].type = gen.baseclassReference(newBase); } } AstEdit.addMethod(targetRoleDecl, newMethodDecl, wasSynthetic, false/*addToFront*/, origin); } if (method.isPrivate()) { newMethodDecl.binding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed; // don't warn unused copied method } newMethodDecl.binding.copiedInContext = tgtTeam.enclosingType(); MethodModel newModel = MethodModel.getModel(newMethodDecl); newModel.addAttribute(CopyInheritanceSourceAttribute.copyInherSrcAttribute(origin, newModel)); if (wasSynthetic) targetRoleDecl.getRoleModel().addSyntheticMethodMapping(method, newMethodDecl.binding); if (method.isAnyCallin() && !method.isCallin()) // callin wrapper newMethodDecl.isMappingWrapper = WrapperKind.CALLIN; if (methodFound == null) { // copy down some more properties: if (TSuperHelper.isTSuper(method)) newMethodDecl.isTSuper = true; if (method.model != null && method.model.callinFlags != 0) MethodModel.addCallinFlag(newMethodDecl, method.model.callinFlags); if (method.isAnyCallin()) { TypeBinding inheritedSrcReturn = MethodModel.getReturnType(method); if (inheritedSrcReturn.isRole()) inheritedSrcReturn = RoleTypeCreator.maybeWrapUnqualifiedRoleType(inheritedSrcReturn, targetRoleDecl.binding); MethodModel.saveReturnType(newMethodDecl.binding, inheritedSrcReturn); } else { if (!method.isPublic() // non-public source-level class method? && !method.isConstructor() && !targetRoleDecl.isInterface() && !CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, method.selector)) { MethodModel.getModel(newMethodDecl).storeModifiers(newMethodDecl.modifiers); } } // more checking: abstract method in non-abstract class? if (newMethodDecl.isAbstract() && (targetRoleDecl.modifiers & ClassFileConstants.AccAbstract) == 0) { targetRoleDecl.scope.problemReporter().setRechecker(new IProblemRechecker() { public boolean shouldBeReported(IrritantSet[] foundIrritants) { if (newMethodDecl.isAbstract()) // implemented by callout? return true; return false; // false alarm } }).abstractMethodMustBeImplemented(targetRoleDecl.binding, newMethodDecl.binding); } } }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.StandardElementGenerator.java
License:Open Source License
/** * For each role (bound or unbound) generate * public org.objectteams.Team _OT$getTeam() * If roleType is an interface generate the abstract interface method. * * @param roleType the role to operate on * @return the binding of the created method or null *//*from w w w .ja va2 s . com*/ public static @Nullable MethodBinding createGetTeamMethod(TypeDeclaration roleType) { MethodBinding existingMethod = TypeAnalyzer.findMethod(roleType.initializerScope, roleType.binding, _OT_GETTEAM, Binding.NO_PARAMETERS); if (existingMethod != null && existingMethod.isValidBinding()) { // is already covered by inheritance (copy or extends) if (roleType.isInterface() == existingMethod.isAbstract()) return null; } AstGenerator gen = roleType.baseclass != null ? new AstGenerator(roleType.baseclass.sourceStart, roleType.baseclass.sourceEnd) : new AstGenerator(roleType.sourceStart, roleType.sourceEnd); ReferenceBinding teamType = null; LookupEnvironment environment = roleType.scope.environment(); try { environment.missingClassFileLocation = roleType; teamType = roleType.scope.getOrgObjectteamsITeam(); } finally { environment.missingClassFileLocation = null; } int flags = AccPublic; if (roleType.isInterface()) flags |= AccAbstract | AccSemicolonBody; MethodDeclaration getTeam = gen.method(roleType.compilationResult, flags, teamType, _OT_GETTEAM, null); AstEdit.addMethod(roleType, getTeam); if ((flags & AccSemicolonBody) == 0) { int depth = roleType.binding.depth() - 1; getTeam.setStatements(new Statement[] { gen.returnStatement( gen.fieldReference(gen.thisReference(), (OUTER_THIS_PREFIX + depth).toCharArray())) }); if (StateMemento.hasMethodResolveStarted(roleType.binding)) getTeam.resolveStatements(); } return getTeam.binding; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.StandardElementGenerator.java
License:Open Source License
/** * @return either a newly created method or a valid, existing one. *///from w w w .jav a2 s . c o m private static MethodBinding createGetBaseMethod(TypeDeclaration roleType, ReferenceBinding baseType, char[] methodName, int flags) { if (roleType == null) return null; // sanity check, null can be caused by binary ifc-part in a source role. MethodBinding existingMethod = null; AbstractMethodDeclaration decl = TypeAnalyzer.findMethodDecl(roleType, methodName, 0); if (decl != null) existingMethod = decl.binding; if (existingMethod == null) existingMethod = TypeAnalyzer.findMethod(roleType.initializerScope, roleType.binding.superclass(), methodName, Binding.NO_PARAMETERS); if (existingMethod != null && existingMethod.isValidBinding()) { // valid method exists if (existingMethod.isAbstract() == roleType.isInterface()) // abstractness is correct if (TypeBinding.equalsEquals(existingMethod.declaringClass, roleType.binding)// declared here || existingMethod.returnType.isCompatibleWith(baseType)) // inherited but compatible return existingMethod; } AstGenerator gen = roleType.baseclass != null ? new AstGenerator(roleType.baseclass.sourceStart, roleType.baseclass.sourceEnd) : new AstGenerator(roleType.sourceStart, roleType.sourceEnd); gen.replaceableEnclosingClass = roleType.binding.enclosingType(); TypeReference baseclassReference; // must set in if or else TypeParameter methodParam = null; Statement bodyStatement; // must set in if or else if (baseType != null) { baseclassReference = gen.baseclassReference(baseType); bodyStatement = gen.returnStatement(gen.castExpression(gen.singleNameReference(_OT_BASE), baseclassReference, CastExpression.DO_WRAP)); } else { // this role is not bound but create a generic getBase method for use via a <B base R> type: final char[] paramName = "_OT$AnyBase".toCharArray(); //$NON-NLS-1$ used only for this one declaration. methodParam = gen.baseBoundedTypeParameter(paramName, roleType.binding); baseclassReference = gen.singleTypeReference(paramName); final char[][] ABSTRACT_METHOD = new char[][] { "java".toCharArray(), //$NON-NLS-1$ "lang".toCharArray(), //$NON-NLS-1$ "AbstractMethodError".toCharArray() }; //$NON-NLS-1$ bodyStatement = gen.throwStatement(gen.allocation(gen.qualifiedTypeReference(ABSTRACT_METHOD), null)); } MethodDeclaration getBase = gen.method(roleType.compilationResult, flags, baseclassReference, methodName, null); if (methodParam != null) getBase.typeParameters = new TypeParameter[] { methodParam }; AstEdit.addMethod(roleType, getBase); for (ReferenceBinding tsuperRole : roleType.getRoleModel().getTSuperRoleBindings()) { for (MethodBinding tsuperMethod : tsuperRole.getMethods(_OT_GETBASE)) getBase.binding.addOverriddenTSuper(tsuperMethod); } if (methodParam != null) roleType.getRoleModel().unimplementedGetBase = getBase.binding; if ((flags & AccSemicolonBody) == 0) { getBase.setStatements(new Statement[] { bodyStatement }); if (StateMemento.hasMethodResolveStarted(roleType.binding)) getBase.resolveStatements(); } return getBase.binding; }
From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.AstConverter.java
License:Open Source License
public static AbstractMethodDeclaration createMethod(MethodBinding methodBinding, ReferenceBinding site, CompilationResult compilationResult, DecapsulationState decapsulation, AstGenerator gen) { if (methodBinding == null) return null; AbstractMethodDeclaration abstractMethodDeclaration; if (CharOperation.equals(methodBinding.selector, TypeConstants.INIT)) { ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration(compilationResult); constructorDeclaration.selector = site != null ? site.sourceName : methodBinding.declaringClass.sourceName; abstractMethodDeclaration = constructorDeclaration; } else {/* ww w. j ava2 s . c om*/ MethodDeclaration methodDeclaration = new MethodDeclaration(compilationResult); // on these special methods see class header comment in CopyInheritance: if (CharOperation.prefixEquals(IOTConstants.CAST_PREFIX, methodBinding.selector) || CharOperation.prefixEquals(IOTConstants._OT_LIFT_TO, methodBinding.selector)) methodDeclaration.returnType = new SingleTypeReference(methodBinding.returnType.internalName(), 0); else methodDeclaration.returnType = gen.typeReference(methodBinding.returnType); methodDeclaration.returnType.setBaseclassDecapsulation(decapsulation); methodDeclaration.selector = methodBinding.selector; TypeVariableBinding[] typeVariables = methodBinding.typeVariables(); if (typeVariables != Binding.NO_TYPE_VARIABLES) { TypeParameter[] parameters = new TypeParameter[typeVariables.length]; for (int i = 0; i < typeVariables.length; i++) parameters[i] = gen.typeParameter(typeVariables[i]); methodDeclaration.typeParameters = parameters; } abstractMethodDeclaration = methodDeclaration; } gen.setMethodPositions(abstractMethodDeclaration); abstractMethodDeclaration.modifiers = methodBinding.modifiers & ~ClassFileConstants.AccSynthetic; if (methodBinding.isAbstract()) // AccSemicolonBody - flag does not exist in binary methods: abstractMethodDeclaration.modifiers |= AccSemicolonBody; abstractMethodDeclaration.arguments = createArguments(methodBinding.parameters, site, decapsulation, gen); abstractMethodDeclaration.isCopied = true; abstractMethodDeclaration.sourceMethodBinding = methodBinding; abstractMethodDeclaration.thrownExceptions = AstClone.copyExceptions(methodBinding, gen); return abstractMethodDeclaration; }