Search in sources :

Example 11 with AbstractMethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration in project lombok by rzwitserloot.

the class HandleHelper method handle.

@Override
public void handle(AnnotationValues<Helper> annotation, Annotation ast, EclipseNode annotationNode) {
    handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper");
    EclipseNode annotatedType = annotationNode.up();
    EclipseNode containingBlock = annotatedType == null ? null : annotatedType.directUp();
    Statement[] origStatements = getStatementsFromAstNode(containingBlock == null ? null : containingBlock.get());
    if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) {
        annotationNode.addError("@Helper is legal only on method-local classes.");
        return;
    }
    TypeDeclaration annotatedType_ = (TypeDeclaration) annotatedType.get();
    int indexOfType = -1;
    for (int i = 0; i < origStatements.length; i++) {
        if (origStatements[i] == annotatedType_) {
            indexOfType = i;
            break;
        }
    }
    final List<String> knownMethodNames = new ArrayList<String>();
    for (AbstractMethodDeclaration methodOfHelper : annotatedType_.methods) {
        if (!(methodOfHelper instanceof MethodDeclaration))
            continue;
        char[] name = methodOfHelper.selector;
        if (name != null && name.length > 0 && name[0] != '<')
            knownMethodNames.add(new String(name));
    }
    Collections.sort(knownMethodNames);
    final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
    final char[] helperName = new char[annotatedType_.name.length + 1];
    final boolean[] helperUsed = new boolean[1];
    helperName[0] = '$';
    System.arraycopy(annotatedType_.name, 0, helperName, 1, helperName.length - 1);
    ASTVisitor visitor = new ASTVisitor() {

        @Override
        public boolean visit(MessageSend messageSend, BlockScope scope) {
            if (messageSend.receiver instanceof ThisReference) {
                if ((((ThisReference) messageSend.receiver).bits & ASTNode.IsImplicitThis) == 0)
                    return true;
            } else if (messageSend.receiver != null)
                return true;
            char[] name = messageSend.selector;
            if (name == null || name.length == 0 || name[0] == '<')
                return true;
            String n = new String(name);
            if (Arrays.binarySearch(knownMethodNames_, n) < 0)
                return true;
            messageSend.receiver = new SingleNameReference(helperName, messageSend.nameSourcePosition);
            helperUsed[0] = true;
            return true;
        }
    };
    for (int i = indexOfType + 1; i < origStatements.length; i++) {
        origStatements[i].traverse(visitor, null);
    }
    if (!helperUsed[0]) {
        annotationNode.addWarning("No methods of this helper class are ever used.");
        return;
    }
    Statement[] newStatements = new Statement[origStatements.length + 1];
    System.arraycopy(origStatements, 0, newStatements, 0, indexOfType + 1);
    System.arraycopy(origStatements, indexOfType + 1, newStatements, indexOfType + 2, origStatements.length - indexOfType - 1);
    LocalDeclaration decl = new LocalDeclaration(helperName, 0, 0);
    decl.modifiers |= ClassFileConstants.AccFinal;
    AllocationExpression alloc = new AllocationExpression();
    alloc.type = new SingleTypeReference(annotatedType_.name, 0L);
    decl.initialization = alloc;
    decl.type = new SingleTypeReference(annotatedType_.name, 0L);
    SetGeneratedByVisitor sgbvVisitor = new SetGeneratedByVisitor(annotationNode.get());
    decl.traverse(sgbvVisitor, null);
    newStatements[indexOfType + 1] = decl;
    setStatementsOfAstNode(containingBlock.get(), newStatements);
}
Also used : LocalDeclaration(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) SwitchStatement(org.eclipse.jdt.internal.compiler.ast.SwitchStatement) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) ArrayList(java.util.ArrayList) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) ASTVisitor(org.eclipse.jdt.internal.compiler.ASTVisitor) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) BlockScope(org.eclipse.jdt.internal.compiler.lookup.BlockScope) EclipseNode(lombok.eclipse.EclipseNode) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Example 12 with AbstractMethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration in project lombok by rzwitserloot.

