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);
}
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;
}
}
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);
}
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;
}
}
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);
}
}
}
Aggregations