Example usage for org.eclipse.jdt.internal.compiler.ast Wildcard UNBOUND

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

Introduction

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

Prototype

int UNBOUND

To view the source code for org.eclipse.jdt.internal.compiler.ast Wildcard UNBOUND.

Click Source Link

Usage

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

License:Open Source License

protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments,
        boolean hasTypeParameters) {
    // Only possible if locator has an unit scope.
    if (locator.unitScope == null)
        return;//from  ww w .j a v a 2 s  .  co m

    // First compare lengthes
    int patternTypeArgsLength = patternArguments == null ? 0 : patternArguments.length;
    int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length;

    // Initialize match rule
    int matchRule = this.match.getRule();
    if (this.match.isRaw()) {
        if (patternTypeArgsLength != 0) {
            matchRule &= ~SearchPattern.R_FULL_MATCH;
        }
    }
    if (hasTypeParameters) {
        matchRule = SearchPattern.R_ERASURE_MATCH;
    }

    // Compare arguments lengthes
    if (patternTypeArgsLength == typeArgumentsLength) {
        if (!this.match.isRaw() && hasTypeParameters) {
            // generic patterns are always not compatible match
            this.match.setRule(SearchPattern.R_ERASURE_MATCH);
            return;
        }
    } else {
        if (patternTypeArgsLength == 0) {
            if (!this.match.isRaw() || hasTypeParameters) {
                this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
            }
        } else if (typeArgumentsLength == 0) {
            // raw binding is always compatible
            this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
        } else {
            this.match.setRule(0); // impossible match
        }
        return;
    }
    if (argumentsBinding == null || patternArguments == null) {
        this.match.setRule(matchRule);
        return;
    }

    // Compare binding for each type argument only if pattern is not erasure only and at first level
    if (!hasTypeParameters && !this.match.isRaw() && (this.match.isEquivalent() || this.match.isExact())) {
        for (int i = 0; i < typeArgumentsLength; i++) {
            // Get parameterized type argument binding
            TypeBinding argumentBinding = argumentsBinding[i];
            if (argumentBinding instanceof CaptureBinding) {
                WildcardBinding capturedWildcard = ((CaptureBinding) argumentBinding).wildcard;
                if (capturedWildcard != null)
                    argumentBinding = capturedWildcard;
            }
            // Get binding for pattern argument
            char[] patternTypeArgument = patternArguments[i];
            char patternWildcard = patternTypeArgument[0];
            char[] patternTypeName = patternTypeArgument;
            int patternWildcardKind = -1;
            switch (patternWildcard) {
            case Signature.C_STAR:
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    if (wildcardBinding.boundKind == Wildcard.UNBOUND)
                        continue;
                }
                matchRule &= ~SearchPattern.R_FULL_MATCH;
                continue; // unbound parameter always match
            case Signature.C_EXTENDS:
                patternWildcardKind = Wildcard.EXTENDS;
                patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
                break;
            case Signature.C_SUPER:
                patternWildcardKind = Wildcard.SUPER;
                patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
                break;
            default:
                break;
            }
            patternTypeName = Signature.toCharArray(patternTypeName);
            TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName);

            // If have no binding for pattern arg, then we won't be able to refine accuracy
            if (patternBinding == null) {
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    if (wildcardBinding.boundKind == Wildcard.UNBOUND) {
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                    } else {
                        this.match.setRule(SearchPattern.R_ERASURE_MATCH);
                        return;
                    }
                }
                continue;
            }

            // Verify tha pattern binding is compatible with match type argument binding
            switch (patternWildcard) {
            case Signature.C_STAR: // UNBOUND pattern
                // unbound always match => skip to next argument
                matchRule &= ~SearchPattern.R_FULL_MATCH;
                continue;
            case Signature.C_EXTENDS: // EXTENDS pattern
                if (argumentBinding.isWildcard()) { // argument is a wildcard
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    // It's ok if wildcards are identical
                    if (wildcardBinding.boundKind == patternWildcardKind
                            && wildcardBinding.bound == patternBinding) {
                        continue;
                    }
                    // Look for wildcard compatibility
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        if (wildcardBinding.bound == null
                                || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
                            // valid when arg extends a subclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.SUPER:
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (argumentBinding.isCompatibleWith(patternBinding)) {
                    // valid when arg is a subclass of pattern
                    matchRule &= ~SearchPattern.R_FULL_MATCH;
                    continue;
                }
                break;
            case Signature.C_SUPER: // SUPER pattern
                if (argumentBinding.isWildcard()) { // argument is a wildcard
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    // It's ok if wildcards are identical
                    if (wildcardBinding.boundKind == patternWildcardKind
                            && wildcardBinding.bound == patternBinding) {
                        continue;
                    }
                    // Look for wildcard compatibility
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        break;
                    case Wildcard.SUPER:
                        if (wildcardBinding.bound == null
                                || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
                            // valid only when arg super a superclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (patternBinding.isCompatibleWith(argumentBinding)) {
                    // valid only when arg is a superclass of pattern
                    matchRule &= ~SearchPattern.R_FULL_MATCH;
                    continue;
                }
                break;
            default:
                if (argumentBinding.isWildcard()) {
                    WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
                    switch (wildcardBinding.boundKind) {
                    case Wildcard.EXTENDS:
                        if (wildcardBinding.bound == null
                                || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
                            // valid only when arg extends a superclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.SUPER:
                        if (wildcardBinding.bound == null
                                || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
                            // valid only when arg super a subclass of pattern
                            matchRule &= ~SearchPattern.R_FULL_MATCH;
                            continue;
                        }
                        break;
                    case Wildcard.UNBOUND:
                        matchRule &= ~SearchPattern.R_FULL_MATCH;
                        continue;
                    }
                } else if (argumentBinding == patternBinding)
                    // valid only when arg is equals to pattern
                    continue;
                break;
            }

            // Argument does not match => erasure match will be the only possible one
            this.match.setRule(SearchPattern.R_ERASURE_MATCH);
            return;
        }
    }

    // Set match rule
    this.match.setRule(matchRule);
}

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;
    }//w  w w  .ja v  a 2s . 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:lombok.eclipse.handlers.ast.EclipseASTMaker.java

