Search in sources :

Example 11 with LocalDeclaration

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

the class HandleEqualsAndHashCode method createHashCode.

public MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess) {
    int pS = source.sourceStart, pE = source.sourceEnd;
    long p = (long) pS << 32 | pE;
    MethodDeclaration method = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
    setGeneratedBy(method, source);
    method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
    method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0);
    setGeneratedBy(method.returnType, source);
    method.annotations = new Annotation[] { makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) };
    method.selector = "hashCode".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;
    method.arguments = null;
    List<Statement> statements = new ArrayList<Statement>();
    final boolean isEmpty = fields.isEmpty();
    /* final int PRIME = X; */
    {
        /* Without fields, PRIME isn't used, and that would trigger a 'local variable not used' warning. */
        if (!isEmpty) {
            LocalDeclaration primeDecl = new LocalDeclaration(PRIME, pS, pE);
            setGeneratedBy(primeDecl, source);
            primeDecl.modifiers |= Modifier.FINAL;
            primeDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
            primeDecl.type.sourceStart = pS;
            primeDecl.type.sourceEnd = pE;
            setGeneratedBy(primeDecl.type, source);
            primeDecl.initialization = makeIntLiteral(String.valueOf(HandlerUtil.primeForHashcode()).toCharArray(), source);
            statements.add(primeDecl);
        }
    }
    /*int result = ... */
    {
        LocalDeclaration resultDecl = new LocalDeclaration(RESULT, pS, pE);
        setGeneratedBy(resultDecl, source);
        final Expression init;
        if (callSuper) {
            /* ... super.hashCode(); */
            MessageSend callToSuper = new MessageSend();
            setGeneratedBy(callToSuper, source);
            callToSuper.sourceStart = pS;
            callToSuper.sourceEnd = pE;
            callToSuper.receiver = new SuperReference(pS, pE);
            setGeneratedBy(callToSuper.receiver, source);
            callToSuper.selector = "hashCode".toCharArray();
            init = callToSuper;
        } else {
            /* ... 1; */
            init = makeIntLiteral("1".toCharArray(), source);
        }
        resultDecl.initialization = init;
        resultDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
        resultDecl.type.sourceStart = pS;
        resultDecl.type.sourceEnd = pE;
        setGeneratedBy(resultDecl.type, source);
        statements.add(resultDecl);
    }
    for (EclipseNode field : fields) {
        TypeReference fType = getFieldType(field, fieldAccess);
        char[] dollarFieldName = ("$" + field.getName()).toCharArray();
        char[] token = fType.getLastToken();
        Expression fieldAccessor = createFieldAccessor(field, fieldAccess, source);
        if (fType.dimensions() == 0 && token != null) {
            if (Arrays.equals(TypeConstants.BOOLEAN, token)) {
                /* booleanField ? X : Y */
                IntLiteral intTrue = makeIntLiteral(String.valueOf(HandlerUtil.primeForTrue()).toCharArray(), source);
                IntLiteral intFalse = makeIntLiteral(String.valueOf(HandlerUtil.primeForFalse()).toCharArray(), source);
                ConditionalExpression intForBool = new ConditionalExpression(fieldAccessor, intTrue, intFalse);
                setGeneratedBy(intForBool, source);
                statements.add(createResultCalculation(source, intForBool));
            } else if (Arrays.equals(TypeConstants.LONG, token)) {
                statements.add(createLocalDeclaration(source, dollarFieldName, TypeReference.baseTypeReference(TypeIds.T_long, 0), fieldAccessor));
                SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
                setGeneratedBy(copy1, source);
                SingleNameReference copy2 = new SingleNameReference(dollarFieldName, p);
                setGeneratedBy(copy2, source);
                statements.add(createResultCalculation(source, longToIntForHashCode(copy1, copy2, source)));
            } else if (Arrays.equals(TypeConstants.FLOAT, token)) {
                /* Float.floatToIntBits(fieldName) */
                MessageSend floatToIntBits = new MessageSend();
                floatToIntBits.sourceStart = pS;
                floatToIntBits.sourceEnd = pE;
                setGeneratedBy(floatToIntBits, source);
                floatToIntBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_FLOAT);
                floatToIntBits.selector = "floatToIntBits".toCharArray();
                floatToIntBits.arguments = new Expression[] { fieldAccessor };
                statements.add(createResultCalculation(source, floatToIntBits));
            } else if (Arrays.equals(TypeConstants.DOUBLE, token)) {
                /* longToIntForHashCode(Double.doubleToLongBits(fieldName)) */
                MessageSend doubleToLongBits = new MessageSend();
                doubleToLongBits.sourceStart = pS;
                doubleToLongBits.sourceEnd = pE;
                setGeneratedBy(doubleToLongBits, source);
                doubleToLongBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_DOUBLE);
                doubleToLongBits.selector = "doubleToLongBits".toCharArray();
                doubleToLongBits.arguments = new Expression[] { fieldAccessor };
                statements.add(createLocalDeclaration(source, dollarFieldName, TypeReference.baseTypeReference(TypeIds.T_long, 0), doubleToLongBits));
                SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
                setGeneratedBy(copy1, source);
                SingleNameReference copy2 = new SingleNameReference(dollarFieldName, p);
                setGeneratedBy(copy2, source);
                statements.add(createResultCalculation(source, longToIntForHashCode(copy1, copy2, source)));
            } else if (BUILT_IN_TYPES.contains(new String(token))) {
                statements.add(createResultCalculation(source, fieldAccessor));
            } else /* objects */
            {
                /* final java.lang.Object $fieldName = this.fieldName; */
                /* $fieldName == null ? NULL_PRIME : $fieldName.hashCode() */
                statements.add(createLocalDeclaration(source, dollarFieldName, generateQualifiedTypeRef(source, TypeConstants.JAVA_LANG_OBJECT), fieldAccessor));
                SingleNameReference copy1 = new SingleNameReference(dollarFieldName, p);
                setGeneratedBy(copy1, source);
                SingleNameReference copy2 = new SingleNameReference(dollarFieldName, p);
                setGeneratedBy(copy2, source);
                MessageSend hashCodeCall = new MessageSend();
                hashCodeCall.sourceStart = pS;
                hashCodeCall.sourceEnd = pE;
                setGeneratedBy(hashCodeCall, source);
                hashCodeCall.receiver = copy1;
                hashCodeCall.selector = "hashCode".toCharArray();
                NullLiteral nullLiteral = new NullLiteral(pS, pE);
                setGeneratedBy(nullLiteral, source);
                EqualExpression objIsNull = new EqualExpression(copy2, nullLiteral, OperatorIds.EQUAL_EQUAL);
                setGeneratedBy(objIsNull, source);
                IntLiteral intMagic = makeIntLiteral(String.valueOf(HandlerUtil.primeForNull()).toCharArray(), source);
                ConditionalExpression nullOrHashCode = new ConditionalExpression(objIsNull, intMagic, hashCodeCall);
                nullOrHashCode.sourceStart = pS;
                nullOrHashCode.sourceEnd = pE;
                setGeneratedBy(nullOrHashCode, source);
                statements.add(createResultCalculation(source, nullOrHashCode));
            }
        } else if (fType.dimensions() > 0 && token != null) {
            /* Arrays.deepHashCode(array)  //just hashCode for simple arrays */
            MessageSend arraysHashCodeCall = new MessageSend();
            arraysHashCodeCall.sourceStart = pS;
            arraysHashCodeCall.sourceEnd = pE;
            setGeneratedBy(arraysHashCodeCall, source);
            arraysHashCodeCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray());
            if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
                arraysHashCodeCall.selector = "deepHashCode".toCharArray();
            } else {
                arraysHashCodeCall.selector = "hashCode".toCharArray();
            }
            arraysHashCodeCall.arguments = new Expression[] { fieldAccessor };
            statements.add(createResultCalculation(source, arraysHashCodeCall));
        }
    }
    /* return result; */
    {
        SingleNameReference resultRef = new SingleNameReference(RESULT, p);
        setGeneratedBy(resultRef, source);
        ReturnStatement returnStatement = new ReturnStatement(resultRef, pS, pE);
        setGeneratedBy(returnStatement, source);
        statements.add(returnStatement);
    }
    method.statements = statements.toArray(new Statement[statements.size()]);
    return method;
}
Also used : LocalDeclaration(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) Statement(org.eclipse.jdt.internal.compiler.ast.Statement) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) IfStatement(org.eclipse.jdt.internal.compiler.ast.IfStatement) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) ArrayList(java.util.ArrayList) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) SingleNameReference(org.eclipse.jdt.internal.compiler.ast.SingleNameReference) SuperReference(org.eclipse.jdt.internal.compiler.ast.SuperReference) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) BinaryExpression(org.eclipse.jdt.internal.compiler.ast.BinaryExpression) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) InstanceOfExpression(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) UnaryExpression(org.eclipse.jdt.internal.compiler.ast.UnaryExpression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) CastExpression(org.eclipse.jdt.internal.compiler.ast.CastExpression) ReturnStatement(org.eclipse.jdt.internal.compiler.ast.ReturnStatement) EclipseNode(lombok.eclipse.EclipseNode) IntLiteral(org.eclipse.jdt.internal.compiler.ast.IntLiteral) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) ParameterizedSingleTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) ParameterizedQualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) NullLiteral(org.eclipse.jdt.internal.compiler.ast.NullLiteral)

