Skip to content

Commit

Permalink
Merge branch 'eclipse-jdt:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
carstenartur authored Nov 13, 2024
2 parents 8aba60c + 74ec8f9 commit a3d1067
Show file tree
Hide file tree
Showing 23 changed files with 457 additions and 685 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ public void generateCode(ClassFile classFile) {
for (Statement stmt : this.statements) {
stmt.generateCode(this.scope, codeStream);
if (!this.compilationResult.hasErrors() && (codeStream.stackDepth != 0 || codeStream.operandStack.size() != 0)) {
// this.scope.problemReporter().operandStackSizeInappropriate(this);
this.scope.problemReporter().operandStackSizeInappropriate(this);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
if (this.statementsWithFinallyBlock != null){
for (int i = 0, max = this.statementsWithFinallyBlock.length; i < max; i++){
StatementWithFinallyBlock stmt = this.statementsWithFinallyBlock[i];
boolean didEscape = stmt.generateFinallyBlock(currentScope, codeStream, this.targetLabel, this.initStateIndex);
boolean didEscape = stmt.generateFinallyBlock(currentScope, codeStream, this.initStateIndex);
if (didEscape) {
codeStream.recordPositionsFrom(pc, this.sourceStart);
StatementWithFinallyBlock.reenterAllExceptionHandlers(this.statementsWithFinallyBlock, i, codeStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1251,18 +1251,6 @@ public boolean forcedToBeRaw(ReferenceContext referenceContext) {
return false;
}

/**
* Returns an object which can be used to identify identical JSR sequence targets
* (see TryStatement finally block codegen)
* or <code>null</code> if not reusable
*/
public Object reusableJSRTarget() {
if (this.constant != Constant.NotAConstant && (this.implicitConversion & TypeIds.BOXING) == 0) {
return this.constant;
}
return null;
}

/**
* Record the type expectation before this expression is typechecked.
* e.g. String s = foo();, foo() will be tagged as being expected of type String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
return FlowInfo.NULL;
}

@Override
public Object reusableJSRTarget() {
return TypeBinding.NULL;
}

@Override
public char[] source() {
return source;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,9 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {

// generation of code responsible for invoking the finally blocks in sequence
if (this.statementsWithFinallyBlock != null) {
Object reusableJSRTarget = this.expression == null ? (Object)TypeBinding.VOID : this.expression.reusableJSRTarget();
for (int i = 0, max = this.statementsWithFinallyBlock.length; i < max; i++) {
StatementWithFinallyBlock stmt = this.statementsWithFinallyBlock[i];
boolean didEscape = stmt.generateFinallyBlock(currentScope, codeStream, reusableJSRTarget, this.initStateIndex);
boolean didEscape = stmt.generateFinallyBlock(currentScope, codeStream, this.initStateIndex);
if (didEscape) {
codeStream.recordPositionsFrom(pc, this.sourceStart);
StatementWithFinallyBlock.reenterAllExceptionHandlers(this.statementsWithFinallyBlock, i, codeStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void enterDeclaredExceptionHandlers(CodeStream codeStream) {
public void enterResourceExceptionHandlers(CodeStream codeStream) {
// do nothing by default
}

public void exitAnyExceptionHandler() {
if (this.anyExceptionLabel != null) {
this.anyExceptionLabel.placeEnd();
Expand All @@ -66,7 +66,7 @@ public void exitDeclaredExceptionHandlers(CodeStream codeStream) {
* Generate the finally block in current context.
* @return boolean, <code>true</code> if the generated code will complete abruptly.
*/
public abstract boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex);
public abstract boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStream, int stateIndex);

public abstract boolean isFinallyBlockEscaping();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
}

/**
* @see StatementWithFinallyBlock#generateFinallyBlock(BlockScope, CodeStream, Object, int)
* @see StatementWithFinallyBlock#generateFinallyBlock(BlockScope, CodeStream, int)
*/
@Override
public boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex) {
public boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStream, int stateIndex) {
codeStream.load(this.synchroVariable);
codeStream.monitorexit();
exitAnyExceptionHandler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.JavaFeature;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;

public class TryStatement extends StatementWithFinallyBlock {

Expand Down Expand Up @@ -79,12 +80,6 @@ public class TryStatement extends StatementWithFinallyBlock {

ExceptionLabel[] declaredExceptionLabels; // only set while generating code

// for sharing finally blocks - behavior disabled by https://bugs.eclipse.org/bugs/show_bug.cgi?id=404146; can be enabled only by an undocumented option.
private Object[] reusableJSRTargets;
private BranchLabel[] reusableJSRSequenceStartLabels;
private int[] reusableJSRStateIndexes;
private int reusableJSRTargetsCount = 0;

private static final int NO_FINALLY = 0; // no finally block
private static final int FINALLY_DOES_NOT_COMPLETE = 2; // non returning finally is optimized with only one instance of finally block
private static final int FINALLY_INLINE = 3; // finally block must be inlined
Expand Down Expand Up @@ -930,60 +925,11 @@ private boolean isDuplicateResourceReference(int index) {
return false;
}

// Disabled behavior enabled only by an undocumented option. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=404146
private boolean reusedFinallyBlock(CodeStream codeStream, Object targetLocation, int stateIndex) {
// optimize finally block generation, using the targetLocation (if any)
CompilerOptions options = this.scope.compilerOptions();
if (options.shareCommonFinallyBlocks && targetLocation != null) {
boolean reuseTargetLocation = true;
if (this.reusableJSRTargetsCount > 0) {
nextReusableTarget: for (int i = 0, count = this.reusableJSRTargetsCount; i < count; i++) {
Object reusableJSRTarget = this.reusableJSRTargets[i];
differentTarget: {
if (targetLocation == reusableJSRTarget)
break differentTarget;
if (targetLocation instanceof Constant
&& reusableJSRTarget instanceof Constant
&& ((Constant)targetLocation).hasSameValue((Constant) reusableJSRTarget)) {
break differentTarget;
}
// cannot reuse current target
continue nextReusableTarget;
}
// current target has been used in the past, simply branch to its label
if ((this.reusableJSRStateIndexes[i] != stateIndex) && finallyMode() == FINALLY_INLINE) {
reuseTargetLocation = false;
break nextReusableTarget;
} else {
codeStream.goto_(this.reusableJSRSequenceStartLabels[i]);
return true;
}
}
} else {
this.reusableJSRTargets = new Object[3];
this.reusableJSRSequenceStartLabels = new BranchLabel[3];
this.reusableJSRStateIndexes = new int[3];
}
if (reuseTargetLocation) {
if (this.reusableJSRTargetsCount == this.reusableJSRTargets.length) {
System.arraycopy(this.reusableJSRTargets, 0, this.reusableJSRTargets = new Object[2*this.reusableJSRTargetsCount], 0, this.reusableJSRTargetsCount);
System.arraycopy(this.reusableJSRSequenceStartLabels, 0, this.reusableJSRSequenceStartLabels = new BranchLabel[2*this.reusableJSRTargetsCount], 0, this.reusableJSRTargetsCount);
System.arraycopy(this.reusableJSRStateIndexes, 0, this.reusableJSRStateIndexes = new int[2*this.reusableJSRTargetsCount], 0, this.reusableJSRTargetsCount);
}
this.reusableJSRTargets[this.reusableJSRTargetsCount] = targetLocation;
BranchLabel reusableJSRSequenceStartLabel = new BranchLabel(codeStream);
reusableJSRSequenceStartLabel.place();
this.reusableJSRStateIndexes[this.reusableJSRTargetsCount] = stateIndex;
this.reusableJSRSequenceStartLabels[this.reusableJSRTargetsCount++] = reusableJSRSequenceStartLabel;
}
}
return false;
}
/**
* @see StatementWithFinallyBlock#generateFinallyBlock(BlockScope, CodeStream, Object, int)
* @see StatementWithFinallyBlock#generateFinallyBlock(BlockScope, CodeStream, int)
*/
@Override
public boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex) {
public boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStream, int stateIndex) {

int resourceCount = this.resources.length;
if (resourceCount > 0 && this.resourceExceptionLabels != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=375248
Expand All @@ -1007,21 +953,16 @@ public boolean generateFinallyBlock(BlockScope currentScope, CodeStream codeStre
case NO_FINALLY:
exitDeclaredExceptionHandlers(codeStream);
return false;
case FINALLY_INLINE:
((StackMapFrameCodeStream) codeStream).pushStateIndex(stateIndex);
exitAnyExceptionHandler();
exitDeclaredExceptionHandlers(codeStream);
this.finallyBlock.generateCode(currentScope, codeStream);
((StackMapFrameCodeStream) codeStream).popStateIndex();
return false;
default:
throw EclipseCompiler.REACHED_DEAD_CODE;
}

/********* Begin: undocumented behavior off by default ******* */
if (reusedFinallyBlock( codeStream, targetLocation, stateIndex))
return true;
/********* End: undocumented behavior off by default ******* */

if (finallyMode == FINALLY_INLINE) {
((StackMapFrameCodeStream) codeStream).pushStateIndex(stateIndex);
exitAnyExceptionHandler();
exitDeclaredExceptionHandlers(codeStream);
this.finallyBlock.generateCode(currentScope, codeStream);
((StackMapFrameCodeStream) codeStream).popStateIndex();
}
return false;
}
@Override
public boolean isFinallyBlockEscaping() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
// inline finally blocks in sequence
for (int i = 0, max = this.statementsWithFinallyBlock.length; i < max; i++) {
StatementWithFinallyBlock stmt = this.statementsWithFinallyBlock[i];
boolean didEscape = stmt.generateFinallyBlock(currentScope, codeStream, this.expression.reusableJSRTarget(), this.initStateIndex);
boolean didEscape = stmt.generateFinallyBlock(currentScope, codeStream, this.initStateIndex);
if (didEscape) {
codeStream.recordPositionsFrom(pc, this.sourceStart);
StatementWithFinallyBlock.reenterAllExceptionHandlers(this.statementsWithFinallyBlock, i, codeStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,6 @@ public class CompilerOptions {
public int reportMissingJavadocCommentsVisibility;
/** Specify if need to flag missing javadoc comment for overriding method */
public boolean reportMissingJavadocCommentsOverriding;
/** Indicate whether common escaping finally blocks should be shared */
public boolean shareCommonFinallyBlocks;
/** Indicate if @SuppressWarning annotations are activated */
public boolean suppressWarnings;
/** Indicate if @SuppressWarning annotations should also suppress optional errors */
Expand Down Expand Up @@ -1427,7 +1425,7 @@ public Map<String, String> getMap() {
optionsMap.put(OPTION_ReportUnusedParameterIncludeDocCommentReference, this.reportUnusedParameterIncludeDocCommentReference ? ENABLED : DISABLED);
optionsMap.put(OPTION_ReportSpecialParameterHidingField, this.reportSpecialParameterHidingField ? ENABLED : DISABLED);
optionsMap.put(OPTION_MaxProblemPerUnit, String.valueOf(this.maxProblemsPerUnit));
optionsMap.put(OPTION_ShareCommonFinallyBlocks, this.shareCommonFinallyBlocks ? ENABLED : DISABLED);
optionsMap.put(OPTION_ShareCommonFinallyBlocks, DISABLED);
optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference));
optionsMap.put(OPTION_ReportPotentialNullReference, getSeverityString(PotentialNullReference));
optionsMap.put(OPTION_ReportRedundantNullCheck, getSeverityString(RedundantNullCheck));
Expand Down Expand Up @@ -1640,9 +1638,6 @@ protected void resetDefaults() {
this.reportMissingJavadocCommentsVisibility = ClassFileConstants.AccPublic;
this.reportMissingJavadocCommentsOverriding = false;

// JSR bytecode and sharing
this.shareCommonFinallyBlocks = false;

// javadoc comment support
this.docCommentSupport = false;

Expand Down Expand Up @@ -1877,11 +1872,7 @@ public void set(Map<String, String> optionsMap) {
}
}
if ((optionValue = optionsMap.get(OPTION_ShareCommonFinallyBlocks)) != null) {
if (ENABLED.equals(optionValue)) {
this.shareCommonFinallyBlocks = true;
} else if (DISABLED.equals(optionValue)) {
this.shareCommonFinallyBlocks = false;
}
// withdrawn support
}
if ((optionValue = optionsMap.get(OPTION_MethodParametersAttribute)) != null) {
if (GENERATE.equals(optionValue)) {
Expand Down Expand Up @@ -2353,7 +2344,6 @@ public String toString() {
buf.append("\n\t- report unused parameter when overriding concrete method : ").append(this.reportUnusedParameterWhenOverridingConcrete ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- report unused parameter include doc comment reference : ").append(this.reportUnusedParameterIncludeDocCommentReference ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- report constructor/setter parameter hiding existing field : ").append(this.reportSpecialParameterHidingField ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- share common finally blocks : ").append(this.shareCommonFinallyBlocks ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- report unavoidable generic type problems : ").append(this.reportUnavoidableGenericTypeProblems ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- unsafe type operation: ").append(getSeverityString(UncheckedTypeOperation)); //$NON-NLS-1$
buf.append("\n\t- unsafe raw type: ").append(getSeverityString(RawTypeReference)); //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ public class Scanner implements TerminalTokens {

public boolean fakeInModule = false;
boolean inCondition = false;
private boolean atClassicSwitchLabel = false;
boolean breakPreviewAllowed = false;
/**
* The current context of the scanner w.r.t restricted keywords
Expand Down Expand Up @@ -3290,28 +3289,20 @@ final void resetLookBack() {
* @see #lookBack
*/
final void addTokenToLookBack(int newToken) {
this.atClassicSwitchLabel = false;
switch (newToken) {
case TokenNameWHITESPACE:
case TokenNameCOMMENT_LINE:
case TokenNameCOMMENT_BLOCK:
case TokenNameCOMMENT_JAVADOC:
return;
case TokenNamecase:
this.scanningSwitchLabel = true;
break;
case TokenNameCaseArrow:
}
if (newToken == TokenNamecase)
this.scanningSwitchLabel = true;
else if (newToken == TokenNameCaseArrow)
this.scanningSwitchLabel = false;
else if (this.scanningSwitchLabel && this.lookBack[1] == TokenNameCOLON) {
if (this.activeParser == null || this.activeParser.automatonWillShift(TokenNamecase))
this.scanningSwitchLabel = false;
break;
case TokenNameCOLON:
if (this.lookBack[1] == TokenNamedefault)
this.atClassicSwitchLabel = true;
if (this.scanningSwitchLabel)
if (this.activeParser == null || this.activeParser.automatonWillShift(TokenNameCaseArrow)) {
this.scanningSwitchLabel = false;
this.atClassicSwitchLabel = true;
}
break;
}
this.lookBack[0] = this.lookBack[1];
this.lookBack[1] = newToken;
Expand Down Expand Up @@ -5433,10 +5424,6 @@ public static boolean isRestrictedKeyword(int token) {
private boolean mayBeAtAnYieldStatement() {
if (isInModuleDeclaration())
return false;

if (this.atClassicSwitchLabel)
return true;

// preceded by ;, {, }, ), or -> [Ref: http://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-May/001401.html]
// above comment is super-seded by http://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-May/001414.html
switch (this.lookBack[1]) {
Expand All @@ -5448,6 +5435,7 @@ private boolean mayBeAtAnYieldStatement() {
case TokenNamedo:
return true;
case TokenNameCOLON:
return this.lookBack[0] == TokenNamedefault || (this.scanningSwitchLabel && (this.activeParser == null || this.activeParser.automatonWillShift(TokenNamecase)));
case TokenNameDOT:
case TokenNameARROW:
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class EclipseCompiler implements JavaCompiler {
WeakHashMap<Thread, EclipseCompilerImpl> threadCache;
public DiagnosticListener<? super JavaFileObject> diagnosticListener;

public static final RuntimeException REACHED_DEAD_CODE = new RuntimeException() { private static final long serialVersionUID = 1L; };

public EclipseCompiler() {
this.threadCache = new WeakHashMap<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8321,4 +8321,29 @@ public static void main(String[] args) {
},
"special");
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3283
// ECJ fails to recognize "yield" as a contextual keyword when there is a case fall-through
public void testIssue3283() {
this.runConformTest(
new String[] {
"X.java",
"""
public class X {
public static int var = 0;
public static void main(String argv[]) {
int j = switch(var){
case 0: yield (0 + 42); // If this is removed, there's a different error
case 1: // If I remove this line, the error goes away
case 2: yield 1; // multiple errors
default:
throw new IllegalArgumentException("Unexpected value: " + var);
};
System.out.println("Yield = " + j);
}
}
"""
},
"Yield = 42");
}
}
Loading

0 comments on commit a3d1067

Please sign in to comment.