License:Open Source License

@Override
public ASTNode visitWildcard(final lombok.ast.Wildcard node, final Void p) {
    int kind = Wildcard.UNBOUND;
    if (node.getBound() != null) {
        switch (node.getBound()) {
        case SUPER:
            kind = Wildcard.SUPER;//from   w ww.  j av  a  2  s  . c  om
            break;
        default:
        case EXTENDS:
            kind = Wildcard.EXTENDS;
        }
    }
    final Wildcard wildcard = new Wildcard(kind);
    setGeneratedByAndCopyPos(wildcard, source, posHintOf(node));
    wildcard.bound = build(node.getType());
    return wildcard;
}

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

License:Open Source License

public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) {
    int dims = binding.dimensions();
    binding = binding.leafComponentType();

    // Primitives

    char[] base = null;

    switch (binding.id) {
    case TypeIds.T_int:
        base = TypeConstants.INT;/*  w  ww.j a va  2s . c o m*/
        break;
    case TypeIds.T_long:
        base = TypeConstants.LONG;
        break;
    case TypeIds.T_short:
        base = TypeConstants.SHORT;
        break;
    case TypeIds.T_byte:
        base = TypeConstants.BYTE;
        break;
    case TypeIds.T_double:
        base = TypeConstants.DOUBLE;
        break;
    case TypeIds.T_float:
        base = TypeConstants.FLOAT;
        break;
    case TypeIds.T_boolean:
        base = TypeConstants.BOOLEAN;
        break;
    case TypeIds.T_char:
        base = TypeConstants.CHAR;
        break;
    case TypeIds.T_void:
        base = TypeConstants.VOID;
        break;
    case TypeIds.T_null:
        return null;
    }

    if (base != null) {
        if (dims > 0) {
            TypeReference result = new ArrayTypeReference(base, dims, pos(pos));
            setGeneratedBy(result, pos);
            return result;
        }
        TypeReference result = new SingleTypeReference(base, pos(pos));
        setGeneratedBy(result, pos);
        return result;
    }

    if (binding.isAnonymousType()) {
        ReferenceBinding ref = (ReferenceBinding) binding;
        ReferenceBinding[] supers = ref.superInterfaces();
        if (supers == null || supers.length == 0)
            supers = new ReferenceBinding[] { ref.superclass() };
        if (supers[0] == null) {
            TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3));
            setGeneratedBy(result, pos);
            return result;
        }
        return makeType(supers[0], pos, false);
    }

    if (binding instanceof CaptureBinding) {
        return makeType(((CaptureBinding) binding).wildcard, pos, allowCompound);
    }

    if (binding.isUnboundWildcard()) {
        if (!allowCompound) {
            TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3));
            setGeneratedBy(result, pos);
            return result;
        } else {
            Wildcard out = new Wildcard(Wildcard.UNBOUND);
            setGeneratedBy(out, pos);
            out.sourceStart = pos.sourceStart;
            out.sourceEnd = pos.sourceEnd;
            return out;
        }
    }

    if (binding.isWildcard()) {
        WildcardBinding wildcard = (WildcardBinding) binding;
        if (wildcard.boundKind == Wildcard.EXTENDS) {
            if (!allowCompound) {
                return makeType(wildcard.bound, pos, false);
            } else {
                Wildcard out = new Wildcard(Wildcard.EXTENDS);
                setGeneratedBy(out, pos);
                out.bound = makeType(wildcard.bound, pos, false);
                out.sourceStart = pos.sourceStart;
                out.sourceEnd = pos.sourceEnd;
                return out;
            }
        } else if (allowCompound && wildcard.boundKind == Wildcard.SUPER) {
            Wildcard out = new Wildcard(Wildcard.SUPER);
            setGeneratedBy(out, pos);
            out.bound = makeType(wildcard.bound, pos, false);
            out.sourceStart = pos.sourceStart;
            out.sourceEnd = pos.sourceEnd;
            return out;
        } else {
            TypeReference result = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(pos, 3));
            setGeneratedBy(result, pos);
            return result;
        }
    }

    // Keep moving up via 'binding.enclosingType()' and gather generics from each binding. We stop after a local type, or a static type, or a top-level type.
    // Finally, add however many nullTypeArgument[] arrays as that are missing, inverse the list, toArray it, and use that as PTR's typeArgument argument.

    List<TypeReference[]> params = new ArrayList<TypeReference[]>();
    /* Calculate generics */ {
        TypeBinding b = binding;
        while (true) {
            boolean isFinalStop = b.isLocalType() || !b.isMemberType() || b.enclosingType() == null;

            TypeReference[] tyParams = null;
            if (b instanceof ParameterizedTypeBinding) {
                ParameterizedTypeBinding paramized = (ParameterizedTypeBinding) b;
                if (paramized.arguments != null) {
                    tyParams = new TypeReference[paramized.arguments.length];
                    for (int i = 0; i < tyParams.length; i++) {
                        tyParams[i] = makeType(paramized.arguments[i], pos, true);
                    }
                }
            }

            params.add(tyParams);
            if (isFinalStop)
                break;
            b = b.enclosingType();
        }
    }

    char[][] parts;

    if (binding.isTypeVariable()) {
        parts = new char[][] { binding.shortReadableName() };
    } else if (binding.isLocalType()) {
        parts = new char[][] { binding.sourceName() };
    } else {
        String[] pkg = new String(binding.qualifiedPackageName()).split("\\.");
        String[] name = new String(binding.qualifiedSourceName()).split("\\.");
        if (pkg.length == 1 && pkg[0].isEmpty())
            pkg = new String[0];
        parts = new char[pkg.length + name.length][];
        int ptr;
        for (ptr = 0; ptr < pkg.length; ptr++)
            parts[ptr] = pkg[ptr].toCharArray();
        for (; ptr < pkg.length + name.length; ptr++)
            parts[ptr] = name[ptr - pkg.length].toCharArray();
    }

    while (params.size() < parts.length)
        params.add(null);
    Collections.reverse(params);

    boolean isParamized = false;

    for (TypeReference[] tyParams : params) {
        if (tyParams != null) {
            isParamized = true;
            break;
        }
    }
    if (isParamized) {
        if (parts.length > 1) {
            TypeReference[][] typeArguments = params.toArray(new TypeReference[0][]);
            TypeReference result = new ParameterizedQualifiedTypeReference(parts, typeArguments, dims,
                    poss(pos, parts.length));
            setGeneratedBy(result, pos);
            return result;
        }
        TypeReference result = new ParameterizedSingleTypeReference(parts[0], params.get(0), dims, pos(pos));
        setGeneratedBy(result, pos);
        return result;
    }

    if (dims > 0) {
        if (parts.length > 1) {
            TypeReference result = new ArrayQualifiedTypeReference(parts, dims, poss(pos, parts.length));
            setGeneratedBy(result, pos);
            return result;
        }
        TypeReference result = new ArrayTypeReference(parts[0], dims, pos(pos));
        setGeneratedBy(result, pos);
        return result;
    }

    if (parts.length > 1) {
        TypeReference result = new QualifiedTypeReference(parts, poss(pos, parts.length));
        setGeneratedBy(result, pos);
        return result;
    }
    TypeReference result = new SingleTypeReference(parts[0], pos(pos));
    setGeneratedBy(result, pos);
    return result;
}

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

