Example usage for org.eclipse.jdt.internal.compiler.ast TypeParameter TypeParameter

List of usage examples for org.eclipse.jdt.internal.compiler.ast TypeParameter TypeParameter

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.ast TypeParameter TypeParameter.

Prototype

TypeParameter

Source Link

Usage

From source file:lombok.eclipse.agent.PatchDelegate.java

License:Open Source License

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);
     *  }//from   w w w.j  av  a2 s  .  c om
     */

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

From source file:lombok.eclipse.handlers.ast.EclipseASTMaker.java

License:Open Source License

@Override
public ASTNode visitTypeParam(final lombok.ast.TypeParam node, final Void p) {
    final TypeParameter typeParameter = new TypeParameter();
    typeParameter.name = node.getName().toCharArray();
    final List<lombok.ast.TypeRef> bounds = new ArrayList<lombok.ast.TypeRef>(node.getBounds());
    if (!bounds.isEmpty()) {
        typeParameter.type = build(bounds.get(0));
        bounds.remove(0);//from www . j a v a  2s  .c  o  m
        typeParameter.bounds = toArray(build(bounds), new TypeReference[0]);
    }
    setGeneratedByAndCopyPos(typeParameter, source, posHintOf(node));
    return typeParameter;
}

From source file:lombok.eclipse.handlers.EclipseHandlerUtil.java

License:Open Source License

/**
 * You can't share TypeParameter objects or bad things happen; for example, one 'T' resolves differently
 * from another 'T', even for the same T in a single class file. Unfortunately the TypeParameter type hierarchy
 * is complicated and there's no clone method on TypeParameter itself. This method can clone them.
 *///from  w w  w . j  av a  2 s. c  o m
public static TypeParameter[] copyTypeParams(TypeParameter[] params, ASTNode source) {
    if (params == null)
        return null;
    TypeParameter[] out = new TypeParameter[params.length];
    int idx = 0;
    for (TypeParameter param : params) {
        TypeParameter o = new TypeParameter();
        setGeneratedBy(o, source);
        o.annotations = param.annotations;
        o.bits = param.bits;
        o.modifiers = param.modifiers;
        o.name = param.name;
        o.type = copyType(param.type, source);
        o.sourceStart = param.sourceStart;
        o.sourceEnd = param.sourceEnd;
        o.declarationEnd = param.declarationEnd;
        o.declarationSourceStart = param.declarationSourceStart;
        o.declarationSourceEnd = param.declarationSourceEnd;
        if (param.bounds != null) {
            TypeReference[] b = new TypeReference[param.bounds.length];
            int idx2 = 0;
            for (TypeReference ref : param.bounds)
                b[idx2++] = copyType(ref, source);
            o.bounds = b;
        }
        out[idx++] = o;
    }
    return out;
}

From source file:lombok.eclipse.handlers.HandleBuilder.java

License:Open Source License

