Example usage for org.eclipse.jdt.internal.compiler.lookup MethodBinding isAbstract

List of usage examples for org.eclipse.jdt.internal.compiler.lookup MethodBinding isAbstract

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.lookup MethodBinding isAbstract.

Prototype

public final boolean isAbstract() 

Source Link

Usage

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;
}