Example usage for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding readableName

List of usage examples for org.eclipse.jdt.internal.compiler.lookup ReferenceBinding readableName

Introduction

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

Prototype

@Override
public char[] readableName()  

Source Link

Document

Answer the receiver's signature.

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.search.matching.PatternLocator.java

License:Open Source License

protected int resolveLevelForType(char[] simpleNamePattern, char[] qualificationPattern,
        char[][][] patternTypeArguments, int depth, TypeBinding type) {
    // standard search with no generic additional information must succeed
    int level = resolveLevelForType(simpleNamePattern, qualificationPattern, type);
    if (level == IMPOSSIBLE_MATCH)
        return IMPOSSIBLE_MATCH;
    if (type == null || patternTypeArguments == null || patternTypeArguments.length == 0
            || depth >= patternTypeArguments.length) {
        return level;
    }//from   w ww . j  a v a2  s . co  m

    // if pattern is erasure match (see bug 79790), commute impossible to erasure
    int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH;

    // pattern has type parameter(s) or type argument(s)
    if (type.isGenericType()) {
        // Binding is generic, get its type variable(s)
        TypeVariableBinding[] typeVariables = null;
        if (type instanceof SourceTypeBinding) {
            SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type;
            typeVariables = sourceTypeBinding.typeVariables;
        } else if (type instanceof BinaryTypeBinding) {
            BinaryTypeBinding binaryTypeBinding = (BinaryTypeBinding) type;
            if (this.mustResolve)
                typeVariables = binaryTypeBinding.typeVariables(); // TODO (frederic) verify performance
        }
        if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0
                && typeVariables != null && typeVariables.length > 0) {
            if (typeVariables.length != patternTypeArguments[depth].length)
                return IMPOSSIBLE_MATCH;
        }
        // TODO (frederic) do we need to verify each parameter?
        return level; // we can't do better
    }

    // raw type always match
    if (type.isRawType()) {
        return level;
    }

    // Standard types (i.e. neither generic nor parameterized nor raw types)
    // cannot match pattern with type parameters or arguments
    TypeBinding leafType = type.leafComponentType();
    if (!leafType.isParameterizedType()) {
        return (patternTypeArguments[depth] == null || patternTypeArguments[depth].length == 0) ? level
                : IMPOSSIBLE_MATCH;
    }

    // Parameterized type
    ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType;

    // Compare arguments only if there ones on both sides
    if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0
            && paramTypeBinding.arguments != null && paramTypeBinding.arguments.length > 0) {

        // type parameters length must match at least specified type names length
        int length = patternTypeArguments[depth].length;
        if (paramTypeBinding.arguments.length != length)
            return IMPOSSIBLE_MATCH;

        // verify each pattern type parameter
        nextTypeArgument: for (int i = 0; i < length; i++) {
            char[] patternTypeArgument = patternTypeArguments[depth][i];
            TypeBinding argTypeBinding = paramTypeBinding.arguments[i];
            // get corresponding pattern wildcard
            switch (patternTypeArgument[0]) {
            case Signature.C_STAR: // unbound parameter always match
            case Signature.C_SUPER: // needs pattern type parameter binding
                // skip to next type argument as it will be resolved later
                continue nextTypeArgument;
            case Signature.C_EXTENDS:
                // remove wildcard from patter type argument
                patternTypeArgument = CharOperation.subarray(patternTypeArgument, 1,
                        patternTypeArgument.length);
                break;
            default:
                // no wildcard
                break;
            }
            // get pattern type argument from its signature
            patternTypeArgument = Signature.toCharArray(patternTypeArgument);
            if (!this.isCaseSensitive)
                patternTypeArgument = CharOperation.toLowerCase(patternTypeArgument);
            boolean patternTypeArgHasAnyChars = CharOperation.contains(new char[] { '*', '?' },
                    patternTypeArgument);

            // Verify that names match...
            // ...special case for wildcard
            if (argTypeBinding instanceof CaptureBinding) {
                WildcardBinding capturedWildcard = ((CaptureBinding) argTypeBinding).wildcard;
                if (capturedWildcard != null)
                    argTypeBinding = capturedWildcard;
            }
            if (argTypeBinding.isWildcard()) {
                WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding;
                switch (wildcardBinding.boundKind) {
                case Wildcard.EXTENDS:
                    // Invalid if type argument is not exact
                    if (patternTypeArgHasAnyChars)
                        return impossible;
                    continue nextTypeArgument;
                case Wildcard.UNBOUND:
                    // there's no bound name to match => valid
                    continue nextTypeArgument;
                }
                // Look if bound name match pattern type argument
                ReferenceBinding boundBinding = (ReferenceBinding) wildcardBinding.bound;
                if (CharOperation.match(patternTypeArgument, boundBinding.shortReadableName(),
                        this.isCaseSensitive)
                        || CharOperation.match(patternTypeArgument, boundBinding.readableName(),
                                this.isCaseSensitive)) {
                    // found name in hierarchy => match
                    continue nextTypeArgument;
                }

                // If pattern is not exact then match fails
                if (patternTypeArgHasAnyChars)
                    return impossible;

                // Look for bound name in type argument superclasses
                boundBinding = boundBinding.superclass();
                while (boundBinding != null) {
                    if (CharOperation.equals(patternTypeArgument, boundBinding.shortReadableName(),
                            this.isCaseSensitive)
                            || CharOperation.equals(patternTypeArgument, boundBinding.readableName(),
                                    this.isCaseSensitive)) {
                        // found name in hierarchy => match
                        continue nextTypeArgument;
                    } else if (boundBinding.isLocalType() || boundBinding.isMemberType()) {
                        // for local or member type, verify also source name (bug 81084)
                        if (CharOperation.match(patternTypeArgument, boundBinding.sourceName(),
                                this.isCaseSensitive))
                            continue nextTypeArgument;
                    }
                    boundBinding = boundBinding.superclass();
                }
                return impossible;
            }

            // See if names match
            if (CharOperation.match(patternTypeArgument, argTypeBinding.shortReadableName(),
                    this.isCaseSensitive)
                    || CharOperation.match(patternTypeArgument, argTypeBinding.readableName(),
                            this.isCaseSensitive)) {
                continue nextTypeArgument;
            } else if (argTypeBinding.isLocalType() || argTypeBinding.isMemberType()) {
                // for local or member type, verify also source name (bug 81084)
                if (CharOperation.match(patternTypeArgument, argTypeBinding.sourceName(), this.isCaseSensitive))
                    continue nextTypeArgument;
            }

            // If pattern is not exact then match fails
            if (patternTypeArgHasAnyChars)
                return impossible;

            // Scan hierarchy
            TypeBinding leafTypeBinding = argTypeBinding.leafComponentType();
            if (leafTypeBinding.isBaseType())
                return impossible;
            ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass();
            while (refBinding != null) {
                if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(),
                        this.isCaseSensitive)
                        || CharOperation.equals(patternTypeArgument, refBinding.readableName(),
                                this.isCaseSensitive)) {
                    // found name in hierarchy => match
                    continue nextTypeArgument;
                } else if (refBinding.isLocalType() || refBinding.isMemberType()) {
                    // for local or member type, verify also source name (bug 81084)
                    if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive))
                        continue nextTypeArgument;
                }
                refBinding = refBinding.superclass();
            }
            return impossible;
        }
    }

    // Recurse on enclosing type
    TypeBinding enclosingType = paramTypeBinding.enclosingType();
    if (enclosingType != null && enclosingType.isParameterizedType() && depth < patternTypeArguments.length
            && qualificationPattern != null) {
        int lastDot = CharOperation.lastIndexOf('.', qualificationPattern);
        char[] enclosingQualificationPattern = lastDot == -1 ? null
                : CharOperation.subarray(qualificationPattern, 0, lastDot);
        char[] enclosingSimpleNamePattern = lastDot == -1 ? qualificationPattern
                : CharOperation.subarray(qualificationPattern, lastDot + 1, qualificationPattern.length);
        int enclosingLevel = resolveLevelForType(enclosingSimpleNamePattern, enclosingQualificationPattern,
                patternTypeArguments, depth + 1, enclosingType);
        if (enclosingLevel == impossible)
            return impossible;
        if (enclosingLevel == IMPOSSIBLE_MATCH)
            return IMPOSSIBLE_MATCH;
    }
    return level;
}

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