the class HandleNonNull method handle.

@Override
public void handle(AnnotationValues<NonNull> annotation, Annotation ast, EclipseNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull");
    if (annotationNode.up().getKind() == Kind.FIELD) {
        try {
            if (isPrimitive(((AbstractVariableDeclaration) annotationNode.up().get()).type)) {
                annotationNode.addWarning("@NonNull is meaningless on a primitive.");
            }
        } catch (Exception ignore) {
        }
        return;
    }
    if (annotationNode.up().getKind() != Kind.ARGUMENT)
        return;
    Argument arg;
    AbstractMethodDeclaration declaration;
    try {
        arg = (Argument) annotationNode.up().get();
        declaration = (AbstractMethodDeclaration) annotationNode.up().up().get();
    } catch (Exception e) {
        return;
    }
    if (isGenerated(declaration))
        return;
    if (declaration.isAbstract()) {
        // This used to be a warning, but as @NonNull also has a documentary purpose, better to not warn about this. Since 1.16.7
        return;
    }
    // Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter,
    // and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
    // wrap all references to it in the super/this to a call to this method.
    Statement nullCheck = generateNullCheck(arg, annotationNode);
    if (nullCheck == null) {
        // @NonNull applied to a primitive. Kinda pointless. Let's generate a warning.
        annotationNode.addWarning("@NonNull is meaningless on a primitive.");
        return;
    }
    if (declaration.statements == null) {
        declaration.statements = new Statement[] { nullCheck };
    } else {
        char[] expectedName = arg.name;
        /* Abort if the null check is already there, delving into try and synchronized statements */
        {
            Statement[] stats = declaration.statements;
            int idx = 0;
            while (stats != null && stats.length > idx) {
                Statement stat = stats[idx++];
                if (stat instanceof TryStatement) {
                    stats = ((TryStatement) stat).tryBlock.statements;
                    idx = 0;
                    continue;
                }
                if (stat instanceof SynchronizedStatement) {
                    stats = ((SynchronizedStatement) stat).block.statements;
                    idx = 0;
                    continue;
                }
                char[] varNameOfNullCheck = returnVarNameIfNullCheck(stat);
                if (varNameOfNullCheck == null)
                    break;
                if (Arrays.equals(varNameOfNullCheck, expectedName))
                    return;
            }
        }
        Statement[] newStatements = new Statement[declaration.statements.length + 1];
        int skipOver = 0;
        for (Statement stat : declaration.statements) {
            if (isGenerated(stat) && isNullCheck(stat))
                skipOver++;
            else
                break;
        }
        System.arraycopy(declaration.statements, 0, newStatements, 0, skipOver);
        System.arraycopy(declaration.statements, skipOver, newStatements, skipOver + 1, declaration.statements.length - skipOver);
        newStatements[skipOver] = nullCheck;
        declaration.statements = newStatements;
    }
    annotationNode.up().up().rebuild();
}
Also used : Argument(org.eclipse.jdt.internal.compiler.ast.Argument) TryStatement(org.eclipse.jdt.internal.compiler.ast.TryStatement) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) SynchronizedStatement(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) ThrowStatement(org.eclipse.jdt.internal.compiler.ast.ThrowStatement) TryStatement(org.eclipse.jdt.internal.compiler.ast.TryStatement) SynchronizedStatement(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Example 13 with AbstractMethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration in project lombok by rzwitserloot.

the class PatchDelegate method createDelegateMethod.

private static MethodDeclaration createDelegateMethod(char[] name, EclipseNode typeNode, BindingTuple pair, CompilationResult compilationResult, EclipseNode annNode, DelegateReceiver delegateReceiver) {
    /* public <T, U, ...> ReturnType methodName(ParamType1 name1, ParamType2 name2, ...) throws T1, T2, ... {
		 *      (return) delegate.<T, U>methodName(name1, name2);
		 *  }
		 */
    boolean isVarargs = (pair.base.modifiers & ClassFileConstants.AccVarargs) != 0;
    try {
        checkConflictOfTypeVarNames(pair, typeNode);
    } catch (CantMakeDelegates e) {
        annNode.addError("There's a conflict in the names of type parameters. Fix it by renaming the following type parameters of your class: " + e.conflicted);
        return null;
    }
    ASTNode source = annNode.get();
    int pS = source.sourceStart, pE = source.sourceEnd;
    MethodBinding binding = pair.parameterized;
    MethodDeclaration method = new MethodDeclaration(compilationResult);
    setGeneratedBy(method, source);
    method.sourceStart = pS;
    method.sourceEnd = pE;
    method.modifiers = ClassFileConstants.AccPublic;
    method.returnType = makeType(binding.returnType, source, false);
    boolean isDeprecated = binding.isDeprecated();
    method.selector = binding.selector;
    if (binding.thrownExceptions != null && binding.thrownExceptions.length > 0) {
        method.thrownExceptions = new TypeReference[binding.thrownExceptions.length];
        for (int i = 0; i < method.thrownExceptions.length; i++) {
            method.thrownExceptions[i] = makeType(binding.thrownExceptions[i], source, false);
        }
    }
    MessageSend call = new MessageSend();
    call.sourceStart = pS;
    call.sourceEnd = pE;
    call.nameSourcePosition = pos(source);
    setGeneratedBy(call, source);
    call.receiver = delegateReceiver.get(source, name);
    call.selector = binding.selector;
    if (binding.typeVariables != null && binding.typeVariables.length > 0) {
        method.typeParameters = new TypeParameter[binding.typeVariables.length];
        call.typeArguments = new TypeReference[binding.typeVariables.length];
        for (int i = 0; i < method.typeParameters.length; i++) {
            method.typeParameters[i] = new TypeParameter();
            method.typeParameters[i].sourceStart = pS;
            method.typeParameters[i].sourceEnd = pE;
            setGeneratedBy(method.typeParameters[i], source);
            method.typeParameters[i].name = binding.typeVariables[i].sourceName;
            call.typeArguments[i] = new SingleTypeReference(binding.typeVariables[i].sourceName, pos(source));
            setGeneratedBy(call.typeArguments[i], source);
            ReferenceBinding super1 = binding.typeVariables[i].superclass;
            ReferenceBinding[] super2 = binding.typeVariables[i].superInterfaces;
            if (super2 == null)
                super2 = new ReferenceBinding[0];
            if (super1 != null || super2.length > 0) {
                int offset = super1 == null ? 0 : 1;
                method.typeParameters[i].bounds = new TypeReference[super2.length + offset - 1];
                if (super1 != null)
                    method.typeParameters[i].type = makeType(super1, source, false);
                else
                    method.typeParameters[i].type = makeType(super2[0], source, false);
                int ctr = 0;
                for (int j = (super1 == null) ? 1 : 0; j < super2.length; j++) {
                    method.typeParameters[i].bounds[ctr] = makeType(super2[j], source, false);
                    method.typeParameters[i].bounds[ctr++].bits |= ASTNode.IsSuperType;
                }
            }
        }
    }
    if (isDeprecated) {
        method.annotations = new Annotation[] { generateDeprecatedAnnotation(source) };
    }
    method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    if (binding.parameters != null && binding.parameters.length > 0) {
        method.arguments = new Argument[binding.parameters.length];
        call.arguments = new Expression[method.arguments.length];
        for (int i = 0; i < method.arguments.length; i++) {
            AbstractMethodDeclaration sourceElem;
            try {
                sourceElem = pair.base.sourceMethod();
            } catch (Exception e) {
                sourceElem = null;
            }
            char[] argName;
            if (sourceElem == null)
                argName = ("arg" + i).toCharArray();
            else {
                argName = sourceElem.arguments[i].name;
            }
            method.arguments[i] = new Argument(argName, pos(source), makeType(binding.parameters[i], source, false), ClassFileConstants.AccFinal);
            setGeneratedBy(method.arguments[i], source);
            call.arguments[i] = new SingleNameReference(argName, pos(source));
            setGeneratedBy(call.arguments[i], source);
        }
        if (isVarargs) {
            method.arguments[method.arguments.length - 1].type.bits |= ASTNode.IsVarArgs;
        }
    }
    Statement body;
    if (method.returnType instanceof SingleTypeReference && ((SingleTypeReference) method.returnType).token == TypeConstants.VOID) {
        body = call;
    } else {
        body = new ReturnStatement(call, source.sourceStart, source.sourceEnd);
        setGeneratedBy(body, source);
    }
    method.statements = new Statement[] { body };
    return method;
}
Also used : TypeParameter(org.eclipse.jdt.internal.compiler.ast.TypeParameter) Argument(org.eclipse.jdt.internal.compiler.ast.Argument) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) UnresolvedReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) ASTNode(org.eclipse.jdt.internal.compiler.ast.ASTNode) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Example 14 with AbstractMethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration in project lombok by rzwitserloot.

