Search in sources :

Example 1 with AbortMethod

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

the class Clinit method generateCode.

/**
 * Bytecode generation for a <clinit> method
 *
 * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
 */
@Override
public void generateCode(ClassScope classScope, ClassFile classFile) {
    int clinitOffset = 0;
    if (this.ignoreFurtherInvestigation) {
        // should never have to add any <clinit> problem method
        return;
    }
    CompilationResult unitResult = null;
    int problemCount = 0;
    if (classScope != null) {
        TypeDeclaration referenceContext = classScope.referenceContext;
        if (referenceContext != null) {
            unitResult = referenceContext.compilationResult();
            problemCount = unitResult.problemCount;
        }
    }
    boolean restart = false;
    do {
        try {
            clinitOffset = classFile.contentsOffset;
            this.generateCode(classScope, classFile, clinitOffset);
            restart = false;
        } catch (AbortMethod e) {
            // cases.
            if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
                // a branch target required a goto_w, restart code gen in wide mode.
                classFile.contentsOffset = clinitOffset;
                classFile.methodCount--;
                // request wide mode
                classFile.codeStream.resetInWideMode();
                // reset the problem count to prevent reporting the same warning twice
                if (unitResult != null) {
                    unitResult.problemCount = problemCount;
                }
                // restart method generation
                restart = true;
            } else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
                classFile.contentsOffset = clinitOffset;
                classFile.methodCount--;
                classFile.codeStream.resetForCodeGenUnusedLocals();
                // reset the problem count to prevent reporting the same warning twice
                if (unitResult != null) {
                    unitResult.problemCount = problemCount;
                }
                // restart method generation
                restart = true;
            } else {
                // produce a problem method accounting for this fatal error
                classFile.contentsOffset = clinitOffset;
                classFile.methodCount--;
                restart = false;
            }
        }
    } while (restart);
}
Also used : CompilationResult(org.eclipse.jdt.internal.compiler.CompilationResult) AbortMethod(org.eclipse.jdt.internal.compiler.problem.AbortMethod)

Example 2 with AbortMethod

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

the class Clinit method analyseCode.

public void analyseCode(ClassScope classScope, InitializationFlowContext staticInitializerFlowContext, FlowInfo flowInfo) {
    if (this.ignoreFurtherInvestigation)
        return;
    try {
        ExceptionHandlingFlowContext clinitContext = new ExceptionHandlingFlowContext(staticInitializerFlowContext.parent, this, Binding.NO_EXCEPTIONS, staticInitializerFlowContext, this.scope, FlowInfo.DEAD_END);
        // check for missing returning path
        if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
            this.bits |= ASTNode.NeedFreeReturn;
        }
        // check missing blank final field initializations
        flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn);
        FieldBinding[] fields = this.scope.enclosingSourceType().fields();
        for (int i = 0, count = fields.length; i < count; i++) {
            FieldBinding field = fields[i];
            if (field.isStatic()) {
                if (!flowInfo.isDefinitelyAssigned(field)) {
                    if (field.isFinal()) {
                        this.scope.problemReporter().uninitializedBlankFinalField(field, this.scope.referenceType().declarationOf(field.original()));
                    // can complain against the field decl, since only one <clinit>
                    } else if (field.isNonNull()) {
                        this.scope.problemReporter().uninitializedNonNullField(field, this.scope.referenceType().declarationOf(field.original()));
                    }
                }
            }
        }
        // check static initializers thrown exceptions
        staticInitializerFlowContext.checkInitializerExceptions(this.scope, clinitContext, flowInfo);
    } catch (AbortMethod e) {
        this.ignoreFurtherInvestigation = true;
    }
}
Also used : FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) ExceptionHandlingFlowContext(org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext) AbortMethod(org.eclipse.jdt.internal.compiler.problem.AbortMethod)

Example 3 with AbortMethod

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

the class LambdaExpression method generateCode.

public void generateCode(ClassFile classFile) {
    classFile.generateMethodInfoHeader(this.binding);
    int methodAttributeOffset = classFile.contentsOffset;
    int attributeNumber = classFile.generateMethodInfoAttributes(this.binding);
    int codeAttributeOffset = classFile.contentsOffset;
    classFile.generateCodeAttributeHeader();
    CodeStream codeStream = classFile.codeStream;
    codeStream.reset(this, classFile);
    // initialize local positions
    this.scope.computeLocalVariablePositions(this.outerLocalVariablesSlotSize + (this.binding.isStatic() ? 0 : 1), codeStream);
    if (this.outerLocalVariables != null) {
        for (int i = 0, max = this.outerLocalVariables.length; i < max; i++) {
            LocalVariableBinding argBinding;
            codeStream.addVisibleLocalVariable(argBinding = this.outerLocalVariables[i]);
            codeStream.record(argBinding);
            argBinding.recordInitializationStartPC(0);
        }
    }
    // arguments initialization for local variable debug attributes
    if (this.arguments != null) {
        for (int i = 0, max = this.arguments.length; i < max; i++) {
            LocalVariableBinding argBinding;
            codeStream.addVisibleLocalVariable(argBinding = this.arguments[i].binding);
            argBinding.recordInitializationStartPC(0);
        }
    }
    if (this.body instanceof Block) {
        this.body.generateCode(this.scope, codeStream);
        if ((this.bits & ASTNode.NeedFreeReturn) != 0) {
            codeStream.return_();
        }
    } else {
        Expression expression = (Expression) this.body;
        expression.generateCode(this.scope, codeStream, true);
        if (this.binding.returnType == TypeBinding.VOID) {
            codeStream.return_();
        } else {
            codeStream.generateReturnBytecode(expression);
        }
    }
    // local variable attributes
    codeStream.exitUserScope(this.scope);
    // WAS declarationSourceEnd.
    codeStream.recordPositionsFrom(0, this.sourceEnd);
    try {
        classFile.completeCodeAttribute(codeAttributeOffset, this.scope);
    } catch (NegativeArraySizeException e) {
        throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
    }
    attributeNumber++;
    classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
}
Also used : CodeStream(org.eclipse.jdt.internal.compiler.codegen.CodeStream) LocalVariableBinding(org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding) AbortMethod(org.eclipse.jdt.internal.compiler.problem.AbortMethod)