Example 12 with LocalDeclaration

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

the class EclipseGuavaSingularizer method appendBuildCode.

@Override
public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName) {
    TypeReference varType = new QualifiedTypeReference(fromQualifiedName(data.getTargetFqn()), NULL_POSS);
    String simpleTypeName = getSimpleTargetTypeName(data);
    int agrumentsCount = getTypeArgumentsCount();
    varType = addTypeArgs(agrumentsCount, false, builderType, varType, data.getTypeArgs());
    MessageSend emptyInvoke;
    {
        // ImmutableX.of()
        emptyInvoke = new MessageSend();
        emptyInvoke.selector = new char[] { 'o', 'f' };
        emptyInvoke.receiver = new QualifiedNameReference(makeGuavaTypeName(simpleTypeName, false), NULL_POSS, 0, 0);
        emptyInvoke.typeArguments = createTypeArgs(agrumentsCount, false, builderType, data.getTypeArgs());
    }
    MessageSend invokeBuild;
    {
        // this.pluralName.build();
        invokeBuild = new MessageSend();
        invokeBuild.selector = new char[] { 'b', 'u', 'i', 'l', 'd' };
        FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
        thisDotField.receiver = new ThisReference(0, 0);
        invokeBuild.receiver = thisDotField;
    }
    Expression isNull;
    {
        // this.pluralName == null
        FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
        thisDotField.receiver = new ThisReference(0, 0);
        isNull = new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
    }
    Expression init = new ConditionalExpression(isNull, emptyInvoke, invokeBuild);
    LocalDeclaration varDefStat = new LocalDeclaration(data.getPluralName(), 0, 0);
    varDefStat.type = varType;
    varDefStat.initialization = init;
    statements.add(varDefStat);
}
Also used : LocalDeclaration(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) FieldReference(org.eclipse.jdt.internal.compiler.ast.FieldReference) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) ThisReference(org.eclipse.jdt.internal.compiler.ast.ThisReference) MessageSend(org.eclipse.jdt.internal.compiler.ast.MessageSend) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) EqualExpression(org.eclipse.jdt.internal.compiler.ast.EqualExpression) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) NullLiteral(org.eclipse.jdt.internal.compiler.ast.NullLiteral) QualifiedNameReference(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference)