License:Open Source License

public MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper,
        ASTNode source, FieldAccess fieldAccess, boolean needsCanEqual, List<Annotation> onParam) {
    int pS = source.sourceStart;
    int pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;
    TypeDeclaration typeDecl = (TypeDeclaration) type.get();

    MethodDeclaration method = new MethodDeclaration(
            ((CompilationUnitDeclaration) type.top().get()).compilationResult);
    setGeneratedBy(method, source);// w  ww  .  j  a v  a  2s  . c o m
    method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
    method.returnType = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
    method.returnType.sourceStart = pS;
    method.returnType.sourceEnd = pE;
    setGeneratedBy(method.returnType, source);
    method.annotations = new Annotation[] { makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) };
    method.selector = "equals".toCharArray();
    method.thrownExceptions = null;
    method.typeParameters = null;
    method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
    method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
    method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
    TypeReference objectRef = new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT,
            new long[] { p, p, p });
    setGeneratedBy(objectRef, source);
    method.arguments = new Argument[] { new Argument(new char[] { 'o' }, 0, objectRef, Modifier.FINAL) };
    method.arguments[0].sourceStart = pS;
    method.arguments[0].sourceEnd = pE;
    if (!onParam.isEmpty())
        method.arguments[0].annotations = onParam.toArray(new Annotation[0]);
    setGeneratedBy(method.arguments[0], source);

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

    /* if (o == this) return true; */ {
        SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p);
        setGeneratedBy(oRef, source);
        ThisReference thisRef = new ThisReference(pS, pE);
        setGeneratedBy(thisRef, source);
        EqualExpression otherEqualsThis = new EqualExpression(oRef, thisRef, OperatorIds.EQUAL_EQUAL);
        setGeneratedBy(otherEqualsThis, source);

        TrueLiteral trueLiteral = new TrueLiteral(pS, pE);
        setGeneratedBy(trueLiteral, source);
        ReturnStatement returnTrue = new ReturnStatement(trueLiteral, pS, pE);
        setGeneratedBy(returnTrue, source);
        IfStatement ifOtherEqualsThis = new IfStatement(otherEqualsThis, returnTrue, pS, pE);
        setGeneratedBy(ifOtherEqualsThis, source);
        statements.add(ifOtherEqualsThis);
    }

    /* if (!(o instanceof Outer.Inner.MyType) return false; */ {
        SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p);
        setGeneratedBy(oRef, source);

        TypeReference typeReference = createTypeReference(type, p);
        setGeneratedBy(typeReference, source);

        InstanceOfExpression instanceOf = new InstanceOfExpression(oRef, typeReference);
        instanceOf.sourceStart = pS;
        instanceOf.sourceEnd = pE;
        setGeneratedBy(instanceOf, source);

        Expression notInstanceOf = new UnaryExpression(instanceOf, OperatorIds.NOT);
        setGeneratedBy(notInstanceOf, source);

        FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
        setGeneratedBy(falseLiteral, source);

        ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE);
        setGeneratedBy(returnFalse, source);

        IfStatement ifNotInstanceOf = new IfStatement(notInstanceOf, returnFalse, pS, pE);
        setGeneratedBy(ifNotInstanceOf, source);
        statements.add(ifNotInstanceOf);
    }

    char[] otherName = "other".toCharArray();

    /* MyType<?> other = (MyType<?>) o; */ {
        if (!fields.isEmpty() || needsCanEqual) {
            LocalDeclaration other = new LocalDeclaration(otherName, pS, pE);
            other.modifiers |= ClassFileConstants.AccFinal;
            setGeneratedBy(other, source);
            char[] typeName = typeDecl.name;
            TypeReference targetType;
            if (typeDecl.typeParameters == null || typeDecl.typeParameters.length == 0) {
                targetType = new SingleTypeReference(typeName, p);
                setGeneratedBy(targetType, source);
                other.type = new SingleTypeReference(typeName, p);
                setGeneratedBy(other.type, source);
            } else {
                TypeReference[] typeArgs = new TypeReference[typeDecl.typeParameters.length];
                for (int i = 0; i < typeArgs.length; i++) {
                    typeArgs[i] = new Wildcard(Wildcard.UNBOUND);
                    typeArgs[i].sourceStart = pS;
                    typeArgs[i].sourceEnd = pE;
                    setGeneratedBy(typeArgs[i], source);
                }
                targetType = new ParameterizedSingleTypeReference(typeName, typeArgs, 0, p);
                setGeneratedBy(targetType, source);
                other.type = new ParameterizedSingleTypeReference(typeName, copyTypes(typeArgs, source), 0, p);
                setGeneratedBy(other.type, source);
            }
            NameReference oRef = new SingleNameReference(new char[] { 'o' }, p);
            setGeneratedBy(oRef, source);
            other.initialization = makeCastExpression(oRef, targetType, source);
            statements.add(other);
        }
    }

    /* if (!other.canEqual((java.lang.Object) this)) return false; */ {
        if (needsCanEqual) {
            MessageSend otherCanEqual = new MessageSend();
            otherCanEqual.sourceStart = pS;
            otherCanEqual.sourceEnd = pE;
            setGeneratedBy(otherCanEqual, source);
            otherCanEqual.receiver = new SingleNameReference(otherName, p);
            setGeneratedBy(otherCanEqual.receiver, source);
            otherCanEqual.selector = "canEqual".toCharArray();

            ThisReference thisReference = new ThisReference(pS, pE);
            setGeneratedBy(thisReference, source);
            CastExpression castThisRef = makeCastExpression(thisReference,
                    generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), source);
            castThisRef.sourceStart = pS;
            castThisRef.sourceEnd = pE;

            otherCanEqual.arguments = new Expression[] { castThisRef };

            Expression notOtherCanEqual = new UnaryExpression(otherCanEqual, OperatorIds.NOT);
            setGeneratedBy(notOtherCanEqual, source);

            FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
            setGeneratedBy(falseLiteral, source);

            ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE);
            setGeneratedBy(returnFalse, source);

            IfStatement ifNotCanEqual = new IfStatement(notOtherCanEqual, returnFalse, pS, pE);
            setGeneratedBy(ifNotCanEqual, source);

            statements.add(ifNotCanEqual);
        }
    }

    /* if (!super.equals(o)) return false; */
    if (callSuper) {
        MessageSend callToSuper = new MessageSend();
        callToSuper.sourceStart = pS;
        callToSuper.sourceEnd = pE;
        setGeneratedBy(callToSuper, source);
        callToSuper.receiver = new SuperReference(pS, pE);
        setGeneratedBy(callToSuper.receiver, source);
        callToSuper.selector = "equals".toCharArray();
        SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p);
        setGeneratedBy(oRef, source);
        callToSuper.arguments = new Expression[] { oRef };
        Expression superNotEqual = new UnaryExpression(callToSuper, OperatorIds.NOT);
        setGeneratedBy(superNotEqual, source);
        FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
        setGeneratedBy(falseLiteral, source);
        ReturnStatement returnFalse = new ReturnStatement(falseLiteral, pS, pE);
        setGeneratedBy(returnFalse, source);
        IfStatement ifSuperEquals = new IfStatement(superNotEqual, returnFalse, pS, pE);
        setGeneratedBy(ifSuperEquals, source);
        statements.add(ifSuperEquals);
    }

    for (EclipseNode field : fields) {
        TypeReference fType = getFieldType(field, fieldAccess);
        char[] token = fType.getLastToken();
        Expression thisFieldAccessor = createFieldAccessor(field, fieldAccess, source);
        Expression otherFieldAccessor = createFieldAccessor(field, fieldAccess, source, otherName);

        if (fType.dimensions() == 0 && token != null) {
            if (Arrays.equals(TypeConstants.FLOAT, token)) {
                statements.add(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor,
                        "Float".toCharArray(), source));
            } else if (Arrays.equals(TypeConstants.DOUBLE, token)) {
                statements.add(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor,
                        "Double".toCharArray(), source));
            } else if (BUILT_IN_TYPES.contains(new String(token))) {
                EqualExpression fieldsNotEqual = new EqualExpression(thisFieldAccessor, otherFieldAccessor,
                        OperatorIds.NOT_EQUAL);
                setGeneratedBy(fieldsNotEqual, source);
                FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
                setGeneratedBy(falseLiteral, source);
                ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE);
                setGeneratedBy(returnStatement, source);
                IfStatement ifStatement = new IfStatement(fieldsNotEqual, returnStatement, pS, pE);
                setGeneratedBy(ifStatement, source);
                statements.add(ifStatement);
            } else /* objects */ {
                /* final java.lang.Object this$fieldName = this.fieldName; */
                /* final java.lang.Object other$fieldName = other.fieldName; */
                /* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false;; */
                char[] thisDollarFieldName = ("this$" + field.getName()).toCharArray();
                char[] otherDollarFieldName = ("other$" + field.getName()).toCharArray();

                statements.add(createLocalDeclaration(source, thisDollarFieldName,
                        generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), thisFieldAccessor));
                statements.add(createLocalDeclaration(source, otherDollarFieldName,
                        generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), otherFieldAccessor));

                SingleNameReference this1 = new SingleNameReference(thisDollarFieldName, p);
                setGeneratedBy(this1, source);
                SingleNameReference this2 = new SingleNameReference(thisDollarFieldName, p);
                setGeneratedBy(this2, source);
                SingleNameReference other1 = new SingleNameReference(otherDollarFieldName, p);
                setGeneratedBy(other1, source);
                SingleNameReference other2 = new SingleNameReference(otherDollarFieldName, p);
                setGeneratedBy(other2, source);

                NullLiteral nullLiteral = new NullLiteral(pS, pE);
                setGeneratedBy(nullLiteral, source);
                EqualExpression fieldIsNull = new EqualExpression(this1, nullLiteral, OperatorIds.EQUAL_EQUAL);
                nullLiteral = new NullLiteral(pS, pE);
                setGeneratedBy(nullLiteral, source);
                EqualExpression otherFieldIsntNull = new EqualExpression(other1, nullLiteral,
                        OperatorIds.NOT_EQUAL);
                MessageSend equalsCall = new MessageSend();
                equalsCall.sourceStart = pS;
                equalsCall.sourceEnd = pE;
                setGeneratedBy(equalsCall, source);
                equalsCall.receiver = this2;
                equalsCall.selector = "equals".toCharArray();
                equalsCall.arguments = new Expression[] { other2 };
                UnaryExpression fieldsNotEqual = new UnaryExpression(equalsCall, OperatorIds.NOT);
                fieldsNotEqual.sourceStart = pS;
                fieldsNotEqual.sourceEnd = pE;
                setGeneratedBy(fieldsNotEqual, source);
                ConditionalExpression fullEquals = new ConditionalExpression(fieldIsNull, otherFieldIsntNull,
                        fieldsNotEqual);
                fullEquals.sourceStart = pS;
                fullEquals.sourceEnd = pE;
                setGeneratedBy(fullEquals, source);
                FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
                setGeneratedBy(falseLiteral, source);
                ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE);
                setGeneratedBy(returnStatement, source);
                IfStatement ifStatement = new IfStatement(fullEquals, returnStatement, pS, pE);
                setGeneratedBy(ifStatement, source);
                statements.add(ifStatement);
            }
        } else if (fType.dimensions() > 0 && token != null) {
            MessageSend arraysEqualCall = new MessageSend();
            arraysEqualCall.sourceStart = pS;
            arraysEqualCall.sourceEnd = pE;
            setGeneratedBy(arraysEqualCall, source);
            arraysEqualCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL,
                    "Arrays".toCharArray());
            if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
                arraysEqualCall.selector = "deepEquals".toCharArray();
            } else {
                arraysEqualCall.selector = "equals".toCharArray();
            }
            arraysEqualCall.arguments = new Expression[] { thisFieldAccessor, otherFieldAccessor };
            UnaryExpression arraysNotEqual = new UnaryExpression(arraysEqualCall, OperatorIds.NOT);
            arraysNotEqual.sourceStart = pS;
            arraysNotEqual.sourceEnd = pE;
            setGeneratedBy(arraysNotEqual, source);
            FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
            setGeneratedBy(falseLiteral, source);
            ReturnStatement returnStatement = new ReturnStatement(falseLiteral, pS, pE);
            setGeneratedBy(returnStatement, source);
            IfStatement ifStatement = new IfStatement(arraysNotEqual, returnStatement, pS, pE);
            setGeneratedBy(ifStatement, source);
            statements.add(ifStatement);
        }
    }

    /* return true; */ {
        TrueLiteral trueLiteral = new TrueLiteral(pS, pE);
        setGeneratedBy(trueLiteral, source);
        ReturnStatement returnStatement = new ReturnStatement(trueLiteral, pS, pE);
        setGeneratedBy(returnStatement, source);
        statements.add(returnStatement);
    }
    method.statements = statements.toArray(new Statement[statements.size()]);
    return method;
}

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