the class PatchDelegate method fillMethodBindingsForMethods.

private static void fillMethodBindingsForMethods(CompilationUnitDeclaration cud, ClassScope scope, List<BindingTuple> methodsToDelegate) {
    TypeDeclaration decl = scope.referenceContext;
    if (decl == null)
        return;
    if (decl.methods != null)
        for (AbstractMethodDeclaration methodDecl : decl.methods) {
            if (methodDecl.annotations == null)
                continue;
            for (Annotation ann : methodDecl.annotations) {
                if (!isDelegate(ann, decl))
                    continue;
                if (Annotation_applied.getAndSet(ann, true))
                    continue;
                if (!(methodDecl instanceof MethodDeclaration)) {
                    EclipseAST eclipseAst = TransformEclipseAST.getAST(cud, true);
                    eclipseAst.get(ann).addError(LEGALITY_OF_DELEGATE);
                    break;
                }
                if (methodDecl.arguments != null) {
                    EclipseAST eclipseAst = TransformEclipseAST.getAST(cud, true);
                    eclipseAst.get(ann).addError(LEGALITY_OF_DELEGATE);
                    break;
                }
                if ((methodDecl.modifiers & ClassFileConstants.AccStatic) != 0) {
                    EclipseAST eclipseAst = TransformEclipseAST.getAST(cud, true);
                    eclipseAst.get(ann).addError(LEGALITY_OF_DELEGATE);
                    break;
                }
                MethodDeclaration method = (MethodDeclaration) methodDecl;
                List<ClassLiteralAccess> rawTypes = rawTypes(ann, "types");
                List<ClassLiteralAccess> excludedRawTypes = rawTypes(ann, "excludes");
                List<BindingTuple> methodsToExclude = new ArrayList<BindingTuple>();
                List<BindingTuple> methodsToDelegateForThisAnn = new ArrayList<BindingTuple>();
                try {
                    for (ClassLiteralAccess cla : excludedRawTypes) {
                        addAllMethodBindings(methodsToExclude, cla.type.resolveType(decl.initializerScope), new HashSet<String>(), method.selector, ann);
                    }
                    Set<String> banList = new HashSet<String>();
                    for (BindingTuple excluded : methodsToExclude) banList.add(printSig(excluded.parameterized));
                    if (rawTypes.isEmpty()) {
                        if (method.returnType == null)
                            continue;
                        addAllMethodBindings(methodsToDelegateForThisAnn, method.returnType.resolveType(decl.initializerScope), banList, method.selector, ann);
                    } else {
                        for (ClassLiteralAccess cla : rawTypes) {
                            addAllMethodBindings(methodsToDelegateForThisAnn, cla.type.resolveType(decl.initializerScope), banList, method.selector, ann);
                        }
                    }
                } catch (DelegateRecursion e) {
                    EclipseAST eclipseAst = TransformEclipseAST.getAST(cud, true);
                    eclipseAst.get(ann).addError(String.format(RECURSION_NOT_ALLOWED, new String(e.member), new String(e.type)));
                    break;
                }
                // Not doing this right now because of problems - see commented-out-method for info.
                // removeExistingMethods(methodsToDelegate, decl, scope);
                String dupe = containsDuplicates(methodsToDelegateForThisAnn);
                if (dupe != null) {
                    EclipseAST eclipseAst = TransformEclipseAST.getAST(cud, true);
                    eclipseAst.get(ann).addError("The method '" + dupe + "' is being delegated by more than one specified type.");
                } else {
                    methodsToDelegate.addAll(methodsToDelegateForThisAnn);
                }
            }
        }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) EclipseAST(lombok.eclipse.EclipseAST) TransformEclipseAST(lombok.eclipse.TransformEclipseAST) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) List(java.util.List) ArrayList(java.util.ArrayList) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) ClassLiteralAccess(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) HashSet(java.util.HashSet)