@Override
public void handle(AnnotationValues<Builder> annotation, Annotation ast, EclipseNode annotationNode) {
    long p = (long) ast.sourceStart << 32 | ast.sourceEnd;

    Builder builderInstance = annotation.getInstance();

    // These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
    boolean fluent = toBoolean(annotation.getActualExpression("fluent"), true);
    boolean chain = toBoolean(annotation.getActualExpression("chain"), true);

    String builderMethodName = builderInstance.builderMethodName();
    String buildMethodName = builderInstance.buildMethodName();
    String builderClassName = builderInstance.builderClassName();
    String toBuilderMethodName = "toBuilder";
    boolean toBuilder = builderInstance.toBuilder();
    List<char[]> typeArgsForToBuilder = null;

    if (builderMethodName == null)
        builderMethodName = "builder";
    if (buildMethodName == null)
        builderMethodName = "build";
    if (builderClassName == null)
        builderClassName = "";

    if (!checkName("builderMethodName", builderMethodName, annotationNode))
        return;/*from  w w  w  . ja  va2s.c  o m*/
    if (!checkName("buildMethodName", buildMethodName, annotationNode))
        return;
    if (!builderClassName.isEmpty()) {
        if (!checkName("builderClassName", builderClassName, annotationNode))
            return;
    }

    EclipseNode parent = annotationNode.up();

    List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
    TypeReference returnType;
    TypeParameter[] typeParams;
    TypeReference[] thrownExceptions;
    char[] nameOfStaticBuilderMethod;
    EclipseNode tdParent;

    EclipseNode fillParametersFrom = parent.get() instanceof AbstractMethodDeclaration ? parent : null;
    boolean addCleaning = false;

    if (parent.get() instanceof TypeDeclaration) {
        tdParent = parent;
        TypeDeclaration td = (TypeDeclaration) tdParent.get();

        List<EclipseNode> allFields = new ArrayList<EclipseNode>();
        @SuppressWarnings("deprecation")
        boolean valuePresent = (hasAnnotation(lombok.Value.class, parent)
                || hasAnnotation(lombok.experimental.Value.class, parent));
        for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent)) {
            FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
            // final fields with an initializer cannot be written to, so they can't be 'builderized'. Unfortunately presence of @Value makes
            // non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves.
            // Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that.
            if (fd.initialization != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode))
                continue;
            BuilderFieldData bfd = new BuilderFieldData();
            bfd.rawName = fieldNode.getName().toCharArray();
            bfd.name = removePrefixFromField(fieldNode);
            bfd.type = fd.type;
            bfd.singularData = getSingularData(fieldNode, ast);
            addObtainVia(bfd, fieldNode);
            builderFields.add(bfd);
            allFields.add(fieldNode);
        }

        new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null,
                SkipIfConstructorExists.I_AM_BUILDER, null, Collections.<Annotation>emptyList(),
                annotationNode);

        returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p);
        typeParams = td.typeParameters;
        thrownExceptions = null;
        nameOfStaticBuilderMethod = null;
        if (builderClassName.isEmpty())
            builderClassName = new String(td.name) + "Builder";
    } else if (parent.get() instanceof ConstructorDeclaration) {
        ConstructorDeclaration cd = (ConstructorDeclaration) parent.get();
        if (cd.typeParameters != null && cd.typeParameters.length > 0) {
            annotationNode
                    .addError("@Builder is not supported on constructors with constructor type parameters.");
            return;
        }

        tdParent = parent.up();
        TypeDeclaration td = (TypeDeclaration) tdParent.get();
        returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p);
        typeParams = td.typeParameters;
        thrownExceptions = cd.thrownExceptions;
        nameOfStaticBuilderMethod = null;
        if (builderClassName.isEmpty())
            builderClassName = new String(cd.selector) + "Builder";
    } else if (parent.get() instanceof MethodDeclaration) {
        MethodDeclaration md = (MethodDeclaration) parent.get();
        tdParent = parent.up();
        if (!md.isStatic()) {
            annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
            return;
        }

        if (toBuilder) {
            final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
            char[] token;
            char[][] pkg = null;
            if (md.returnType.dimensions() > 0) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            if (md.returnType instanceof SingleTypeReference) {
                token = ((SingleTypeReference) md.returnType).token;
            } else if (md.returnType instanceof QualifiedTypeReference) {
                pkg = ((QualifiedTypeReference) md.returnType).tokens;
                token = pkg[pkg.length];
                char[][] pkg_ = new char[pkg.length - 1][];
                System.arraycopy(pkg, 0, pkg_, 0, pkg_.length);
                pkg = pkg_;
            } else {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            if (pkg != null && !equals(parent.getPackageDeclaration(), pkg)) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            if (tdParent == null || !equals(tdParent.getName(), token)) {
                annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
                return;
            }

            TypeParameter[] tpOnType = ((TypeDeclaration) tdParent.get()).typeParameters;
            TypeParameter[] tpOnMethod = md.typeParameters;
            TypeReference[][] tpOnRet_ = null;
            if (md.returnType instanceof ParameterizedSingleTypeReference) {
                tpOnRet_ = new TypeReference[1][];
                tpOnRet_[0] = ((ParameterizedSingleTypeReference) md.returnType).typeArguments;
            } else if (md.returnType instanceof ParameterizedQualifiedTypeReference) {
                tpOnRet_ = ((ParameterizedQualifiedTypeReference) md.returnType).typeArguments;
            }

            if (tpOnRet_ != null)
                for (int i = 0; i < tpOnRet_.length - 1; i++) {
                    if (tpOnRet_[i] != null && tpOnRet_[i].length > 0) {
                        annotationNode.addError(
                                "@Builder(toBuilder=true) is not supported if returning a type with generics applied to an intermediate.");
                        return;
                    }
                }
            TypeReference[] tpOnRet = tpOnRet_ == null ? null : tpOnRet_[tpOnRet_.length - 1];
            typeArgsForToBuilder = new ArrayList<char[]>();

            // Every typearg on this method needs to be found in the return type, but the reverse is not true.
            // We also need to 'map' them.

            if (tpOnMethod != null)
                for (TypeParameter onMethod : tpOnMethod) {
                    int pos = -1;
                    if (tpOnRet != null)
                        for (int i = 0; i < tpOnRet.length; i++) {
                            if (tpOnRet[i].getClass() != SingleTypeReference.class)
                                continue;
                            if (!Arrays.equals(((SingleTypeReference) tpOnRet[i]).token, onMethod.name))
                                continue;
                            pos = i;
                        }
                    if (pos == -1 || tpOnType == null || tpOnType.length <= pos) {
                        annotationNode.addError(
                                "@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter "
                                        + new String(onMethod.name) + " is not part of the return type.");
                        return;
                    }

                    typeArgsForToBuilder.add(tpOnType[pos].name);
                }
        }

        returnType = copyType(md.returnType, ast);
        typeParams = md.typeParameters;
        thrownExceptions = md.thrownExceptions;
        nameOfStaticBuilderMethod = md.selector;
        if (builderClassName.isEmpty()) {
            char[] token;
            if (md.returnType instanceof QualifiedTypeReference) {
                char[][] tokens = ((QualifiedTypeReference) md.returnType).tokens;
                token = tokens[tokens.length - 1];
            } else if (md.returnType instanceof SingleTypeReference) {
                token = ((SingleTypeReference) md.returnType).token;
                if (!(md.returnType instanceof ParameterizedSingleTypeReference) && typeParams != null) {
                    for (TypeParameter tp : typeParams) {
                        if (Arrays.equals(tp.name, token)) {
                            annotationNode.addError(
                                    "@Builder requires specifying 'builderClassName' if used on methods with a type parameter as return type.");
                            return;
                        }
                    }
                }
            } else {
                annotationNode.addError(
                        "Unexpected kind of return type on annotated method. Specify 'builderClassName' to solve this problem.");
                return;
            }

            if (Character.isLowerCase(token[0])) {
                char[] newToken = new char[token.length];
                System.arraycopy(token, 1, newToken, 1, token.length - 1);
                newToken[0] = Character.toTitleCase(token[0]);
                token = newToken;
            }

            builderClassName = new String(token) + "Builder";
        }
    } else {
        annotationNode.addError("@Builder is only supported on types, constructors, and static methods.");
        return;
    }

    if (fillParametersFrom != null) {
        for (EclipseNode param : fillParametersFrom.down()) {
            if (param.getKind() != Kind.ARGUMENT)
                continue;
            BuilderFieldData bfd = new BuilderFieldData();
            Argument arg = (Argument) param.get();
            bfd.rawName = arg.name;
            bfd.name = arg.name;
            bfd.type = arg.type;
            bfd.singularData = getSingularData(param, ast);
            addObtainVia(bfd, param);
            builderFields.add(bfd);
        }
    }

    EclipseNode builderType = findInnerClass(tdParent, builderClassName);
    if (builderType == null) {
        builderType = makeBuilderClass(tdParent, builderClassName, typeParams, ast);
    } else {
        sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
        /* generate errors for @Singular BFDs that have one already defined node. */ {
            for (BuilderFieldData bfd : builderFields) {
                SingularData sd = bfd.singularData;
                if (sd == null)
                    continue;
                EclipseSingularizer singularizer = sd.getSingularizer();
                if (singularizer == null)
                    continue;
                if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
                    bfd.singularData = null;
                }
            }
        }
    }

    for (BuilderFieldData bfd : builderFields) {
        if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
            if (bfd.singularData.getSingularizer().requiresCleaning()) {
                addCleaning = true;
                break;
            }
        }
        if (bfd.obtainVia != null) {
            if (bfd.obtainVia.field().isEmpty() == bfd.obtainVia.method().isEmpty()) {
                bfd.obtainViaNode.addError(
                        "The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\").");
                return;
            }
            if (bfd.obtainVia.method().isEmpty() && bfd.obtainVia.isStatic()) {
                bfd.obtainViaNode
                        .addError("@ObtainVia(isStatic = true) is not valid unless 'method' has been set.");
                return;
            }
        }
    }

    generateBuilderFields(builderType, builderFields, ast);
    if (addCleaning) {
        FieldDeclaration cleanDecl = new FieldDeclaration(CLEAN_FIELD_NAME, 0, -1);
        cleanDecl.declarationSourceEnd = -1;
        cleanDecl.modifiers = ClassFileConstants.AccPrivate;
        cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
        injectFieldAndMarkGenerated(builderType, cleanDecl);
    }

    if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) {
        ConstructorDeclaration cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, builderType,
                Collections.<EclipseNode>emptyList(), false, null, annotationNode,
                Collections.<Annotation>emptyList());
        if (cd != null)
            injectMethod(builderType, cd);
    }

    for (BuilderFieldData bfd : builderFields) {
        makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
    }

    if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
        MethodDeclaration md = generateBuildMethod(buildMethodName, nameOfStaticBuilderMethod, returnType,
                builderFields, builderType, thrownExceptions, addCleaning, ast);
        if (md != null)
            injectMethod(builderType, md);
    }

    if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
        List<EclipseNode> fieldNodes = new ArrayList<EclipseNode>();
        for (BuilderFieldData bfd : builderFields) {
            fieldNodes.addAll(bfd.createdFields);
        }
        MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true, false, ast,
                FieldAccess.ALWAYS_FIELD);
        if (md != null)
            injectMethod(builderType, md);
    }

    if (addCleaning) {
        MethodDeclaration cleanMethod = generateCleanMethod(builderFields, builderType, ast);
        if (cleanMethod != null)
            injectMethod(builderType, cleanMethod);
    }

    if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
        MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, tdParent, typeParams,
                ast);
        if (md != null)
            injectMethod(tdParent, md);
    }

    if (toBuilder)
        switch (methodExists(toBuilderMethodName, tdParent, 0)) {
        case EXISTS_BY_USER:
            annotationNode.addWarning("Not generating toBuilder() as it already exists.");
            break;
        case NOT_EXISTS:
            TypeParameter[] tps = typeParams;
            if (typeArgsForToBuilder != null) {
                tps = new TypeParameter[typeArgsForToBuilder.size()];
                for (int i = 0; i < tps.length; i++) {
                    tps[i] = new TypeParameter();
                    tps[i].name = typeArgsForToBuilder.get(i);
                }
            }
            MethodDeclaration md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps,
                    builderFields, fluent, ast);

            if (md != null)
                injectMethod(tdParent, md);
        }
}

