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

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

Introduction

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

Prototype

public final boolean isFinal() 

Source Link

Usage

From source file:com.google.gwt.dev.javac.Shared.java

License:Open Source License

public static int bindingToModifierBits(MethodBinding binding) {
    int bits = 0;
    bits |= (binding.isPublic() ? MOD_PUBLIC : 0);
    bits |= (binding.isPrivate() ? MOD_PRIVATE : 0);
    bits |= (binding.isProtected() ? MOD_PROTECTED : 0);
    bits |= (binding.isStatic() ? MOD_STATIC : 0);
    bits |= (binding.isFinal() ? MOD_FINAL : 0);
    bits |= (binding.isNative() ? MOD_NATIVE : 0);
    bits |= (binding.isAbstract() ? MOD_ABSTRACT : 0);
    return bits;//from  www. j a va 2s  .  co  m
}

From source file:com.google.gwt.dev.jjs.impl.BuildTypeMap.java

License:Apache License

private JMethod processMethodBinding(MethodBinding b, JDeclaredType enclosingType, SourceInfo info) {
    JType returnType = getType(b.returnType);
    JMethod newMethod = program.createMethod(info, String.valueOf(b.selector), enclosingType, returnType,
            b.isAbstract(), b.isStatic(), b.isFinal(), AccessModifier.fromMethodBinding(b), b.isNative());
    addThrownExceptions(b, newMethod);/*from  w w w. j a  va  2 s.c o m*/
    if (b.isSynthetic()) {
        newMethod.setSynthetic();
    }

    if (enclosingType.isExternal()) {
        newMethod.setBody(null);
    }
    typeMap.put(b, newMethod);
    return newMethod;
}

From source file:com.google.gwt.dev.jjs.impl.GwtAstBuilder.java

License:Apache License

private void createMethod(AbstractMethodDeclaration x) {
    if (x instanceof Clinit) {
        return;//ww w .ja v a 2 s .  co  m
    }
    SourceInfo info = makeSourceInfo(x);
    MethodBinding b = x.binding;
    ReferenceBinding declaringClass = (ReferenceBinding) b.declaringClass.erasure();
    Set<String> alreadyNamedVariables = Sets.newHashSet();
    JDeclaredType enclosingType = (JDeclaredType) typeMap.get(declaringClass);
    assert !enclosingType.isExternal();
    JMethod method;
    boolean isNested = JdtUtil.isInnerClass(declaringClass);
    if (x.isConstructor()) {
        method = new JConstructor(info, (JClassType) enclosingType);
        if (x.isDefaultConstructor()) {
            ((JConstructor) method).setDefaultConstructor();
        }
        if (x.binding.declaringClass.isEnum()) {
            // Enums have hidden arguments for name and value
            method.addParam(new JParameter(info, "enum$name", typeMap.get(x.scope.getJavaLangString()), true,
                    false, method));
            method.addParam(new JParameter(info, "enum$ordinal", JPrimitiveType.INT, true, false, method));
        }
        // add synthetic args for outer this
        if (isNested) {
            NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
            if (nestedBinding.enclosingInstances != null) {
                for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
                    SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
                    String argName = String.valueOf(arg.name);
                    if (alreadyNamedVariables.contains(argName)) {
                        argName += "_" + i;
                    }
                    createParameter(info, arg, argName, method);
                    alreadyNamedVariables.add(argName);
                }
            }
        }
    } else {
        method = new JMethod(info, intern(b.selector), enclosingType, typeMap.get(b.returnType), b.isAbstract(),
                b.isStatic(), b.isFinal(), AccessModifier.fromMethodBinding(b));
    }

    // User args.
    createParameters(method, x);

    if (x.isConstructor()) {
        if (isNested) {
            // add synthetic args for locals
            NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
            // add synthetic args for outer this and locals
            if (nestedBinding.outerLocalVariables != null) {
                for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
                    SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
                    String argName = String.valueOf(arg.name);
                    if (alreadyNamedVariables.contains(argName)) {
                        argName += "_" + i;
                    }
                    createParameter(info, arg, argName, method);
                    alreadyNamedVariables.add(argName);
                }
            }
        }
    }

    mapExceptions(method, b);

    if (b.isSynthetic()) {
        method.setSynthetic();
    }

    if (b.isDefaultMethod()) {
        method.setDefaultMethod();
    }

    enclosingType.addMethod(method);
    JsInteropUtil.maybeSetJsinteropMethodProperties(x, method);
    processAnnotations(x, method);
    typeMap.setMethod(b, method);
}

