Search in sources :

Example 1 with FunctionalExpression

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

the class PatchVal method handleValForLocalDeclaration.

public static boolean handleValForLocalDeclaration(LocalDeclaration local, BlockScope scope) {
    if (local == null || !LocalDeclaration.class.equals(local.getClass()))
        return false;
    boolean decomponent = false;
    boolean val = isVal(local, scope);
    boolean var = isVar(local, scope);
    if (!(val || var))
        return false;
    if (val) {
        StackTraceElement[] st = new Throwable().getStackTrace();
        for (int i = 0; i < st.length - 2 && i < 10; i++) {
            if (st[i].getClassName().equals("lombok.launch.PatchFixesHider$Val")) {
                boolean valInForStatement = st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") && st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement");
                if (valInForStatement)
                    return false;
                break;
            }
        }
    }
    Expression init = local.initialization;
    if (init == null && Reflection.initCopyField != null) {
        try {
            init = (Expression) Reflection.initCopyField.get(local);
        } catch (Exception e) {
        // init remains null.
        }
    }
    if (init == null && Reflection.iterableCopyField != null) {
        try {
            init = (Expression) Reflection.iterableCopyField.get(local);
            decomponent = true;
        } catch (Exception e) {
        // init remains null.
        }
    }
    TypeReference replacement = null;
    // Java 10+: Lombok uses the native 'var' support and transforms 'val' to 'final var'.
    if (hasNativeVarSupport(scope) && val) {
        replacement = new SingleTypeReference("var".toCharArray(), pos(local.type));
        local.initialization = init;
        init = null;
    }
    if (init != null) {
        if (init.getClass().getName().equals("org.eclipse.jdt.internal.compiler.ast.LambdaExpression")) {
            return false;
        }
        TypeBinding resolved = null;
        try {
            resolved = decomponent ? getForEachComponentType(init, scope) : resolveForExpression(init, scope);
        } catch (NullPointerException e) {
            // This definitely occurs if as part of resolving the initializer expression, a
            // lambda expression in it must also be resolved (such as when lambdas are part of
            // a ternary expression). This can't result in a viable 'val' matching, so, we
            // just go with 'Object' and let the IDE print the appropriate errors.
            resolved = null;
        }
        if (resolved == null) {
            if (init instanceof ConditionalExpression) {
                ConditionalExpression cexp = (ConditionalExpression) init;
                Expression ifTrue = cexp.valueIfTrue;
                Expression ifFalse = cexp.valueIfFalse;
                TypeBinding ifTrueResolvedType = ifTrue.resolvedType;
                CompilationResult compilationResult = scope.referenceCompilationUnit().compilationResult;
                CategorizedProblem[] problems = compilationResult.problems;
                CategorizedProblem lastProblem = problems[compilationResult.problemCount - 1];
                if (ifTrueResolvedType != null && ifFalse.resolvedType == null && lastProblem.getCategoryID() == CAT_TYPE) {
                    int problemCount = compilationResult.problemCount;
                    for (int i = 0; i < problemCount; ++i) {
                        if (problems[i] == lastProblem) {
                            problems[i] = null;
                            if (i + 1 < problemCount) {
                                System.arraycopy(problems, i + 1, problems, i, problemCount - i + 1);
                            }
                            break;
                        }
                    }
                    compilationResult.removeProblem(lastProblem);
                    if (!compilationResult.hasErrors()) {
                        clearIgnoreFurtherInvestigationField(scope.referenceContext());
                        setValue(getField(CompilationResult.class, "hasMandatoryErrors"), compilationResult, false);
                    }
                    if (ifFalse instanceof FunctionalExpression) {
                        FunctionalExpression functionalExpression = (FunctionalExpression) ifFalse;
                        functionalExpression.setExpectedType(ifTrueResolvedType);
                    }
                    if (ifFalse.resolvedType == null) {
                        resolveForExpression(ifFalse, scope);
                    }
                    resolved = ifTrueResolvedType;
                }
            }
        }
        if (resolved != null) {
            try {
                replacement = makeType(resolved, local.type, false);
                if (!decomponent)
                    init.resolvedType = replacement.resolveType(scope);
            } catch (Exception e) {
            // Some type thing failed.
            }
        }
    }
    if (val)
        local.modifiers |= ClassFileConstants.AccFinal;
    local.annotations = addValAnnotation(local.annotations, local.type, scope);
    local.type = replacement != null ? replacement : new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(local.type, 3));
    return false;
}
Also used : ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) CategorizedProblem(org.eclipse.jdt.core.compiler.CategorizedProblem) ConditionalExpression(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) LambdaExpression(org.eclipse.jdt.internal.compiler.ast.LambdaExpression) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) FunctionalExpression(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) SingleTypeReference(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) QualifiedTypeReference(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) CompilationResult(org.eclipse.jdt.internal.compiler.CompilationResult) FunctionalExpression(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression)

Aggregations

CategorizedProblem (org.eclipse.jdt.core.compiler.CategorizedProblem)1 CompilationResult (org.eclipse.jdt.internal.compiler.CompilationResult)1 ConditionalExpression (org.eclipse.jdt.internal.compiler.ast.ConditionalExpression)1 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)1 FunctionalExpression (org.eclipse.jdt.internal.compiler.ast.FunctionalExpression)1 LambdaExpression (org.eclipse.jdt.internal.compiler.ast.LambdaExpression)1 QualifiedTypeReference (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference)1 SingleTypeReference (org.eclipse.jdt.internal.compiler.ast.SingleTypeReference)1 TypeReference (org.eclipse.jdt.internal.compiler.ast.TypeReference)1 ParameterizedTypeBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding)1 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)1