From source file:lombok.eclipse.handlers.HandleSuperBuilder.java

License:Open Source License

private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass,
        TypeReference superclassBuilderClass, TypeParameter[] typeParams, ASTNode source,
        String classGenericName, String builderGenericName) {

    TypeDeclaration parent = (TypeDeclaration) tdParent.get();
    TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
    builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
    builder.modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccStatic
            | ClassFileConstants.AccAbstract;
    builder.name = builderClass.toCharArray();

    // Keep any type params of the annotated class.
    builder.typeParameters = Arrays.copyOf(copyTypeParams(typeParams, source), typeParams.length + 2);
    // Add builder-specific type params required for inheritable builders.
    // 1. The return type for the build() method, named "C", which extends the annotated class.
    TypeParameter o = new TypeParameter();
    o.name = classGenericName.toCharArray();
    o.type = cloneSelfType(tdParent, source);
    builder.typeParameters[builder.typeParameters.length - 2] = o;
    // 2. The return type for all setter methods, named "B", which extends this builder class.
    o = new TypeParameter();
    o.name = builderGenericName.toCharArray();
    TypeReference[] typerefs = appendBuilderTypeReferences(typeParams, classGenericName, builderGenericName);
    o.type = new ParameterizedSingleTypeReference(builderClass.toCharArray(), typerefs, 0, 0);
    builder.typeParameters[builder.typeParameters.length - 1] = o;

    builder.superclass = copyType(superclassBuilderClass, source);

    builder.createDefaultConstructor(false, true);

    builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
    return injectType(tdParent, builder);
}