Aggregations

LocalDeclaration (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)12 MessageSend (org.eclipse.jdt.internal.compiler.ast.MessageSend)10 SingleNameReference (org.eclipse.jdt.internal.compiler.ast.SingleNameReference)9 Statement (org.eclipse.jdt.internal.compiler.ast.Statement)9 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)8 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)8 EqualExpression (org.eclipse.jdt.internal.compiler.ast.EqualExpression)7 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)7 IfStatement (org.eclipse.jdt.internal.compiler.ast.IfStatement)7 ThisReference (org.eclipse.jdt.internal.compiler.ast.ThisReference)7 ArrayList (java.util.ArrayList)6 ConditionalExpression (org.eclipse.jdt.internal.compiler.ast.ConditionalExpression)6 NullLiteral (org.eclipse.jdt.internal.compiler.ast.NullLiteral)6 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)5 BinaryExpression (org.eclipse.jdt.internal.compiler.ast.BinaryExpression)5 FieldReference (org.eclipse.jdt.internal.compiler.ast.FieldReference)5 QualifiedNameReference (org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference)5 SwitchStatement (org.eclipse.jdt.internal.compiler.ast.SwitchStatement)5 EclipseNode (lombok.eclipse.EclipseNode)4 Assignment (org.eclipse.jdt.internal.compiler.ast.Assignment)4