License:Open Source License

/**
 * Generates a constructor that has a builder as the only parameter.
 * The values from the builder are used to initialize the fields of new instances.
 *
 * @param typeNode//w  w  w. java 2s  .com
 *            the type (with the {@code @Builder} annotation) for which a
 *            constructor should be generated.
 * @param typeParams
 * @param builderFields a list of fields in the builder which should be assigned to new instances.
 * @param source the annotation (used for setting source code locations for the generated code).
 * @param callBuilderBasedSuperConstructor
 *            If {@code true}, the constructor will explicitly call a super
 *            constructor with the builder as argument. Requires
 *            {@code builderClassAsParameter != null}.
 */
private void generateBuilderBasedConstructor(EclipseNode typeNode, TypeParameter[] typeParams,
        List<BuilderFieldData> builderFields, EclipseNode sourceNode, String builderClassName,
        boolean callBuilderBasedSuperConstructor) {

    ASTNode source = sourceNode.get();

    TypeDeclaration typeDeclaration = ((TypeDeclaration) typeNode.get());
    long p = (long) source.sourceStart << 32 | source.sourceEnd;

    ConstructorDeclaration constructor = new ConstructorDeclaration(
            ((CompilationUnitDeclaration) typeNode.top().get()).compilationResult);

    constructor.modifiers = toEclipseModifier(AccessLevel.PROTECTED);
    constructor.selector = typeDeclaration.name;
    if (callBuilderBasedSuperConstructor) {
        constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super);
        constructor.constructorCall.arguments = new Expression[] {
                new SingleNameReference(BUILDER_VARIABLE_NAME, p) };
    } else {
        constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
    }
    constructor.constructorCall.sourceStart = source.sourceStart;
    constructor.constructorCall.sourceEnd = source.sourceEnd;
    constructor.thrownExceptions = null;
    constructor.typeParameters = null;
    constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart;
    constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;

    TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND),
            new Wildcard(Wildcard.UNBOUND) };
    TypeReference builderType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(),
            mergeToTypeReferences(typeParams, wildcards), 0, p);
    constructor.arguments = new Argument[] {
            new Argument(BUILDER_VARIABLE_NAME, p, builderType, Modifier.FINAL) };

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

    for (BuilderFieldData fieldNode : builderFields) {
        char[] fieldName = removePrefixFromField(fieldNode.originalFieldNode);
        FieldReference fieldInThis = new FieldReference(fieldNode.rawName, p);
        int s = (int) (p >> 32);
        int e = (int) p;
        fieldInThis.receiver = new ThisReference(s, e);

        Expression assignmentExpr;
        if (fieldNode.singularData != null && fieldNode.singularData.getSingularizer() != null) {
            fieldNode.singularData.getSingularizer().appendBuildCode(fieldNode.singularData, typeNode,
                    statements, fieldNode.name, BUILDER_VARIABLE_NAME_STRING);
            assignmentExpr = new SingleNameReference(fieldNode.name, p);
        } else {
            char[][] variableInBuilder = new char[][] { BUILDER_VARIABLE_NAME, fieldName };
            long[] positions = new long[] { p, p };
            assignmentExpr = new QualifiedNameReference(variableInBuilder, positions, s, e);
        }
        Statement assignment = new Assignment(fieldInThis, assignmentExpr, (int) p);

        // In case of @Builder.Default, set the value to the default if it was NOT set in the builder.
        if (fieldNode.nameOfSetFlag != null) {
            char[][] setVariableInBuilder = new char[][] { BUILDER_VARIABLE_NAME, fieldNode.nameOfSetFlag };
            long[] positions = new long[] { p, p };
            QualifiedNameReference setVariableInBuilderRef = new QualifiedNameReference(setVariableInBuilder,
                    positions, s, e);

            MessageSend defaultMethodCall = new MessageSend();
            defaultMethodCall.sourceStart = source.sourceStart;
            defaultMethodCall.sourceEnd = source.sourceEnd;
            defaultMethodCall.receiver = new SingleNameReference(((TypeDeclaration) typeNode.get()).name, 0L);
            defaultMethodCall.selector = fieldNode.nameOfDefaultProvider;
            defaultMethodCall.typeArguments = typeParameterNames(
                    ((TypeDeclaration) typeNode.get()).typeParameters);

            Statement defaultAssignment = new Assignment(fieldInThis, defaultMethodCall, (int) p);
            IfStatement ifBlockForDefault = new IfStatement(setVariableInBuilderRef, assignment,
                    defaultAssignment, s, e);
            statements.add(ifBlockForDefault);
        } else {
            statements.add(assignment);
        }

        if (hasNonNullAnnotations(fieldNode.originalFieldNode)) {
            Statement nullCheck = generateNullCheck((FieldDeclaration) fieldNode.originalFieldNode.get(),
                    sourceNode);
            if (nullCheck != null)
                statements.add(nullCheck);
        }
    }

    constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);

    constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);

    injectMethod(typeNode, constructor);
}

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