From source file:org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.java

License:Open Source License

/**
 * Build JDT TypeDeclarations for the groovy type declarations that were parsed from the source file.
 *//* ww w. j a  v a  2 s  .  co m*/
private void createTypeDeclarations(ModuleNode moduleNode) {
    List<ClassNode> moduleClassNodes = moduleNode.getClasses();
    List<TypeDeclaration> typeDeclarations = new ArrayList<TypeDeclaration>();
    Map<ClassNode, TypeDeclaration> fromClassNodeToDecl = new HashMap<ClassNode, TypeDeclaration>();

    char[] mainName = toMainName(compilationResult.getFileName());
    boolean isInner = false;
    List<ClassNode> classNodes = null;
    classNodes = moduleClassNodes;
    Map<ClassNode, List<TypeDeclaration>> innersToRecord = new HashMap<ClassNode, List<TypeDeclaration>>();
    for (ClassNode classNode : classNodes) {
        if (!classNode.isPrimaryClassNode()) {
            continue;
        }

        GroovyTypeDeclaration typeDeclaration = new GroovyTypeDeclaration(compilationResult, classNode);

        typeDeclaration.annotations = transformAnnotations(classNode.getAnnotations());
        // FIXASC duplicates code further down, tidy this up
        if (classNode instanceof InnerClassNode) {
            InnerClassNode innerClassNode = (InnerClassNode) classNode;
            ClassNode outerClass = innerClassNode.getOuterClass();
            String outername = outerClass.getNameWithoutPackage();
            String newInner = innerClassNode.getNameWithoutPackage().substring(outername.length() + 1);
            typeDeclaration.name = newInner.toCharArray();
            isInner = true;
        } else {
            typeDeclaration.name = classNode.getNameWithoutPackage().toCharArray();
            isInner = false;
        }

        // classNode.getInnerClasses();
        // classNode.
        boolean isInterface = classNode.isInterface();
        int mods = classNode.getModifiers();
        if ((mods & Opcodes.ACC_ENUM) != 0) {
            // remove final
            mods = mods & ~Opcodes.ACC_FINAL;
        }
        // FIXASC should this modifier be set?
        // mods |= Opcodes.ACC_PUBLIC;
        // FIXASC should not do this for inner classes, just for top level types
        // FIXASC does this make things visible that shouldn't be?
        mods = mods & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
        if (!isInner) {
            if ((mods & Opcodes.ACC_STATIC) != 0) {
                mods = mods & ~(Opcodes.ACC_STATIC);
            }
        }
        typeDeclaration.modifiers = mods & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0);

        if (!(classNode instanceof InnerClassNode)) {
            if (!CharOperation.equals(typeDeclaration.name, mainName)) {
                typeDeclaration.bits |= ASTNode.IsSecondaryType;
            }
        }

        fixupSourceLocationsForTypeDeclaration(typeDeclaration, classNode);

        if (classNode.getGenericsTypes() != null) {
            GenericsType[] genericInfo = classNode.getGenericsTypes();
            // Example case here: Foo<T extends Number & I>
            // the type parameter is T, the 'type' is Number and the bounds for the type parameter are just the extra bound
            // I.
            typeDeclaration.typeParameters = new TypeParameter[genericInfo.length];
            for (int tp = 0; tp < genericInfo.length; tp++) {
                TypeParameter typeParameter = new TypeParameter();
                typeParameter.name = genericInfo[tp].getName().toCharArray();
                ClassNode[] upperBounds = genericInfo[tp].getUpperBounds();
                if (upperBounds != null) {
                    // FIXASC (M3) Positional info for these references?
                    typeParameter.type = createTypeReferenceForClassNode(upperBounds[0]);
                    typeParameter.bounds = (upperBounds.length > 1 ? new TypeReference[upperBounds.length - 1]
                            : null);
                    for (int b = 1, max = upperBounds.length; b < max; b++) {
                        typeParameter.bounds[b - 1] = createTypeReferenceForClassNode(upperBounds[b]);
                        typeParameter.bounds[b - 1].bits |= ASTNode.IsSuperType;
                    }
                }
                typeDeclaration.typeParameters[tp] = typeParameter;
            }
        }

        boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0;
        configureSuperClass(typeDeclaration, classNode.getSuperClass(), isEnum);
        configureSuperInterfaces(typeDeclaration, classNode);
        typeDeclaration.methods = createMethodAndConstructorDeclarations(classNode, isEnum, compilationResult);
        typeDeclaration.fields = createFieldDeclarations(classNode);
        typeDeclaration.properties = classNode.getProperties();
        if (classNode instanceof InnerClassNode) {
            InnerClassNode innerClassNode = (InnerClassNode) classNode;
            ClassNode outerClass = innerClassNode.getOuterClass();
            String outername = outerClass.getNameWithoutPackage();
            String newInner = innerClassNode.getNameWithoutPackage().substring(outername.length() + 1);
            typeDeclaration.name = newInner.toCharArray();

            // Record that we need to set the parent of this inner type later
            List<TypeDeclaration> inners = innersToRecord.get(outerClass);
            if (inners == null) {
                inners = new ArrayList<TypeDeclaration>();
                innersToRecord.put(outerClass, inners);
            }
            inners.add(typeDeclaration);
        } else {
            typeDeclarations.add(typeDeclaration);
        }
        fromClassNodeToDecl.put(classNode, typeDeclaration);
    }

    // For inner types, now attach them to their parents. This was not done earlier as sometimes the types are processed in
    // such an order that inners are dealt with before outers
    for (Map.Entry<ClassNode, List<TypeDeclaration>> innersToRecordEntry : innersToRecord.entrySet()) {
        TypeDeclaration outerTypeDeclaration = fromClassNodeToDecl.get(innersToRecordEntry.getKey());
        // Check if there is a problem locating the parent for the inner
        if (outerTypeDeclaration == null) {
            throw new GroovyEclipseBug(
                    "Failed to find the type declaration for " + innersToRecordEntry.getKey().getName());
        }
        List<TypeDeclaration> newInnersList = innersToRecordEntry.getValue();
        outerTypeDeclaration.memberTypes = newInnersList.toArray(new TypeDeclaration[newInnersList.size()]);
    }

    types = typeDeclarations.toArray(new TypeDeclaration[typeDeclarations.size()]);
}