From source file:com.google.gwt.dev.jjs.impl.ReferenceMapper.java

License:Apache License

JMethod createMethod(SourceInfo info, MethodBinding b, String[] paramNames) {
    JDeclaredType enclosingType = (JDeclaredType) get(b.declaringClass);
    JMethod method = new JMethod(info, intern(b.selector), enclosingType, get(b.returnType), b.isAbstract(),
            b.isStatic(), b.isFinal(), AccessModifier.fromMethodBinding(b));
    enclosingType.addMethod(method);/*from  w  w  w .j  ava  2s  .  c o  m*/
    if (paramNames == null) {
        mapParameters(info, method, b, 0);
    } else {
        mapParameters(info, method, b, paramNames);
    }
    mapExceptions(method, b);
    if (b.isSynthetic()) {
        method.setSynthetic();
    }
    return method;
}

From source file:com.redhat.ceylon.eclipse.core.model.mirror.JDTMethod.java

License:Open Source License

public JDTMethod(JDTClass enclosingClass, MethodBinding method) {
    this.enclosingClass = enclosingClass;
    bindingRef = new WeakReference<MethodBinding>(method);
    name = new String(method.selector);
    readableName = new String(method.readableName());
    isStatic = method.isStatic();/*from ww w  . j  av a  2  s.c o  m*/
    isPublic = method.isPublic();
    isConstructor = method.isConstructor();
    isStaticInit = method.selector == TypeConstants.CLINIT; // TODO : check if it is right
    isAbstract = method.isAbstract();
    isFinal = method.isFinal();
    isProtected = method.isProtected();
    isDefaultAccess = method.isDefault();
    isDeclaredVoid = method.returnType.id == TypeIds.T_void;
    isVariadic = method.isVarargs();
    isDefault = method.getDefaultValue() != null;
    bindingKey = method.computeUniqueKey();
    if (method instanceof ProblemMethodBinding) {
        annotations = new HashMap<>();
        parameters = Collections.emptyList();
        returnType = JDTType.UNKNOWN_TYPE;
        typeParameters = Collections.emptyList();
        isOverriding = false;
        isOverloading = false;
    }
}

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 ww  w .  ja va2  s .c om*/
    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.jdt.internal.compiler.lookup.SourceTypeBinding.java

License:Open Source License

