Search in sources :

Example 1 with FieldInitsFakingFlowContext

use of org.eclipse.jdt.internal.compiler.flow.FieldInitsFakingFlowContext in project bazel-jdt-java-toolchain by salesforce.

the class ReferenceExpression method generateImplicitLambda.

public void generateImplicitLambda(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
    ReferenceExpression copy = copy();
    int argc = this.descriptor.parameters.length;
    LambdaExpression implicitLambda = new LambdaExpression(this.compilationResult, false, (this.binding.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0);
    Argument[] arguments = new Argument[argc];
    for (int i = 0; i < argc; i++) arguments[i] = new Argument(CharOperation.append(ImplicitArgName, Integer.toString(i).toCharArray()), 0, null, 0, true);
    implicitLambda.setArguments(arguments);
    implicitLambda.setExpressionContext(this.expressionContext);
    implicitLambda.setExpectedType(this.expectedType);
    int parameterShift = this.receiverPrecedesParameters ? 1 : 0;
    Expression[] argv = new SingleNameReference[argc - parameterShift];
    for (int i = 0, length = argv.length; i < length; i++) {
        char[] name = CharOperation.append(ImplicitArgName, Integer.toString((i + parameterShift)).toCharArray());
        argv[i] = new SingleNameReference(name, 0);
    }
    boolean generateSecretReceiverVariable = shouldGenerateSecretReceiverVariable();
    if (isMethodReference()) {
        if (generateSecretReceiverVariable) {
            this.lhs.generateCode(currentScope, codeStream, true);
            codeStream.store(this.receiverVariable, false);
            codeStream.addVariable(this.receiverVariable);
        }
        MessageSend message = new MessageSend();
        message.selector = this.selector;
        Expression receiver = generateSecretReceiverVariable ? new SingleNameReference(this.receiverVariable.name, 0) : copy.lhs;
        message.receiver = this.receiverPrecedesParameters ? new SingleNameReference(CharOperation.append(ImplicitArgName, Integer.toString(0).toCharArray()), 0) : receiver;
        message.typeArguments = copy.typeArguments;
        message.arguments = argv;
        implicitLambda.setBody(message);
    } else if (isArrayConstructorReference()) {
        // We don't care for annotations, source positions etc. They are immaterial, just drop.
        ArrayAllocationExpression arrayAllocationExpression = new ArrayAllocationExpression();
        arrayAllocationExpression.dimensions = new Expression[] { argv[0] };
        if (this.lhs instanceof ArrayTypeReference) {
            ArrayTypeReference arrayTypeReference = (ArrayTypeReference) this.lhs;
            arrayAllocationExpression.type = arrayTypeReference.dimensions == 1 ? new SingleTypeReference(arrayTypeReference.token, 0L) : new ArrayTypeReference(arrayTypeReference.token, arrayTypeReference.dimensions - 1, 0L);
        } else {
            ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) this.lhs;
            arrayAllocationExpression.type = arrayQualifiedTypeReference.dimensions == 1 ? new QualifiedTypeReference(arrayQualifiedTypeReference.tokens, arrayQualifiedTypeReference.sourcePositions) : new ArrayQualifiedTypeReference(arrayQualifiedTypeReference.tokens, arrayQualifiedTypeReference.dimensions - 1, arrayQualifiedTypeReference.sourcePositions);
        }
        implicitLambda.setBody(arrayAllocationExpression);
    } else {
        AllocationExpression allocation = new AllocationExpression();
        if (this.lhs instanceof TypeReference) {
            allocation.type = (TypeReference) this.lhs;
        } else if (this.lhs instanceof SingleNameReference) {
            allocation.type = new SingleTypeReference(((SingleNameReference) this.lhs).token, 0);
        } else if (this.lhs instanceof QualifiedNameReference) {
            allocation.type = new QualifiedTypeReference(((QualifiedNameReference) this.lhs).tokens, new long[((QualifiedNameReference) this.lhs).tokens.length]);
        } else {
            // $NON-NLS-1$
            throw new IllegalStateException("Unexpected node type");
        }
        allocation.typeArguments = copy.typeArguments;
        allocation.arguments = argv;
        implicitLambda.setBody(allocation);
    }
    // Process the lambda, taking care not to double report diagnostics. Don't expect any from resolve, Any from code generation should surface, but not those from flow analysis.
    BlockScope lambdaScope = this.receiverVariable != null ? this.receiverVariable.declaringScope : currentScope;
    IErrorHandlingPolicy oldPolicy = lambdaScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
    try {
        implicitLambda.resolveType(lambdaScope, true);
        implicitLambda.analyseCode(lambdaScope, new FieldInitsFakingFlowContext(null, this, Binding.NO_EXCEPTIONS, null, lambdaScope, FlowInfo.DEAD_END), UnconditionalFlowInfo.fakeInitializedFlowInfo(lambdaScope.outerMostMethodScope().analysisIndex, lambdaScope.referenceType().maxFieldCount));
    } finally {
        lambdaScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
    }
    SyntheticArgumentBinding[] outerLocals = this.receiverType.syntheticOuterLocalVariables();
    for (int i = 0, length = outerLocals == null ? 0 : outerLocals.length; i < length; i++) implicitLambda.addSyntheticArgument(outerLocals[i].actualOuterLocalVariable);
    implicitLambda.generateCode(lambdaScope, codeStream, valueRequired);
    if (generateSecretReceiverVariable) {
        codeStream.removeVariable(this.receiverVariable);
    }
}
Also used : IErrorHandlingPolicy(org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy) FieldInitsFakingFlowContext(org.eclipse.jdt.internal.compiler.flow.FieldInitsFakingFlowContext) SyntheticArgumentBinding(org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding) BlockScope(org.eclipse.jdt.internal.compiler.lookup.BlockScope)

Aggregations

IErrorHandlingPolicy (org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy)1 FieldInitsFakingFlowContext (org.eclipse.jdt.internal.compiler.flow.FieldInitsFakingFlowContext)1 BlockScope (org.eclipse.jdt.internal.compiler.lookup.BlockScope)1 SyntheticArgumentBinding (org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding)1