From source file:org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.java

License:Open Source License

/**
 * Create a JDT MethodDeclaration that represents a groovy MethodNode
 *//*from  w w  w  .  ja va  2 s  . c  om*/
private MethodDeclaration createMethodDeclaration(ClassNode classNode, MethodNode methodNode, boolean isEnum,
        CompilationResult compilationResult) {
    if (classNode.isAnnotationDefinition()) {
        AnnotationMethodDeclaration methodDeclaration = new AnnotationMethodDeclaration(compilationResult);
        int modifiers = methodNode.getModifiers();
        modifiers &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccTransient);
        methodDeclaration.annotations = transformAnnotations(methodNode.getAnnotations());
        methodDeclaration.modifiers = modifiers;
        if (methodNode.hasAnnotationDefault()) {
            methodDeclaration.modifiers |= ClassFileConstants.AccAnnotationDefault;
        }
        methodDeclaration.selector = methodNode.getName().toCharArray();
        fixupSourceLocationsForMethodDeclaration(methodDeclaration, methodNode);
        ClassNode returnType = methodNode.getReturnType();
        methodDeclaration.returnType = createTypeReferenceForClassNode(returnType);
        return methodDeclaration;
    } else {
        MethodDeclaration methodDeclaration = new MethodDeclaration(compilationResult);

        // TODO refactor - extract method
        GenericsType[] generics = methodNode.getGenericsTypes();
        // generic method
        if (generics != null && generics.length != 0) {
            methodDeclaration.typeParameters = new TypeParameter[generics.length];
            for (int tp = 0; tp < generics.length; tp++) {
                TypeParameter typeParameter = new TypeParameter();
                typeParameter.name = generics[tp].getName().toCharArray();
                ClassNode[] upperBounds = generics[tp].getUpperBounds();
                if (upperBounds != null) {
                    // FIXASC Positional info for these references?
                    typeParameter.type = createTypeReferenceForClassNode(upperBounds[0]);
                    typeParameter.bounds = (upperBounds.length > 1 ? new TypeReference[upperBounds.length - 1]
                            : null);
                    for (int b = 1, max = upperBounds.length; b < max; b++) {
                        typeParameter.bounds[b - 1] = createTypeReferenceForClassNode(upperBounds[b]);
                        typeParameter.bounds[b - 1].bits |= ASTNode.IsSuperType;
                    }
                }
                methodDeclaration.typeParameters[tp] = typeParameter;
            }
        }

        boolean isMain = false;
        // Note: modifiers for the MethodBinding constructed for this declaration will be created marked with
        // AccVarArgs if the bitset for the type reference in the final argument is marked IsVarArgs
        int modifiers = methodNode.getModifiers();
        modifiers &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccTransient);
        methodDeclaration.annotations = transformAnnotations(methodNode.getAnnotations());
        methodDeclaration.modifiers = modifiers;
        methodDeclaration.selector = methodNode.getName().toCharArray();
        // Need to capture the rule in Verifier.adjustTypesIfStaticMainMethod(MethodNode node)
        // if (node.getName().equals("main") && node.isStatic()) {
        // Parameter[] params = node.getParameters();
        // if (params.length == 1) {
        // Parameter param = params[0];
        // if (param.getType() == null || param.getType()==ClassHelper.OBJECT_TYPE) {
        // param.setType(ClassHelper.STRING_TYPE.makeArray());
        // ClassNode returnType = node.getReturnType();
        // if(returnType == ClassHelper.OBJECT_TYPE) {
        // node.setReturnType(ClassHelper.VOID_TYPE);
        // }
        // }
        // }
        Parameter[] params = methodNode.getParameters();
        ClassNode returnType = methodNode.getReturnType();

        // source of 'static main(args)' would become 'static Object main(Object args)' - so transform here
        if ((modifiers & ClassFileConstants.AccStatic) != 0 && params != null && params.length == 1
                && methodNode.getName().equals("main")) {
            Parameter p = params[0];
            if (p.getType() == null || p.getType().getName().equals(ClassHelper.OBJECT)) {
                String name = p.getName();
                params = new Parameter[1];
                params[0] = new Parameter(ClassHelper.STRING_TYPE.makeArray(), name);
                if (returnType.getName().equals(ClassHelper.OBJECT)) {
                    returnType = ClassHelper.VOID_TYPE;
                }
            }
        }

        methodDeclaration.arguments = createArguments(params, isMain);
        methodDeclaration.returnType = createTypeReferenceForClassNode(returnType);
        methodDeclaration.thrownExceptions = createTypeReferencesForClassNodes(methodNode.getExceptions());
        fixupSourceLocationsForMethodDeclaration(methodDeclaration, methodNode);
        return methodDeclaration;
    }
}