License:Open Source License

private MethodDeclaration generateBuilderMethod(String builderMethodName, String builderClassName,
        String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;

    MethodDeclaration out = new MethodDeclaration(
            ((CompilationUnitDeclaration) type.top().get()).compilationResult);
    out.selector = builderMethodName.toCharArray();
    out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
    out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;

    // Add type params if there are any.
    if (typeParams != null && typeParams.length > 0)
        out.typeParameters = copyTypeParams(typeParams, source);

    TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND),
            new Wildcard(Wildcard.UNBOUND) };
    out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(),
            mergeToTypeReferences(typeParams, wildcards), 0, p);

    AllocationExpression invoke = new AllocationExpression();
    invoke.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
    out.statements = new Statement[] { new ReturnStatement(invoke, pS, pE) };

    out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
    return out;//from   ww  w.j  a  v  a2s.  c o m
}

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

License:Open Source License

/**
 * Generates a <code>toBuilder()</code> method in the annotated class that looks like this:
 * <pre>/*w w  w  .ja v a  2s .  c  om*/
 * public ParentBuilder&lt;?, ?&gt; toBuilder() {
 *     return new <i>Foobar</i>BuilderImpl().$fillValuesFrom(this);
 * }
 * </pre>
 */
private MethodDeclaration generateToBuilderMethod(String builderClassName, String builderImplClassName,
        EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;

    MethodDeclaration out = new MethodDeclaration(
            ((CompilationUnitDeclaration) type.top().get()).compilationResult);
    out.selector = TO_BUILDER_METHOD_NAME;
    out.modifiers = ClassFileConstants.AccPublic;
    out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;

    TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND),
            new Wildcard(Wildcard.UNBOUND) };
    out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(),
            mergeToTypeReferences(typeParams, wildcards), 0, p);

    AllocationExpression newClass = new AllocationExpression();
    newClass.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
    MessageSend invokeFillMethod = new MessageSend();
    invokeFillMethod.receiver = newClass;
    invokeFillMethod.selector = FILL_VALUES_METHOD_NAME;
    invokeFillMethod.arguments = new Expression[] { new ThisReference(0, 0) };
    out.statements = new Statement[] { new ReturnStatement(invokeFillMethod, pS, pE) };

    out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
    return out;
}

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