Example 4 with AbortMethod

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

the class MethodDeclaration method analyseCode.

public void analyseCode(ClassScope classScope, FlowContext flowContext, FlowInfo flowInfo) {
    // starting of the code analysis for methods
    if (this.ignoreFurtherInvestigation)
        return;
    try {
        if (this.binding == null)
            return;
        if (!this.binding.isUsed() && !this.binding.isAbstract()) {
            if (this.binding.isPrivate() || (((this.binding.modifiers & (ExtraCompilerModifiers.AccOverriding | ExtraCompilerModifiers.AccImplementing)) == 0) && this.binding.isOrEnclosedByPrivateType())) {
                if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
                    this.scope.problemReporter().unusedPrivateMethod(this);
                }
            }
        }
        // skip enum implicit methods
        if (this.binding.declaringClass.isEnum() && (this.selector == TypeConstants.VALUES || this.selector == TypeConstants.VALUEOF))
            return;
        // may be in a non necessary <clinit> for innerclass with static final constant fields
        if (this.binding.isAbstract() || this.binding.isNative())
            return;
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=385780
        if (this.typeParameters != null && !this.scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
            for (int i = 0, length = this.typeParameters.length; i < length; ++i) {
                TypeParameter typeParameter = this.typeParameters[i];
                if ((typeParameter.binding.modifiers & ExtraCompilerModifiers.AccLocallyUsed) == 0) {
                    this.scope.problemReporter().unusedTypeParameter(typeParameter);
                }
            }
        }
        ExceptionHandlingFlowContext methodContext = new ExceptionHandlingFlowContext(flowContext, this, this.binding.thrownExceptions, null, this.scope, FlowInfo.DEAD_END);
        // nullity and mark as assigned
        analyseArguments(classScope.environment(), flowInfo, this.arguments, this.binding);
        if (this.binding.declaringClass instanceof MemberTypeBinding && !this.binding.declaringClass.isStatic()) {
            // method of a non-static member type can't be static.
            this.bits &= ~ASTNode.CanBeStatic;
        }
        // propagate to statements
        if (this.statements != null) {
            CompilerOptions compilerOptions = this.scope.compilerOptions();
            boolean enableSyntacticNullAnalysisForFields = compilerOptions.enableSyntacticNullAnalysisForFields;
            int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
            for (int i = 0, count = this.statements.length; i < count; i++) {
                Statement stat = this.statements[i];
                if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
                    flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo);
                }
                if (enableSyntacticNullAnalysisForFields) {
                    methodContext.expireNullCheckedFieldInfo();
                }
                if (compilerOptions.analyseResourceLeaks) {
                    FakedTrackingVariable.cleanUpUnassigned(this.scope, stat, flowInfo);
                }
            }
        } else {
            // method with empty body should not be flagged as static.
            this.bits &= ~ASTNode.CanBeStatic;
        }
        // check for missing returning path
        TypeBinding returnTypeBinding = this.binding.returnType;
        if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) {
            if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
                this.bits |= ASTNode.NeedFreeReturn;
            }
        } else {
            if (flowInfo != FlowInfo.DEAD_END) {
                this.scope.problemReporter().shouldReturn(returnTypeBinding, this);
            }
        }
        // check unreachable catch blocks
        methodContext.complainIfUnusedExceptionHandlers(this);
        // check unused parameters
        this.scope.checkUnusedParameters(this.binding);
        // check if the method could have been static
        if (!this.binding.isStatic() && (this.bits & ASTNode.CanBeStatic) != 0 && !this.isDefaultMethod()) {
            if (!this.binding.isOverriding() && !this.binding.isImplementing()) {
                if (this.binding.isPrivate() || this.binding.isFinal() || this.binding.declaringClass.isFinal()) {
                    this.scope.problemReporter().methodCanBeDeclaredStatic(this);
                } else {
                    this.scope.problemReporter().methodCanBePotentiallyDeclaredStatic(this);
                }
            }
        }
        this.scope.checkUnclosedCloseables(flowInfo, null, null, /*don't report against a specific location*/
        null);
    } catch (AbortMethod e) {
        this.ignoreFurtherInvestigation = true;
    }
}
Also used : MemberTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding) MemberTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding) LocalTypeBinding(org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) CompilerOptions(org.eclipse.jdt.internal.compiler.impl.CompilerOptions) ExceptionHandlingFlowContext(org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext) AbortMethod(org.eclipse.jdt.internal.compiler.problem.AbortMethod)