From source file:org.eclipse.ajdt.core.parserbridge.ITDInserter.java

License:Open Source License

/**
 * @param typeParameters//from  w ww . j  av a 2 s . co m
 * @return
 */
private TypeParameter[] createTypeParameters(
        org.eclipse.ajdt.core.model.AJWorldFacade.TypeParameter[] typeParameters) {
    if (typeParameters == null || typeParameters.length == 0) {
        return null;
    }
    TypeParameter[] newTypeParameters = new TypeParameter[typeParameters.length];
    for (int i = 0; i < typeParameters.length; i++) {
        newTypeParameters[i] = new TypeParameter();
        newTypeParameters[i].name = typeParameters[i].name.toCharArray();
        if (typeParameters[i].upperBoundTypeName != null) {
            newTypeParameters[i].bounds = new TypeReference[1];
            newTypeParameters[i].bounds[0] = createTypeReference(typeParameters[i].upperBoundTypeName);
        }
    }
    return newTypeParameters;
}

From source file:org.eclipse.jdt.internal.compiler.parser.Parser.java

License:Open Source License

protected void consumeTypeParameterHeader() {
    //TypeParameterHeader ::= Identifier
    TypeParameter typeParameter = new TypeParameter();
    long pos = this.identifierPositionStack[this.identifierPtr];
    final int end = (int) pos;
    typeParameter.declarationSourceEnd = end;
    typeParameter.sourceEnd = end;/* ww  w  .  j  a v  a  2 s .  c  om*/
    final int start = (int) (pos >>> 32);
    typeParameter.declarationSourceStart = start;
    typeParameter.sourceStart = start;
    typeParameter.name = this.identifierStack[this.identifierPtr--];
    this.identifierLengthPtr--;
    pushOnGenericsStack(typeParameter);

    this.listTypeParameterLength++;
}