License:Open Source License

/**
 * Generates a <code>$fillValuesFromInstanceIntoBuilder()</code> method in
 * the builder implementation class that copies all fields from the instance
 * to the builder. It looks like this://from  w ww  .ja  v a2 s . c  o  m
 * 
 * <pre>
 * protected B $fillValuesFromInstanceIntoBuilder(Foobar instance, FoobarBuilder&lt;?, ?&gt; b) {
 *    b.field(instance.field);
 * }
 * </pre>
 */
private MethodDeclaration generateStaticFillValuesMethod(EclipseNode tdParent, String builderClassName,
        TypeParameter[] typeParams, java.util.List<BuilderFieldData> builderFields, ASTNode source) {
    MethodDeclaration out = new MethodDeclaration(
            ((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
    out.selector = FILL_VALUES_STATIC_METHOD_NAME;
    out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
    out.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
    out.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);

    TypeReference[] wildcards = new TypeReference[] { new Wildcard(Wildcard.UNBOUND),
            new Wildcard(Wildcard.UNBOUND) };
    TypeReference builderType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(),
            mergeToTypeReferences(typeParams, wildcards), 0, 0);
    Argument builderArgument = new Argument(BUILDER_VARIABLE_NAME, 0, builderType, Modifier.FINAL);
    TypeReference parentArgument = createTypeReferenceWithTypeParameters(tdParent.getName(), typeParams);
    out.arguments = new Argument[] { new Argument(INSTANCE_VARIABLE_NAME, 0, parentArgument, Modifier.FINAL),
            builderArgument };

    // Add type params if there are any.
    if (typeParams.length > 0)
        out.typeParameters = copyTypeParams(typeParams, source);

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

    // Call the builder's setter methods to fill the values from the instance.
    for (BuilderFieldData bfd : builderFields) {
        MessageSend exec = createSetterCallWithInstanceValue(bfd, tdParent, source);
        body.add(exec);
    }

    out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]);

    return out;
}

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