public MethodBinding resolveTypesFor(MethodBinding method) {
    if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
        return method;

    if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
        if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
            method.modifiers |= ClassFileConstants.AccDeprecated;
    }//from ww  w.j  a  va  2s. c  om
    if (isViewedAsDeprecated() && !method.isDeprecated())
        method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
    if (hasRestrictedAccess())
        method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;

    AbstractMethodDeclaration methodDecl = method.sourceMethod();
    // GROOVY
    /* old {
    if (methodDecl == null) return null; // method could not be resolved in previous iteration
     } new*/
    if (methodDecl == null) {
        if (method instanceof LazilyResolvedMethodBinding) {
            LazilyResolvedMethodBinding lrMethod = (LazilyResolvedMethodBinding) method;
            // the rest is a copy of the code below but doesn't depend on the method declaration
            // nothing to do for method type parameters (there are none)
            // nothing to do for method exceptions (there are none)
            TypeBinding ptb = lrMethod.getParameterTypeBinding();
            if (ptb == null) {
                method.parameters = Binding.NO_PARAMETERS;
            } else {
                method.parameters = new TypeBinding[] { ptb };
            }
            method.returnType = lrMethod.getReturnTypeBinding();
            method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
            return method;
        }
        // returning null is what this clause would have done anyway
        return null;
    }
    // FIXASC - end

    TypeParameter[] typeParameters = methodDecl.typeParameters();
    if (typeParameters != null) {
        methodDecl.scope.connectTypeVariables(typeParameters, true);
        // Perform deferred bound checks for type variables (only done after type variable hierarchy is connected)
        for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++)
            typeParameters[i].checkBounds(methodDecl.scope);
    }
    TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
    if (exceptionTypes != null) {
        int size = exceptionTypes.length;
        method.thrownExceptions = new ReferenceBinding[size];
        int count = 0;
        ReferenceBinding resolvedExceptionType;
        for (int i = 0; i < size; i++) {
            resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope,
                    true /* check bounds*/);
            if (resolvedExceptionType == null)
                continue;
            if (resolvedExceptionType.isBoundParameterizedType()) {
                methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType,
                        exceptionTypes[i]);
                continue;
            }
            if (resolvedExceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
                if (resolvedExceptionType.isValidBinding()) {
                    methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i],
                            resolvedExceptionType);
                    continue;
                }
            }
            if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) {
                method.tagBits |= TagBits.HasMissingType;
            }
            method.modifiers |= (resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
            method.thrownExceptions[count++] = resolvedExceptionType;
        }
        if (count < size)
            System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count],
                    0, count);
    }
    final boolean reportUnavoidableGenericTypeProblems = this.scope
            .compilerOptions().reportUnavoidableGenericTypeProblems;
    boolean foundArgProblem = false;
    Argument[] arguments = methodDecl.arguments;
    if (arguments != null) {
        int size = arguments.length;
        method.parameters = Binding.NO_PARAMETERS;
        TypeBinding[] newParameters = new TypeBinding[size];
        for (int i = 0; i < size; i++) {
            Argument arg = arguments[i];
            if (arg.annotations != null) {
                method.tagBits |= TagBits.HasParameterAnnotations;
            }
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817
            boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems && !method.isConstructor()
                    && (arg.type.bits & ASTNode.IgnoreRawTypeCheck) == 0;
            TypeBinding parameterType;
            if (deferRawTypeCheck) {
                arg.type.bits |= ASTNode.IgnoreRawTypeCheck;
            }
            try {
                parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/);
            } finally {
                if (deferRawTypeCheck) {
                    arg.type.bits &= ~ASTNode.IgnoreRawTypeCheck;
                }
            }

            if (parameterType == null) {
                foundArgProblem = true;
            } else if (parameterType == TypeBinding.VOID) {
                methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this, methodDecl, arg);
                foundArgProblem = true;
            } else {
                if ((parameterType.tagBits & TagBits.HasMissingType) != 0) {
                    method.tagBits |= TagBits.HasMissingType;
                }
                TypeBinding leafType = parameterType.leafComponentType();
                if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers
                        & ExtraCompilerModifiers.AccGenericSignature) != 0)
                    method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
                newParameters[i] = parameterType;
                arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true);
            }
        }
        // only assign parameters if no problems are found
        if (!foundArgProblem) {
            method.parameters = newParameters;
        }
    }

    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799
    if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7) {
        if ((method.tagBits & TagBits.AnnotationSafeVarargs) != 0) {
            if (!method.isVarargs()) {
                methodDecl.scope.problemReporter().safeVarargsOnFixedArityMethod(method);
            } else if (!method.isStatic() && !method.isFinal() && !method.isConstructor()) {
                methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method);
            }
        } else if (method.parameters != null && method.parameters.length > 0 && method.isVarargs()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795
            if (!method.parameters[method.parameters.length - 1].isReifiable()) {
                methodDecl.scope.problemReporter()
                        .possibleHeapPollutionFromVararg(methodDecl.arguments[methodDecl.arguments.length - 1]);
            }
        }
    }

    boolean foundReturnTypeProblem = false;
    if (!method.isConstructor()) {
        TypeReference returnType = methodDecl instanceof MethodDeclaration
                ? ((MethodDeclaration) methodDecl).returnType
                : null;
        if (returnType == null) {
            methodDecl.scope.problemReporter().missingReturnType(methodDecl);
            method.returnType = null;
            foundReturnTypeProblem = true;
        } else {
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817
            boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems
                    && (returnType.bits & ASTNode.IgnoreRawTypeCheck) == 0;
            TypeBinding methodType;
            if (deferRawTypeCheck) {
                returnType.bits |= ASTNode.IgnoreRawTypeCheck;
            }
            try {
                methodType = returnType.resolveType(methodDecl.scope, true /* check bounds*/);
            } finally {
                if (deferRawTypeCheck) {
                    returnType.bits &= ~ASTNode.IgnoreRawTypeCheck;
                }
            }
            if (methodType == null) {
                foundReturnTypeProblem = true;
            } else if (methodType.isArrayType()
                    && ((ArrayBinding) methodType).leafComponentType == TypeBinding.VOID) {
                methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray((MethodDeclaration) methodDecl);
                foundReturnTypeProblem = true;
            } else {
                if ((methodType.tagBits & TagBits.HasMissingType) != 0) {
                    method.tagBits |= TagBits.HasMissingType;
                }
                method.returnType = methodType;
                TypeBinding leafType = methodType.leafComponentType();
                if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers
                        & ExtraCompilerModifiers.AccGenericSignature) != 0)
                    method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
            }
        }
    }
    if (foundArgProblem) {
        methodDecl.binding = null;
        method.parameters = Binding.NO_PARAMETERS; // see 107004
        // nullify type parameter bindings as well as they have a backpointer to the method binding
        // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134)
        if (typeParameters != null)
            for (int i = 0, length = typeParameters.length; i < length; i++)
                typeParameters[i].binding = null;
        return null;
    }
    if (foundReturnTypeProblem)
        return method; // but its still unresolved with a null return type & is still connected to its method declaration

    method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
    return method;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration.java