Example 5 with AbortMethod

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

the class SingleNameReference method generatePostIncrement.

@Override
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
    switch(this.bits & ASTNode.RestrictiveFlagMASK) {
        case // assigning to a field
        Binding.FIELD:
            FieldBinding fieldBinding = (FieldBinding) this.binding;
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
            // check if postIncrement is the only usage of a private field
            reportOnlyUselesslyReadPrivateField(currentScope, fieldBinding, valueRequired);
            FieldBinding codegenField = fieldBinding.original();
            if (codegenField.isStatic()) {
                if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
                    TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true);
                    codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
                } else {
                    codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null);
                }
            } else {
                if ((this.bits & ASTNode.DepthMASK) != 0) {
                    ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
                    Object[] emulationPath = currentScope.getEmulationPath(targetType, true, /*only exact match*/
                    false);
                    codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
                } else {
                    codeStream.aload_0();
                }
                codeStream.dup();
                if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
                    TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true);
                    codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
                } else {
                    codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null);
                }
            }
            TypeBinding operandType;
            if (this.genericCast != null) {
                codeStream.checkcast(this.genericCast);
                operandType = this.genericCast;
            } else {
                operandType = codegenField.type;
            }
            if (valueRequired) {
                if (codegenField.isStatic()) {
                    switch(operandType.id) {
                        case TypeIds.T_long:
                        case TypeIds.T_double:
                            codeStream.dup2();
                            break;
                        default:
                            codeStream.dup();
                            break;
                    }
                } else {
                    // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
                    switch(operandType.id) {
                        case TypeIds.T_long:
                        case TypeIds.T_double:
                            codeStream.dup2_x1();
                            break;
                        default:
                            codeStream.dup_x1();
                            break;
                    }
                }
            }
            codeStream.generateImplicitConversion(this.implicitConversion);
            codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
            codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
            codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
            fieldStore(currentScope, codeStream, codegenField, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], this.actualReceiverType, true, /*implicit this*/
            false);
            // no need for generic cast
            return;
        case // assigning to a local variable
        Binding.LOCAL:
            LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
            // check if postIncrement is the only usage of this local
            Reference.reportOnlyUselesslyReadLocal(currentScope, localBinding, valueRequired);
            if (localBinding.resolvedPosition == -1) {
                if (valueRequired) {
                    // restart code gen
                    localBinding.useFlag = LocalVariableBinding.USED;
                    throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
                }
                return;
            }
            // using incr bytecode if possible
            if (TypeBinding.equalsEquals(localBinding.type, TypeBinding.INT)) {
                if (valueRequired) {
                    codeStream.load(localBinding);
                }
                if (postIncrement.operator == OperatorIds.PLUS) {
                    codeStream.iinc(localBinding.resolvedPosition, 1);
                } else {
                    codeStream.iinc(localBinding.resolvedPosition, -1);
                }
            } else {
                codeStream.load(localBinding);
                if (valueRequired) {
                    switch(localBinding.type.id) {
                        case TypeIds.T_long:
                        case TypeIds.T_double:
                            codeStream.dup2();
                            break;
                        default:
                            codeStream.dup();
                            break;
                    }
                }
                codeStream.generateImplicitConversion(this.implicitConversion);
                codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
                codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
                codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
                codeStream.store(localBinding, false);
            }
    }
}
Also used : SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) ProblemFieldBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) LocalVariableBinding(org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding) AbortMethod(org.eclipse.jdt.internal.compiler.problem.AbortMethod)

Aggregations

AbortMethod (org.eclipse.jdt.internal.compiler.problem.AbortMethod)8 FieldBinding (org.eclipse.jdt.internal.compiler.lookup.FieldBinding)4 LocalVariableBinding (org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding)4 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)4 MissingTypeBinding (org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding)3 ProblemFieldBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding)3 ProblemReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding)3 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)3 SourceTypeBinding (org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)3 ExceptionHandlingFlowContext (org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext)2 Constant (org.eclipse.jdt.internal.compiler.impl.Constant)2 CompilationResult (org.eclipse.jdt.internal.compiler.CompilationResult)1 CodeStream (org.eclipse.jdt.internal.compiler.codegen.CodeStream)1 CompilerOptions (org.eclipse.jdt.internal.compiler.impl.CompilerOptions)1 LocalTypeBinding (org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding)1 MemberTypeBinding (org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding)1 MethodBinding (org.eclipse.jdt.internal.compiler.lookup.MethodBinding)1 PolymorphicMethodBinding (org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding)1 SyntheticMethodBinding (org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding)1 VariableBinding (org.eclipse.jdt.internal.compiler.lookup.VariableBinding)1