License:Open Source License

private TypeReference createTypeReferenceForClassNode(GenericsType genericsType) {
    if (genericsType.isWildcard()) {
        ClassNode[] bounds = genericsType.getUpperBounds();
        if (bounds != null) {
            // FIXASC other bounds?
            // positions example: (29>31)Set<(33>54)? extends (43>54)Serializable>
            TypeReference boundReference = createTypeReferenceForClassNode(bounds[0]);
            Wildcard wildcard = new Wildcard(Wildcard.EXTENDS);
            wildcard.sourceStart = genericsType.getStart();
            wildcard.sourceEnd = boundReference.sourceEnd();
            wildcard.bound = boundReference;
            return wildcard;
        } else if (genericsType.getLowerBound() != null) {
            // positions example: (67>69)Set<(71>84)? super (79>84)Number>
            TypeReference boundReference = createTypeReferenceForClassNode(genericsType.getLowerBound());
            Wildcard wildcard = new Wildcard(Wildcard.SUPER);
            wildcard.sourceStart = genericsType.getStart();
            wildcard.sourceEnd = boundReference.sourceEnd();
            wildcard.bound = boundReference;
            return wildcard;
        } else {//  w ww .  jav a 2 s .c  o  m
            Wildcard w = new Wildcard(Wildcard.UNBOUND);
            w.sourceStart = genericsType.getStart();
            w.sourceEnd = genericsType.getStart();
            return w;
        }
        // FIXASC what does the check on this next really line mean?
    } else if (!genericsType.getType().isGenericsPlaceHolder()) {
        TypeReference typeReference = createTypeReferenceForClassNode(genericsType.getType());
        return typeReference;
    } else {
        // this means it is a placeholder. As an example, if the reference is to 'List'
        // then the genericsType info may include a placeholder for the type variable (as the user
        // didn't fill it in as anything) and so for this example the genericsType is 'E extends java.lang.Object'
        // I don't think we need a type reference for this as the type references we are constructed
        // here are representative of what the user did in the source, not the resolved result of that.
        // throw new GroovyEclipseBug();
        return null;
    }
}