License:Open Source License

public boolean isOverridingMethod() {
    if (isOverriding == null) {
        isOverriding = false;//from ww  w  . j a v a2 s  . c o  m

        doWithBindings(new ActionOnMethodBinding() {
            @Override
            public void doWithBinding(IType declaringClassModel, ReferenceBinding declaringClass,
                    MethodBinding method) {

                if (CharOperation.equals(declaringClass.readableName(),
                        "ceylon.language.Identifiable".toCharArray())) {
                    if ("equals".equals(name) || "hashCode".equals(name)) {
                        isOverriding = true;
                        return;
                    }
                }
                if (CharOperation.equals(declaringClass.readableName(),
                        "ceylon.language.Object".toCharArray())) {
                    if ("equals".equals(name) || "hashCode".equals(name) || "toString".equals(name)) {
                        isOverriding = false;
                        return;
                    }
                }

                // try the superclass first
                if (isDefinedInSuperClasses(declaringClass, method)) {
                    isOverriding = true;
                }
                if (isDefinedInSuperInterfaces(declaringClass, method)) {
                    isOverriding = true;
                }
            }
        });
    }
    return isOverriding.booleanValue();
}

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

License:Open Source License

private static TypeBinding ensureGetClassMethodPart(TypeDeclaration teamDecl, ReferenceBinding teamBinding,
        TypeDeclaration roleDecl, ReferenceBinding roleBinding, char[] selector) {
    MethodBinding[] existingMethods = teamBinding.getMethods(selector);
    if (existingMethods != NO_METHODS)
        return existingMethods[0].returnType; // already generated
    if (teamDecl == null)
        throw new InternalCompilerError("Requesting to generate a method for binary type " //$NON-NLS-1$
                + String.valueOf(teamBinding.readableName()));
    AstGenerator gen;/*ww w.  ja  v a2 s . c om*/
    if (roleDecl != null)
        gen = new AstGenerator(roleDecl.scope.compilerOptions().sourceLevel, roleDecl.sourceStart,
                roleDecl.sourceEnd);
    else
        gen = new AstGenerator(teamDecl.scope.compilerOptions().sourceLevel, teamDecl.sourceStart,
                teamDecl.sourceEnd);

    // return type reference is either "Class<Role>" or "Class<Role<?,?...>>"
    TypeVariableBinding[] typeVariables = roleBinding.typeVariables();
    TypeReference roleTypeRef;
    if (typeVariables != Binding.NO_TYPE_VARIABLES) {
        Wildcard[] wildcards = new Wildcard[typeVariables.length];
        for (int i = 0; i < typeVariables.length; i++)
            wildcards[i] = gen.wildcard(Wildcard.UNBOUND);
        roleTypeRef = gen.parameterizedSingleTypeReference(roleBinding.sourceName(), wildcards, 0);
    } else {
        roleTypeRef = gen.singleTypeReference(roleBinding.sourceName());
    }
    TypeReference[] typeArguments = new TypeReference[] { roleTypeRef };

    MethodDeclaration method = gen.method(teamDecl.compilationResult,
            (teamBinding.isRole()) ? ClassFileConstants.AccPublic // advertized via ifc, must be public
                    : roleBinding.modifiers & AccVisibilityMASK,
            gen.parameterizedQualifiedTypeReference( // java.lang.Class<R>
                    TypeConstants.JAVA_LANG_CLASS, typeArguments),
            selector, null);
    if (teamBinding.isInterface())
        method.modifiers |= ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody;
    else
        method.setStatements(new Statement[] { gen.returnStatement(new ClassLiteralAccess(gen.sourceEnd,
                gen.singleTypeReference(roleBinding.sourceName()), true)) });
    AstEdit.addMethod(teamDecl, method);
    return method.returnType.resolvedType;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.OTSpecialAccessAttribute.java

License:Open Source License

@SuppressWarnings("nls")
@Override//from   ww w . j a  v a2 s .  c om
public String toString() {
    StringBuilder result = new StringBuilder();
    result.append(this._site.readableName());
    result.append(" requires special access to these elements:");
    for (DecapsulatedMethodDesc method : this._decapsulatedMethods) {
        result.append("\n\tmethod ");
        result.append(method.toString());
    }
    for (CalloutToFieldDesc field : this._calloutToFields) {
        result.append("\n\tfield ");
        result.append(field.toString());
    }
    for (SuperMethodDesc method : this._superMethods) {
        result.append("\n\t");
        result.append(method.toString());
    }
    for (ReferenceBinding baseclass : this._adaptedBaseclasses) {
        result.append("\n\tbase class ");
        result.append(baseclass.readableName());
    }
    return result.toString();
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.DeclaredLifting.java

License:Open Source License

static Statement generateDynamicSwitch(BlockScope scope, ReferenceBinding roleType, int problemId,
        AstGenerator gen) {//from   ww  w  .j av a2  s. c om
    ReferenceBinding[] boundDescendants = roleType.roleModel.getBoundDescendants();
    int len = boundDescendants.length;
    if (len == 0)
        return gen.throwStatement(gen.allocation(gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_ERROR),
                new Expression[] { gen.stringLiteral(CharOperation.concat(
                        "Lifting impossible, role has no bound descendants: ".toCharArray(), //$NON-NLS-1$
                        roleType.readableName())) }));
    LookupEnvironment environment = scope.compilationUnitScope().environment;
    // toplevel "if"
    IfStatement ifStat = genNewIf(scope, gen, boundDescendants[0], environment);
    IfStatement current = ifStat;
    // needed at least one if, nested ifs are optional:
    for (int i = 1; i < len; i++) {
        IfStatement newIf = genNewIf(scope, gen, boundDescendants[i], environment);
        current.elseStatement = newIf; // nest within existing "if else { /* here */ }"
        current = newIf;
    }
    // final branch:
    current.elseStatement = Lifting.genLiftingFailedException(IOTConstants.BASE, roleType, problemId, gen);
    return ifStat;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lifting.java

License:Open Source License

/**
* API for AbstractMethodDeclaration:/*from w w  w.j ava2  s.  c o  m*/
*
 *  Create a byte code sequence for a runtime check in a creation method:
 *  R _OT$create_OT$R(B b) {
 *       if (this._OT$cache_OT$R.contains(b))
 *       throw new DuplicateRoleException("R");
 *     // continue regular code.
 *  }
 *
 * Note, the need for this runtime check is detected quite late.
 * At this point it is easier to create the byte code sequence directly,
 * rather the creating AST first.
 */
public static void createDuplicateRoleCheck(CodeStream codeStream, AbstractMethodDeclaration method) {
    MethodBinding binding = method.binding;
    Scope scope = method.scope;

    ReferenceBinding roleType = (ReferenceBinding) binding.returnType;
    String roleName = new String(roleType.readableName());
    // TODO(SH): check why roleType.getRoleModel().getClassPartBinding().roleModel may yield a different result.
    // I think it occured in haeder/stopwatch from smile-CVS.
    //RoleModel role = roleType.getRealClass().roleModel;
    char[] cacheName = LiftingEnvironment.getCacheName(roleType.roleModel.getBoundRootRole());

    ReferenceBinding teamBinding = roleType.enclosingType();//role.getTeamModel().getBinding();
    FieldBinding cache = TypeAnalyzer.findField(teamBinding, cacheName, /*static*/false, /*outer*/false,
            ITranslationStates.STATE_FULL_LIFTING); // generated by this state
    if (cache == null)
        throw new InternalCompilerError("generated cache field not found: " + new String(cacheName)); //$NON-NLS-1$
    ReferenceBinding map = (ReferenceBinding) scope.getType(IOTConstants.WEAK_HASH_MAP, 3);
    MethodBinding contains = map.getMethod(scope, IOTConstants.CONTAINS_KEY);

    ReferenceBinding exc = (ReferenceBinding) scope.getType(IOTConstants.ORG_OBJECTTEAMS_DUPLICATE_ROLE, 3);
    TypeBinding[] types = new TypeBinding[] { scope.getJavaLangString() };
    MethodBinding excInit = exc.getExactConstructor(types);

    BranchLabel normalCase = new BranchLabel(codeStream);

    codeStream.aload_0(); // this
    codeStream.fieldAccess(Opcodes.OPC_getfield, cache, teamBinding); // getfield      MyTeam._OT$cache_OT$R Ljava/util/WeakHashMap;
    codeStream.aload_1(); // arg0
    codeStream.invoke(Opcodes.OPC_invokevirtual, contains, map); // invokevirtual java.util.WeakHashMap.containsKey (Ljava/lang/Object;)Z
    codeStream.ifeq(normalCase); // false -> #endif
    codeStream.new_(exc); // new           <org.objectteams.DuplicateRoleException>
    codeStream.dup(); // dup
    codeStream.ldc(roleName); // ldc "R"
    codeStream.invoke(Opcodes.OPC_invokespecial, excInit, exc); // invokespecial org.objectteams.DuplicateRoleException.<init> (Ljava/lang/String;)V
    codeStream.athrow(); // athrow
    normalCase.place(); // #endif
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding.java

License:Open Source License

/** Answer the name of this callin qualified with the declaring class's name. */
public char[] getQualifiedName() {
    char[] name = this.name;
    if (name[0] == '<')
        return name; // synthetic name is already unique.
    ReferenceBinding currentType = this._declaringRoleClass;
    return CharOperation.concat(name, currentType.readableName(), '$');
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementor.java

License:Open Source License

/**
 * Record that the base argument is equivalent to the base field.
 * @param newMethod//w  ww  . java 2  s  .c o  m
 */
private void setBaseArgBestName(MethodDeclaration newMethod, Argument baseArg) {
    // base arg is always first, so binding cannot disturb argument order.
    baseArg.bind(newMethod.scope, baseArg.type.resolvedType, false);
    ITeamAnchor baseArgBinding = newMethod.arguments[0].binding;
    // lookup _OT$base:
    ReferenceBinding roleBinding = this._role.getBinding();
    if (!roleBinding.isHierarchyInconsistent() && !this._role.hasBaseclassProblem()) // CLOVER: never false in jacks suite
    {
        // have no base field if hierarchy is inconsistent (see TPX-214).
        ITeamAnchor baseField = TypeAnalyzer.findField(roleBinding, IOTConstants._OT_BASE, /*static*/false,
                /*outer*/true, ITranslationStates.STATE_ROLE_HIERARCHY_ANALYZED);
        // link both vars:
        if (baseField != null) {
            baseArgBinding.shareBestName(baseField);
        } else if (roleBinding.isRegularInterface()) {
            // OK!?
        } else {
            // Notes: Observed this while preparing the NODe-tutorial.
            //        Reoccurred as TPX-491, fixed by v14499.
            throw new InternalCompilerError(
                    "Role has no base field: " + new String(roleBinding.readableName())); //$NON-NLS-1$
        }
    }
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementorDyn.java

License:Open Source License

private void generateDispatchMethod(char[] methodName, final boolean isReplace, final boolean isAfter,
        final List<CallinMappingDeclaration> callinDecls, final TeamModel aTeam) {
    // FIXME(SH): once we know that Team has empty implementations (and checked cases involving team inheritance)
    // we probably want to avoid generating empty methods here.
    final TypeDeclaration teamDecl = aTeam.getAst();
    if (teamDecl == null)
        return;/*from  w w  w.j av a  2 s  .  co m*/

    final AstGenerator gen = new AstGenerator(teamDecl);
    gen.replaceableEnclosingClass = teamDecl.binding;

    // public void _OT$callBefore   (IBoundBase2 base,                      int boundMethodId, int callinId,    Object[] args)
    // public void _OT$callAfter   (IBoundBase2 base,                      int boundMethodId, int callinId,    Object[] args, Object result)
    // public void _OT$callReplace   (IBoundBase2 base, Team[] teams, int index,    int boundMethodId, int[] callinIds, Object[] args)
    int length = 4;
    if (isReplace)
        length = 6;
    else if (isAfter)
        length = 5;
    Argument[] arguments = new Argument[length];
    int a = 0;
    arguments[a++] = gen.argument(_BASE$, gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_IBOUNDBASE2));
    if (isReplace)
        arguments[a++] = gen.argument(TEAMS,
                gen.qualifiedArrayTypeReference(IOTConstants.ORG_OBJECTTEAMS_ITEAM, 1));
    if (isReplace)
        arguments[a++] = gen.argument(INDEX, gen.typeReference(TypeBinding.INT));
    arguments[a++] = isReplace ? gen.argument(CALLIN_ID, gen.createArrayTypeReference(TypeBinding.INT, 1))
            : gen.argument(CALLIN_ID, gen.typeReference(TypeBinding.INT));
    arguments[a++] = gen.argument(BOUND_METHOD_ID, gen.typeReference(TypeBinding.INT));
    arguments[a++] = gen.argument(ARGUMENTS,
            gen.qualifiedArrayTypeReference(TypeConstants.JAVA_LANG_OBJECT, 1));
    if (isAfter)
        arguments[a++] = gen.argument(_OT_RESULT, gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT));

    TypeReference returnTypeRef = isReplace ? gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT)
            : gen.typeReference(TypeBinding.VOID);

    final MethodDeclaration callMethod = gen.method(teamDecl.compilationResult, AccPublic, returnTypeRef,
            methodName, arguments);
    callMethod.isMappingWrapper = AbstractMethodDeclaration.WrapperKind.CALLIN;

    AstEdit.addMethod(teamDecl, callMethod);

    MethodModel.addCallinFlag(callMethod, IOTConstants.CALLIN_FLAG_WRAPPER);
    callMethod.model._declaringMappings = callinDecls;

    MethodModel.getModel(callMethod).setStatementsGenerator(new AbstractStatementsGenerator() {

        protected boolean generateStatements(AbstractMethodDeclaration methodDecl) {

            // into head of tryStats we generate local vars to be shared by case statements:
            List<Statement> tryStats = new ArrayList<Statement>();

            SwitchStatement switchStat = new SwitchStatement();
            switchStat.expression = isReplace
                    ? gen.arrayReference(gen.singleNameReference(CALLIN_ID), gen.singleNameReference(INDEX)) // switch(callinId[index]) {  ...
                    : gen.singleNameReference(CALLIN_ID); // switch(callinId) { ...

            // statements for the body of the switchStatement:
            List<Statement> statements = new ArrayList<Statement>();

            int callinIdCount = teamDecl.getTeamModel().getCallinIdCount();
            // callinIds not handled here will be handled using a super-call.
            boolean[] handledCallinIds = new boolean[callinIdCount];
            // do we need to catch LiftingFailedException?
            boolean canLiftingFail = false;
            // one case block per callin mapping:
            for (CallinMappingDeclaration callinDecl : callinDecls) {
                if (callinDecl.ignoreFurtherInvestigation
                        || RoleModel.isRoleWithBaseProblem(callinDecl.scope.referenceType()))
                    continue;
                if (!callinDecl.hasParsedParamMappings) // during reconcile we may not be interested in this level of detail (e.g., of a role file)
                    continue;

                gen.retargetFrom(callinDecl);

                // one case label per bound base method:
                for (MethodSpec baseSpec : callinDecl.baseMethodSpecs) {
                    statements.add(gen.caseStatement(gen.intLiteral(baseSpec.callinID))); // case <baseMethod.callinId>: 
                    handledCallinIds[baseSpec.callinID] = true;

                    PredicateGenerator predGen = new PredicateGenerator(callinDecl.binding._declaringRoleClass,
                            callinDecl.isReplaceCallin());

                    TypeBinding baseReturn = baseSpec.resolvedType();
                    boolean isStaticRoleMethod = callinDecl.getRoleMethod().isStatic();
                    ReferenceBinding roleType = callinDecl.scope.enclosingSourceType();
                    if (roleType.isGenericType()) // cannot handle generic role in this generated code
                        roleType = (ReferenceBinding) callinDecl.scope.environment().convertToRawType(roleType,
                                false);
                    MethodBinding roleMethodBinding = callinDecl.getRoleMethod();

                    boolean needLiftedRoleVar = !isStaticRoleMethod
                            && roleType.isCompatibleWith(roleMethodBinding.declaringClass);

                    List<Statement> blockStatements = new ArrayList<Statement>();

                    // do we need to expose _OT$result as result?
                    char[] resultName = null;
                    if (callinDecl.callinModifier == TerminalTokens.TokenNameafter
                            && (callinDecl.mappings != null || callinDecl.predicate != null)
                            && baseReturn != TypeBinding.VOID) {
                        resultName = RESULT;
                        callinDecl.resultVar = gen.localBaseVariable(RESULT, baseReturn, //   BaseReturnType result = (BaseReturnType)_OT$result; 
                                gen.createCastOrUnboxing(gen.singleNameReference(_OT_RESULT), baseReturn,
                                        true/*baseAccess*/));
                        blockStatements.add(callinDecl.resultVar);
                    }
                    // expose casted _base$ as "base":
                    blockStatements.add(gen.localVariable(IOTConstants.BASE,
                            gen.alienScopeTypeReference(gen.baseTypeReference(roleType.baseclass()),
                                    callinDecl.scope),
                            gen.castExpression(gen.baseNameReference(_BASE$),
                                    gen.alienScopeTypeReference(gen.baseTypeReference(roleType.baseclass()),
                                            callinDecl.scope),
                                    CastExpression.RAW)));

                    // -------------- base predicate check -------
                    boolean hasBasePredicate = false;
                    for (MethodSpec baseMethodSpec : callinDecl.baseMethodSpecs) { // FIXME: check this inner loop, outer already loops over baseMethods!!
                        char[] resultName2 = null;
                        if (callinDecl.callinModifier == TerminalTokens.TokenNameafter
                                && baseMethodSpec.resolvedType() != TypeBinding.VOID) {
                            resultName2 = IOTConstants.RESULT;
                        }
                        // FIXME(SH): only call predidate for the current base method (from BoundMethodID?)
                        Statement predicateCheck = predGen.createBasePredicateCheck(callinDecl, baseMethodSpec,
                                resultName2, gen);
                        if (predicateCheck != null) {
                            blockStatements.add(predicateCheck); //   if (!base$when(baseArg,...)) throw new LiftingVetoException();
                            hasBasePredicate = true;
                        }
                    }
                    Expression resetFlag = CallinImplementor.setExecutingCallin(roleType.roleModel,
                            blockStatements); //   boolean _OT$oldIsExecutingCallin = _OT$setExecutingCallin(true);

                    // ----------- receiver for role method call: -----------
                    Expression receiver;
                    char[] roleVar = null;
                    if (!isStaticRoleMethod) {
                        if (needLiftedRoleVar) {

                            canLiftingFail |= checkLiftingProblem(teamDecl, callinDecl, roleType);

                            roleVar = (LOCAL_ROLE + statements.size()).toCharArray();
                            TypeReference roleTypeReference = gen
                                    .roleTypeReference(teamDecl.getTeamModel().getTThis(), roleType, 0);
                            blockStatements.add(gen.localVariable(roleVar, //   RoleType local$n = this._OT$liftToRoleType((BaseType)base);
                                    gen.alienScopeTypeReference(roleTypeReference, callinDecl.scope),
                                    ClassFileConstants.AccFinal,
                                    Lifting.liftCall(callMethod.scope, gen.thisReference(),
                                            gen.baseNameReference(IOTConstants.BASE), callMethod.scope
                                                    .getType(IOTConstants.ORG_OBJECTTEAMS_IBOUNDBASE2, 3),
                                            roleType, false, gen)));
                            receiver = gen.thislikeNameReference(roleVar);
                            // private receiver needs to be casted to the class.
                        } else {
                            // method is from role's enclosing team
                            receiver = gen.qualifiedThisReference(TeamModel
                                    .strengthenEnclosing(teamDecl.binding, roleMethodBinding.declaringClass));
                        }
                    } else {
                        receiver = gen
                                .singleNameReference(callinDecl.getRoleMethod().declaringClass.sourceName());
                    }

                    int baseArgOffset = 0;
                    if (baseSpec.isCallin())
                        baseArgOffset += MethodSignatureEnhancer.getEnhancingArgLen(WeavingScheme.OTDRE);
                    if (baseSpec.isStatic() && baseSpec.getDeclaringClass().isRole())
                        baseArgOffset += 2;
                    // unpack arguments to be used by parameter mappings and base predicate:
                    // ArgTypeN argn = args[n]
                    if (callinDecl.mappings != null || (hasBasePredicate && baseSpec.arguments != null)) {
                        TypeBinding[] baseParams = baseSpec.resolvedParameters();
                        for (int i = 0; i < baseSpec.arguments.length; i++) { //   BaseType baseArg = castAndOrUnbox(arguments[n]);
                            Argument baseArg = baseSpec.arguments[i];
                            Expression rawArg = gen.arrayReference(gen.singleNameReference(ARGUMENTS),
                                    i + baseArgOffset);
                            Expression init = rawArg;
                            if (!baseParams[i].isTypeVariable())
                                init = gen.createCastOrUnboxing(rawArg, baseParams[i], callinDecl.scope);
                            LocalDeclaration baseArgLocal = gen.localVariable(baseArg.name,
                                    gen.alienScopeTypeReference(baseArg.type, callinDecl.scope), init);
                            baseArgLocal.modifiers |= (baseArg.modifiers & ClassFileConstants.AccFinal);
                            if (hasBasePredicate) {
                                // add to front so it is already available for the base predicate check:
                                blockStatements.add(i, baseArgLocal);
                            } else {
                                // otherwise give it a chance for expressions/types that depend on the role instance
                                baseArgLocal.initialization = new PotentialRoleReceiverExpression(init, roleVar,
                                        gen.typeReference(roleType));
                                blockStatements.add(baseArgLocal);
                            }
                        }
                    }

                    // -- assemble arguments:
                    TypeBinding[] roleParams = callinDecl.roleMethodSpec.resolvedParameters();
                    Expression[] callArgs = new Expression[roleParams.length
                            + (isReplace ? MethodSignatureEnhancer.getEnhancingArgLen(WeavingScheme.OTDRE)
                                    : 0)];
                    int idx = 0;
                    if (isReplace)
                        for (char[] argName : REPLACE_ARG_NAMES)
                            callArgs[idx++] = gen.singleNameReference(argName); //    prepare: base, teams, boundMethodId, callinIds, index, arguments ...

                    // prepare parameter mappings:
                    callinDecl.traverse(new ReplaceResultReferenceVisitor(callinDecl),
                            callinDecl.scope.classScope());

                    boolean hasArgError = false;
                    for (int i = 0; i < roleParams.length; i++) {
                        Expression arg;
                        TypeBinding roleParam = roleParams[i];
                        if (roleParam.isTypeVariable()) {
                            TypeVariableBinding tvb = (TypeVariableBinding) roleParam;
                            if (tvb.declaringElement instanceof MethodBinding) {
                                if (TypeBinding.equalsEquals(
                                        ((MethodBinding) tvb.declaringElement).declaringClass, roleType))
                                    // don't use type variable of target method, see test4140_callinReplaceCompatibility10s()
                                    roleParam = roleParam.erasure();
                            }
                        }
                        TypeReference localTypeRef = null;
                        if (callinDecl.mappings == null) {
                            // ------------ unmapped arguments --------------
                            arg = gen.arrayReference(gen.singleNameReference(ARGUMENTS), i + baseArgOffset); //    prepare: somePreparation(arguments[i])
                            TypeBinding baseArgType = baseSpec.resolvedParameters()[i];
                            if (roleParam.isBaseType()) {
                                // this includes intermediate cast to boxed type:
                                arg = gen.createUnboxing(arg, (BaseTypeBinding) roleParam);
                            } else if (baseArgType.isBaseType()) {
                                // Object -> BoxingType
                                arg = gen.castExpression(arg,
                                        gen.qualifiedTypeReference(
                                                AstGenerator.boxTypeName((BaseTypeBinding) baseArgType)),
                                        CastExpression.RAW);
                            } else {
                                // Object -> MyBaseClass
                                ReferenceBinding baseclass = roleType.baseclass();
                                if (baseclass instanceof DependentTypeBinding
                                        && baseArgType instanceof ReferenceBinding)
                                    baseArgType = RoleTypeCreator.maybeInstantiateFromPlayedBy(callinDecl.scope,
                                            (ReferenceBinding) baseArgType);
                                arg = gen.castExpression(arg,
                                        gen.alienScopeTypeReference(gen.typeReference(baseArgType),
                                                callinDecl.scope),
                                        CastExpression.DO_WRAP);
                                if (!roleParam.leafComponentType().isBaseType() && PotentialLiftExpression
                                        .isLiftingRequired(callinDecl.scope, roleParam, baseArgType, arg)) {
                                    // lift?(MyBaseClass)
                                    Reference liftReceiver = null; // default: let gen find the team
                                    if (roleType.isTeam()
                                            && TypeBinding.equalsEquals(roleParam.enclosingType(), roleType))
                                        liftReceiver = gen.singleNameReference(roleVar); // lift to inner role
                                    arg = gen.potentialLift(liftReceiver, arg, roleParam,
                                            isReplace/*reversible*/);
                                    localTypeRef = gen.typeReference(roleParam);
                                    canLiftingFail |= checkLiftingProblem(teamDecl, callinDecl,
                                            (ReferenceBinding) roleParam.leafComponentType());
                                }
                            }
                            if (localTypeRef == null)
                                localTypeRef = gen.baseclassReference(baseArgType); // unless lifting was required above
                        } else {
                            // ------------ mapped arguments --------------
                            if (roleParam.isTypeVariable()
                                    && ((TypeVariableBinding) roleParam).declaringElement instanceof CallinCalloutBinding)
                                localTypeRef = gen.typeReference(roleParam.erasure()); // cannot explicitly mention this TVB
                            else
                                localTypeRef = gen.typeReference(roleParam);

                            arg = getArgument(callinDecl, //    prepare:  <mappedArg<n>>
                                    (MethodDeclaration) methodDecl, callinDecl.getRoleMethod().parameters,
                                    i + idx, baseSpec);
                            if (arg == null) {
                                hasArgError = true;
                                continue; // keep going to find problems with other args, too.
                            }
                            if (Lifting.isLiftToMethodCall(arg))
                                canLiftingFail |= checkLiftingProblem(teamDecl, callinDecl, roleType);
                            boolean isBaseReference = arg instanceof SingleNameReference && CharOperation
                                    .equals(((SingleNameReference) arg).token, IOTConstants.BASE);
                            if (needLiftedRoleVar)
                                arg = new PotentialRoleReceiverExpression(arg, roleVar,
                                        gen.typeReference(roleType.getRealClass()));
                            // mapped expression may require casting: "base" reference has static type IBoundBase2
                            if (isBaseReference)
                                arg = gen.castExpression(arg, gen.typeReference(roleParam), CastExpression.RAW);
                        }
                        char[] localName = (OT_LOCAL + i).toCharArray(); //    RoleParamType _OT$local$n = preparedArg<n>;
                        blockStatements.add(gen.localVariable(localName,
                                gen.alienScopeTypeReference(localTypeRef, callinDecl.scope), arg));
                        callArgs[i + idx] = gen.singleNameReference(localName); //    prepare: ... _OT$local$ ...

                    }
                    if (hasArgError)
                        continue;

                    // -- role side predicate:
                    Expression[] predicateArgs = isReplace
                            ? MethodSignatureEnhancer.retrenchBasecallArguments(callArgs, true,
                                    WeavingScheme.OTDRE)
                            : callArgs;
                    predicateArgs = maybeAddResultReference(callinDecl, predicateArgs, resultName, gen);
                    Statement rolePredicateCheck = predGen.createPredicateCheck( //    if (!when(callArgs)) throw new LiftingVetoException();
                            callinDecl, callinDecl.scope.referenceType(), receiver, predicateArgs, callArgs,
                            gen);
                    if (rolePredicateCheck != null)
                        // predicateCheck(_OT$role)
                        blockStatements.add(rolePredicateCheck);

                    // -- assemble the method call:                                                //    local$n.roleMethod((ArgType0)args[0], .. (ArgTypeN)args[n]);
                    boolean lhsResolvesToTeamMethod = TypeBinding
                            .equalsEquals(callinDecl.getRoleMethod().declaringClass, roleType.enclosingType()); // TODO(SH): more levels
                    MessageSend roleMethodCall = (callinDecl.getRoleMethod().isPrivate()
                            && !lhsResolvesToTeamMethod)
                                    ? new PrivateRoleMethodCall(receiver, callinDecl.roleMethodSpec.selector,
                                            callArgs, false/*c-t-f*/, callinDecl.scope, roleType,
                                            callinDecl.getRoleMethod(), gen)
                                    : gen.messageSend(receiver, callinDecl.roleMethodSpec.selector, callArgs);
                    roleMethodCall.isGenerated = true; // for PrivateRoleMethodCall
                    roleMethodCall.isPushedOutRoleMethodCall = true;

                    // -- post processing:
                    Statement[] messageSendStatements;
                    if (isReplace) {
                        Expression result = roleMethodCall;
                        if (baseSpec.returnNeedsTranslation) {
                            // lowering:
                            TypeBinding[]/*role,base*/ returnTypes = getReturnTypes(callinDecl, 0);
                            //   who is responsible for lowering: the team or the current role?
                            Expression lowerReceiver = (isRoleOfCurrentRole(roleType, returnTypes[0]))
                                    ? gen.singleNameReference(roleVar)
                                    : genTeamThis(gen, returnTypes[0]);
                            result = new Lowering().lowerExpression(methodDecl.scope, result, returnTypes[0],
                                    returnTypes[1], lowerReceiver, true/*needNullCheck*/,
                                    true/*delayedResolve*/);
                        }
                        // possibly convert using result mapping
                        callinDecl.checkResultMapping();
                        boolean isResultBoxed = baseReturn.isBaseType() && baseReturn != TypeBinding.VOID;
                        if (callinDecl.mappings != null && callinDecl.isResultMapped) {
                            if (isResultBoxed)
                                result = gen.createUnboxing(result, (BaseTypeBinding) baseReturn);
                            Expression mappedResult = new PotentialRoleReceiverExpression(
                                    callinDecl.getResultExpression(baseSpec, isResultBoxed, gen/*stepOverGen*/),
                                    roleVar, gen.typeReference(roleType.getRealClass()));
                            messageSendStatements = new Statement[] {
                                    callinDecl.resultVar = gen.localVariable(IOTConstants.RESULT, baseReturn, //   result = (Type)role.roleMethod(args);
                                            gen.castExpression(result, gen.typeReference(baseReturn),
                                                    CastExpression.RAW)),
                                    // cast because role return might be generalized
                                    gen.returnStatement(mappedResult) //   return mappedResult(result);
                            };
                        } else {
                            if (isResultBoxed) { // $if_need_result_unboxing$
                                messageSendStatements = new Statement[] {
                                        gen.localVariable(IOTConstants.OT_RESULT, //   Object _OT$result = role.roleMethod(args);
                                                gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT),
                                                result),
                                        CallinImplementor.genResultNotProvidedCheck( //    if (_OT$result == null)
                                                teamDecl.binding.readableName(), //      throw new ResultNotProvidedException(..)
                                                roleType.readableName(), roleMethodBinding,
                                                roleType.baseclass(), baseSpec, gen),
                                        gen.returnStatement(gen.singleNameReference(IOTConstants.OT_RESULT)) //  return _OT$result;
                                };
                            } else { // $endif$
                                messageSendStatements = new Statement[] { gen.returnStatement(result) }; //   return role.roleMethod(args);
                            }
                        }
                    } else {
                        messageSendStatements = new Statement[] { roleMethodCall, //   role.roleMethod(args);
                                gen.breakStatement() //   break;
                        };
                    }
                    // assemble:
                    //      try { roleMessageSend(); }
                    //      catch(Exception _OT$caughtException) { throw new SneakyException(_OT$caughtException); }
                    //      finally { _OT$setExecutingCallin(_OT$oldIsExecutingCallin); } 
                    blockStatements.add(
                            protectRoleMethodCall(messageSendStatements, roleMethodBinding, resetFlag, gen));
                    statements.add(gen.block(blockStatements.toArray(new Statement[blockStatements.size()])));
                    // collectively report the problem(s)
                    if (canLiftingFail && callinDecl.rolesWithLiftingProblem != null)
                        for (Map.Entry<ReferenceBinding, Integer> entry : callinDecl.rolesWithLiftingProblem
                                .entrySet())
                            callinDecl.scope.problemReporter().callinDespiteLiftingProblem(entry.getKey(),
                                    entry.getValue(), callinDecl);
                }
            } // END for (CallinMappingDeclaration callinDecl : callinDecls) 

            gen.retargetFrom(teamDecl);

            boolean needSuperCall = false;
            // do we have a relevant super team, which possibly defines more callins?
            ReferenceBinding superTeam = aTeam.getBinding().superclass();
            if (superTeam != null && superTeam.isTeam() && superTeam.id != IOTConstants.T_OrgObjectTeamsTeam) {
                // callinIds to be handled by super call?
                for (int i = 0; i < callinIdCount; i++)
                    if (!handledCallinIds[i]) {
                        statements.add(gen.caseStatement(gen.intLiteral(i))); // case callinIdOfSuper:
                        needSuperCall = true;
                    }
                if (!isReplace)
                    needSuperCall = true;
                // a super call might become necessary after the fact when this dispatch method
                // is copy-inherited to a tsub-team, because the tsub-team may have a super
                // with more callins, see test1111_roleInheritsCallinFromTsupers1.
                // TODO: can we safely handle this for the replace-case, too??
                // (replace needs to "return _OT$callNext();" in the default branch, see below).
                // See https://bugs.eclipse.org/433123
            }
            if (needSuperCall) {
                if (!isReplace)
                    statements.add(gen.caseStatement(null)); // default label
                char[] selector;
                char[][] argNames;
                if (isReplace) {
                    selector = OT_CALL_REPLACE;
                    argNames = REPLACE_ARG_NAMES;
                } else if (isAfter) {
                    selector = OT_CALL_AFTER;
                    argNames = AFTER_ARG_NAMES;
                } else {
                    selector = OT_CALL_BEFORE;
                    argNames = BEFORE_ARG_NAMES;
                }
                Expression[] superCallArgs = new Expression[argNames.length];
                for (int idx = 0; idx < argNames.length; idx++)
                    superCallArgs[idx] = gen.singleNameReference(argNames[idx]);
                // if we have a tsuper team which a corresponding dispatch method that one takes precedence:
                MessageSend superCall = aTeam.hasTSuperTeamMethod(selector)
                        ? gen.tsuperMessageSend(gen.thisReference(), selector, superCallArgs)
                        : gen.messageSend(gen.superReference(), selector, superCallArgs);
                if (isReplace)
                    statements.add(gen.returnStatement(superCall)); //    return super._OT$callReplace(..);
                else
                    statements.add(superCall); //    super._OT$callBefore/After(..);
            }

            Statement catchStatement1 = gen.emptyStatement();
            Statement catchStatement2 = gen.emptyStatement();
            if (isReplace) {

                // default: callNext:
                Expression[] callArgs = new Expression[REPLACE_ARG_NAMES.length + 1];
                for (int idx = 0; idx < REPLACE_ARG_NAMES.length; idx++)
                    callArgs[idx] = gen.singleNameReference(REPLACE_ARG_NAMES[idx]);
                callArgs[callArgs.length - 1] = gen.nullLiteral(); // no explicit baseCallArguments
                statements.add(gen.caseStatement(null)); // default:
                statements.add(gen.returnStatement( //    return _OT$callNext(..);
                        gen.messageSend(gen.qualifiedThisReference(aTeam.getBinding()), OT_CALL_NEXT,
                                callArgs)));
                catchStatement1 = gen.returnStatement(gen
                        .messageSend(gen.qualifiedThisReference(aTeam.getBinding()), OT_CALL_NEXT, callArgs));
                catchStatement2 = gen.returnStatement(gen
                        .messageSend(gen.qualifiedThisReference(aTeam.getBinding()), OT_CALL_NEXT, callArgs));
            }

            // ==== overall assembly: ====
            switchStat.statements = statements.toArray(new Statement[statements.size()]);
            Argument[] exceptionArguments;
            Statement[][] exceptionStatementss;
            if (canLiftingFail) {
                exceptionArguments = new Argument[] { gen.argument("ex".toCharArray(), //$NON-NLS-1$
                        gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_LIFTING_VETO)),
                        gen.argument("ex".toCharArray(), //$NON-NLS-1$
                                gen.qualifiedTypeReference(IOTConstants.O_O_LIFTING_FAILED_EXCEPTION)) };
                exceptionStatementss = new Statement[][] { { catchStatement1 }, { catchStatement2 } };
            } else {
                exceptionArguments = new Argument[] { gen.argument("ex".toCharArray(), //$NON-NLS-1$
                        gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_LIFTING_VETO)) };
                exceptionStatementss = new Statement[][] { { catchStatement1 } };
            }
            tryStats.add(switchStat);
            methodDecl.statements = new Statement[] {
                    gen.tryCatch(tryStats.toArray(new Statement[tryStats.size()]),
                            // expected exception is ignored, do nothing (before/after) or proceed to callNext (replace)
                            exceptionArguments, exceptionStatementss) };
            methodDecl.hasParsedStatements = true;
            return true;
        }

    });
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.model.FieldModel.java

License:Open Source License

/** Given that this is the model of a fake strong base field, return the original field from the super role. */
public FieldBinding getOriginalFromFake() {
    ReferenceBinding superRole = this.actualDeclaringClass;
    FieldBinding fieldBinding = superRole.getField(this._binding.name, true);
    if (fieldBinding == null)
        throw new InternalCompilerError(
                "Expected base field not found in super Role " + new String(superRole.readableName())); //$NON-NLS-1$
    return fieldBinding;
}