License:Open Source License

/**
  * In this case: check match of "replace" and "callin" flags, plus static-ness
  * @param haveBaseMethods have base methods been resolved?
  * @param baseClass       the role's bound base class
 *//*from   w w  w  .j av a2  s  . co  m*/
@Override
protected void checkModifiers(boolean haveBaseMethods, ReferenceBinding baseClass) {
    if (this.ignoreFurtherInvestigation) // error was already flagged, i.e. missing replace
        return;
    // replace and callin matching:
    if (isReplaceCallin()) {
        if (!this.roleMethodSpec.resolvedMethod.isCallin()) {
            this.scope.problemReporter().replaceMappingToNonCallin(this.roleMethodSpec,
                    this.roleMethodSpec.resolvedMethod);
            this.binding.tagBits |= TagBits.HasMappingIncompatibility;
            return;
        }
    } else {
        if (this.roleMethodSpec.resolvedMethod.isCallin()) {
            this.scope.problemReporter().callinMethodBoundNonReplace(this.roleMethodSpec, this);
            this.binding.tagBits |= TagBits.HasMappingIncompatibility;
            return;
        }
    }
    if (haveBaseMethods) {
        // static non-static consistency:
        if (!this.roleMethodSpec.resolvedMethod.isStatic()) {
            for (int i = 0; i < this.baseMethodSpecs.length; i++) {
                this.baseMethodSpecs[i].checkStaticness(this, false);
            }
        }
        if (isReplaceCallin()) {
            if (this.roleMethodSpec.resolvedMethod.isStatic()) {
                for (int i = 0; i < this.baseMethodSpecs.length; i++) {
                    this.baseMethodSpecs[i].checkStaticness(this, true);
                }
            }
        }
        // callin-to-final? respect OTJLD 4.1(f)
        for (int i = 0; i < this.baseMethodSpecs.length; i++) {
            MethodBinding baseMethod = this.baseMethodSpecs[i].resolvedMethod;
            if (baseMethod != null) {
                if (baseMethod.isFinal()) {
                    if (TypeBinding.notEquals(baseMethod.declaringClass, baseClass)) {
                        this.scope.problemReporter().bindingToInheritedFinal(this.baseMethodSpecs[i],
                                baseMethod, baseClass);
                        this.binding.tagBits |= TagBits.HasMappingIncompatibility;
                    }
                }
                if (baseMethod.isConstructor()) {
                    if (this.callinModifier != TokenNameafter) {
                        this.scope.problemReporter().callinToCtorMustBeAfter(this.baseMethodSpecs[i],
                                baseMethod);
                        this.binding.tagBits |= TagBits.HasMappingIncompatibility;
                    }
                }
            }
        }
    }
}

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// www  .j a va2 s.com
 * @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);
        }
    }
}