From source file:org.eclipse.objectteams.otdt.internal.core.compiler.util.AstClone.java

License:Open Source License

public static TypeParameter[] copyTypeParameters(TypeParameter[] typeParameters) {
    if (typeParameters == null)
        return null;
    int len = typeParameters.length;
    TypeParameter[] result = new TypeParameter[len];
    for (int i = 0; i < len; i++) {
        if (typeParameters[i] instanceof TypeValueParameter) {
            long poss = ((long) typeParameters[i].sourceStart) << 32 + (long) typeParameters[i].sourceEnd;
            result[i] = new TypeValueParameter(typeParameters[i].name, poss);
            result[i].declarationSourceStart = typeParameters[i].declarationSourceStart;
        } else {/*w w  w  .ja v a 2 s  . c  o  m*/
            result[i] = new TypeParameter();
            result[i].bounds = copyTypeArray(typeParameters[i].bounds);
            result[i].bits = typeParameters[i].bits;
            result[i].declarationSourceStart = typeParameters[i].declarationSourceStart;
            result[i].declarationSourceEnd = typeParameters[i].declarationSourceEnd;
            result[i].sourceStart = typeParameters[i].sourceStart;
            result[i].sourceEnd = typeParameters[i].sourceEnd;
            result[i].declarationEnd = typeParameters[i].declarationEnd;
            result[i].name = typeParameters[i].name;
            result[i].type = copyTypeReference(typeParameters[i].type);
        }
    }
    return result;
}