Example 15 with AbstractMethodDeclaration

use of org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration in project lombok by rzwitserloot.

the class EclipseHandlerUtil method methodExists.

/**
 * Checks if there is a method with the provided name. In case of multiple methods (overloading), only
 * the first method decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
 *
 * @param methodName the method name to check for.
 * @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof.
 * @param caseSensitive If the search should be case sensitive.
 * @param params The number of parameters the method should have; varargs count as 0-*. Set to -1 to find any method with the appropriate name regardless of parameter count.
 */
public static MemberExistsResult methodExists(String methodName, EclipseNode node, boolean caseSensitive, int params) {
    while (node != null && !(node.get() instanceof TypeDeclaration)) {
        node = node.up();
    }
    if (node != null && node.get() instanceof TypeDeclaration) {
        TypeDeclaration typeDecl = (TypeDeclaration) node.get();
        if (typeDecl.methods != null)
            top: for (AbstractMethodDeclaration def : typeDecl.methods) {
                if (def instanceof MethodDeclaration) {
                    char[] mName = def.selector;
                    if (mName == null)
                        continue;
                    boolean nameEquals = caseSensitive ? methodName.equals(new String(mName)) : methodName.equalsIgnoreCase(new String(mName));
                    if (nameEquals) {
                        if (params > -1) {
                            int minArgs = 0;
                            int maxArgs = 0;
                            if (def.arguments != null && def.arguments.length > 0) {
                                minArgs = def.arguments.length;
                                if ((def.arguments[def.arguments.length - 1].type.bits & ASTNode.IsVarArgs) != 0) {
                                    minArgs--;
                                    maxArgs = Integer.MAX_VALUE;
                                } else {
                                    maxArgs = minArgs;
                                }
                            }
                            if (params < minArgs || params > maxArgs)
                                continue;
                        }
                        if (isTolerate(node, def))
                            continue top;
                        return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK;
                    }
                }
            }
    }
    return MemberExistsResult.NOT_EXISTS;
}
Also used : MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Aggregations

AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)20 TypeDeclaration (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)12 MethodDeclaration (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration)11 EclipseNode (lombok.eclipse.EclipseNode)6 FieldDeclaration (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)5 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)5 ArrayList (java.util.ArrayList)4 Argument (org.eclipse.jdt.internal.compiler.ast.Argument)4 ConstructorDeclaration (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration)4 TypeParameter (org.eclipse.jdt.internal.compiler.ast.TypeParameter)4 CompilationUnitDeclaration (org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration)3 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)3 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)3 SingleTypeReference (org.eclipse.jdt.internal.compiler.ast.SingleTypeReference)3 IJavaElement (org.eclipse.jdt.core.IJavaElement)2 ASTNode (org.eclipse.jdt.internal.compiler.ast.ASTNode)2 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)2 AnnotationMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration)2 Clinit (org.eclipse.jdt.internal.compiler.ast.Clinit)2 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)2