Skip to content

Commit

Permalink
Eclipse 4.22 (M3) JDT Patch for Groovy-Eclipse
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 12, 2021
1 parent 39e19d5 commit 07d8466
Show file tree
Hide file tree
Showing 22 changed files with 215 additions and 106 deletions.
2 changes: 1 addition & 1 deletion groovy-eclipse.setup
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@
<repository
url="https://download.eclipse.org/eclipse/updates/4.22"/>
<repository
url="https://download.eclipse.org/eclipse/updates/4.22-I-builds/I20211023-1800"/>
url="https://download.eclipse.org/eclipse/updates/4.22-I-builds/I20211111-0910"/>
</repositoryList>
<repositoryList
name="2021-09">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</license>

<requires>
<import feature="org.eclipse.jdt" version="3.18.1000.v20211023-1800" patch="true"/>
<import feature="org.eclipse.jdt" version="3.18.1000.v20211111-0910" patch="true"/>
</requires>

<plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,12 @@ public void test_switchNullInSameCase() {
" }\n" +
"}\n"
};
// demonstrate that null case cannot leak into a type pattern:
runner.expectedCompilerLog =
"----------\n" +
"1. ERROR in X.java (at line 5)\n" +
" case null, Integer i -> consumeInt(i);\n" +
" ^^^^^^^^^\n" +
"Illegal fall-through to a pattern\n" +
" ^\n" +
"Null type mismatch: required \'@NonNull Integer\' but the provided value is inferred as @Nullable\n" +
"----------\n";
runner.runNegativeTest();
}
Expand Down Expand Up @@ -492,4 +491,54 @@ public void test_defaultDoesNotApplyToNull_field() {
runner.expectedOutputString = "null";
runner.runConformTest();
}

public void test_defaultDoesNotApplyToNull_field2() {
Runner runner = getDefaultRunner();
runner.customOptions.put(CompilerOptions.OPTION_SyntacticNullAnalysisForFields, CompilerOptions.ENABLED);
runner.testFiles = new String[] {
"X.java",
"import org.eclipse.jdt.annotation.*;\n" +
"public class X {\n" +
" @Nullable Object o;\n" +
" void foo(X x) {\n" +
" switch (x.o) {\n" +
" case Integer i -> consumeInt(i);\n" +
" default -> System.out.println(x.o.toString());\n" +
" case null -> System.out.print(\"null\");\n" +
" };\n" +
" }\n" +
" void consumeInt(@NonNull Integer i) {\n" +
" }\n" +
" public static void main(String... args) {\n" +
" new X().foo(new X());\n" +
" }\n" +
"}\n"
};
runner.expectedCompilerLog = "";
runner.expectedOutputString = "null";
runner.runConformTest();
}

public void testBug576329() {
Runner runner = getDefaultRunner();
runner.customOptions.put(CompilerOptions.OPTION_SyntacticNullAnalysisForFields, CompilerOptions.ENABLED);
runner.testFiles = new String[] {
"Main.java",
"public class Main {\n" +
" int length;\n" +
" public String switchOnArray(Object argv[]) {\n" +
" return switch(argv.length) {\n" +
" case 0 -> \"0\";\n" +
" default -> \"x\";\n" +
" };\n" +
" }\n" +
" public static void main(String... args) {\n" +
" System.out.print(new Main().switchOnArray(args));\n" +
" }\n" +
"}\n"
};
runner.expectedCompilerLog = "";
runner.expectedOutputString = "0";
runner.runConformTest();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6115,4 +6115,25 @@ public void testBug576026() {
},
"Success");
}
public void testBug576861_001() {
this.runConformTest(
new String[] {
"X.java",
"import java.util.Comparator;\n"+
"\n"+
"public class X {\n"+
" public static void foo(Comparator<? super Long> comparator) {}\n"+
"\n"+
" public static void main(String[] args) {\n"+
" int someSwitchCondition = 10;\n"+
" X.foo(switch (someSwitchCondition) {\n"+
" case 10 -> Comparator.comparingLong(Long::longValue);\n"+
" default -> throw new IllegalArgumentException(\"Unsupported\");\n"+
" });\n"+
" System.out.println(\"hello\");\n"+
" }\n"+
"}"
},
"hello");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1317,8 +1317,8 @@ private Statement buildMoreCompletionEnclosingContext(Statement statement) {
// collect all if statements with instanceof expressions that enclose the completion node
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304006
while (index >= 0) {
if (this.elementInfoStack[index] == IF && this.elementObjectInfoStack[index] instanceof InstanceOfExpression) {
InstanceOfExpression condition = (InstanceOfExpression)this.elementObjectInfoStack[index];
if (this.elementInfoStack[index] == IF && isInstanceOfGuard(this.elementObjectInfoStack[index])) {
Expression condition = (Expression)this.elementObjectInfoStack[index];
ifStatement =
new IfStatement(
condition,
Expand All @@ -1332,6 +1332,15 @@ private Statement buildMoreCompletionEnclosingContext(Statement statement) {
this.enclosingNode = ifStatement;
return ifStatement;
}
private boolean isInstanceOfGuard(Object object) {
if (object instanceof InstanceOfExpression)
return true;
if (object instanceof AND_AND_Expression) {
AND_AND_Expression expression = (AND_AND_Expression) object;
return isInstanceOfGuard(expression.left) || isInstanceOfGuard(expression.right);
}
return false;
}
private void buildMoreGenericsCompletionContext(ASTNode node, boolean consumeTypeArguments) {
int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
if(kind != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public FlowInfo analyseCode(
currentScope.problemReporter().IllegalFallThroughToPattern(e);
}
analyseConstantExpression(currentScope, flowContext, flowInfo, e);
if (nullPatternCount > 0 && e instanceof TypePattern) {
LocalVariableBinding binding = ((TypePattern) e).local.binding;
if (binding != null)
flowInfo.markNullStatus(binding, FlowInfo.POTENTIALLY_NULL);
}
}
}
return flowInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public class SwitchExpression extends SwitchStatement implements IPolyExpression
private boolean isPolyExpression = false;
private TypeBinding[] originalValueResultExpressionTypes;
private TypeBinding[] finalValueResultExpressionTypes;
/* package */ Map<Expression, TypeBinding> originalTypeMap;


private int nullStatus = FlowInfo.UNKNOWN;
public List<Expression> resultExpressions;
Expand Down Expand Up @@ -473,6 +475,8 @@ public TypeBinding resolveTypeInternal(BlockScope upperScope) {
}
}

if (this.originalTypeMap == null)
this.originalTypeMap = new HashMap<>();
resolve(upperScope);

if (this.statements == null || this.statements.length == 0) {
Expand Down Expand Up @@ -512,7 +516,8 @@ public TypeBinding resolveTypeInternal(BlockScope upperScope) {
return this.resolvedType = null; // error flagging would have been done during the earlier phase.
for (int i = 0; i < resultExpressionsCount; i++) {
Expression resultExpr = this.resultExpressions.get(i);
if (resultExpr.resolvedType == null || resultExpr.resolvedType.kind() == Binding.POLY_TYPE) {
TypeBinding origType = this.originalTypeMap.get(resultExpr);
if (origType == null || origType.kind() == Binding.POLY_TYPE) {
this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] =
resultExpr.resolveTypeExpecting(upperScope, this.expectedType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.JavaFeature;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
Expand Down Expand Up @@ -187,17 +186,19 @@ else if ((statement.bits & ASTNode.DocumentedFallthrough) == 0) { // the case is
this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
}
caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
if ((this.switchBits & LabeledRules) != 0 && this.expression instanceof Reference) {
Reference reference = (Reference) this.expression;
// default case does not apply to null => mark the variable being switched over as nonnull:
switch (reference.bits & ASTNode.RestrictiveFlagMASK) {
case Binding.LOCAL:
if ((this.switchBits & LabeledRules) != 0 && this.expression.resolvedType instanceof ReferenceBinding) {
if (this.expression instanceof NameReference) {
// default case does not apply to null => mark the variable being switched over as nonnull:
NameReference reference = (NameReference) this.expression;
if (reference.localVariableBinding() != null) {
caseInits.markAsDefinitelyNonNull(reference.localVariableBinding());
break;
case Binding.FIELD:
} else if (reference.lastFieldBinding() != null) {
if (this.scope.compilerOptions().enableSyntacticNullAnalysisForFields)
switchContext.recordNullCheckedFieldReference(reference, 2); // survive this case statement and into the next
break;
}
} else if (this.expression instanceof FieldReference) {
if (this.scope.compilerOptions().enableSyntacticNullAnalysisForFields)
switchContext.recordNullCheckedFieldReference((FieldReference) this.expression, 2); // survive this case statement and into the next
}
}
complaintLevel = initialComplaintLevel; // reset complaint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,9 @@ Switch labeled rules in switch statements differ from those in switch expression
this.scope.problemReporter().switchExpressionsYieldOutsideSwitchExpression(this);
}
}
this.expression.resolveType(this.scope);
TypeBinding type = this.expression.resolveType(this.scope);
if (this.switchExpression != null && type != null)
this.switchExpression.originalTypeMap.put(this.expression, type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class ClassFileReader extends ClassFileStruct implements IBinaryType {
private RecordComponentInfo[] recordComponents;

private static String printTypeModifiers(int modifiers) {
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
java.io.StringWriter out = new java.io.StringWriter();
java.io.PrintWriter print = new java.io.PrintWriter(out);

if ((modifiers & ClassFileConstants.AccPublic) != 0) print.print("public "); //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9750,6 +9750,7 @@ private SwitchStatement createSwitchStatementOrExpression(boolean isStmt) {
if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) {
switchStatement.bits |= ASTNode.UndocumentedEmptyBlock;
}
this.scanner.caseStartPosition = -1; // safety: at the end of a switch we definitely leave the scope of this value
return switchStatement;
}
protected void consumeStatementSwitch() {
Expand Down Expand Up @@ -9993,6 +9994,7 @@ protected void consumeSwitchLabels() {
protected void consumeSwitchLabelCaseLhs() {
if (this.scanner.lookBack[1] == TerminalTokens.TokenNameCOLON) // kludge for yield :(
this.scanner.yieldColons = 1;
this.scanner.caseStartPosition = -1; // value has expired
}
protected void consumeCaseLabelExpr() {
// SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr '->'
Expand Down Expand Up @@ -14436,6 +14438,8 @@ protected int resumeOnSyntaxError() {
if (this.lastPosistion < this.scanner.currentPosition) {
this.lastPosistion = this.scanner.currentPosition;
this.scanner.lastPosition = this.scanner.currentPosition;
if (this.scanner.startPosition <= this.scanner.caseStartPosition)
this.scanner.caseStartPosition = -1;
}

/* attempt to reset state in order to resume to parse loop */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.eclipse.jdt.internal.compiler.parser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -115,7 +116,7 @@ public class Scanner implements TerminalTokens {
public boolean wasAcr = false;

public boolean fakeInModule = false;
int caseStartPosition = -1;
public int caseStartPosition = -1;
boolean inCondition = false;
/* package */ int yieldColons = -1;
boolean breakPreviewAllowed = false;
Expand Down Expand Up @@ -5367,13 +5368,10 @@ int disambiguatedToken(int token, Scanner scanner) {
final VanguardParser parser = getVanguardParser();
if (token == TokenNameARROW && mayBeAtCaseLabelExpr() && scanner.caseStartPosition < scanner.startPosition) {
// this.caseStartPosition > this.startPositionpossible on recovery - bother only about correct ones.
int nSz = scanner.startPosition - scanner.caseStartPosition;
// add fake token of TokenNameCOLON, call vanguard on this modified source
// TODO: Inefficient method due to redoing of the same source, investigate alternate
// Can we do a dup of parsing/check the transition of the state?
String s = new String(scanner.source, scanner.caseStartPosition, nSz);
String modSource = s.concat(new String(new char[] {':'}));
char[] nSource = modSource.toCharArray();
char[] nSource = CharOperation.append(Arrays.copyOfRange(scanner.source, scanner.caseStartPosition, scanner.startPosition), ':');
VanguardParser vp = getNewVanguardParser(nSource);
if (vp.parse(Goal.SwitchLabelCaseLhsGoal) == VanguardParser.SUCCESS) {
scanner.nextToken = TokenNameARROW;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@
import static org.eclipse.jdt.internal.compiler.util.Util.UTF_8;
import static org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsCharArray;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
Expand Down Expand Up @@ -505,18 +503,12 @@ private static IPath[] decodePatterns(NamedNodeMap nodeMap, String tag) {
}

private static void decodeUnknownNode(Node node, StringBuffer buffer, IJavaProject project) {
ByteArrayOutputStream s = new ByteArrayOutputStream();
OutputStreamWriter writer;
try {
writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
XMLWriter xmlWriter = new XMLWriter(writer, project, false/*don't print XML version*/);
decodeUnknownNode(node, xmlWriter, true/*insert new line*/);
xmlWriter.flush();
xmlWriter.close();
buffer.append(s.toString("UTF8")); //$NON-NLS-1$
} catch (UnsupportedEncodingException e) {
// ignore (UTF8 is always supported)
}
StringWriter writer = new StringWriter();
XMLWriter xmlWriter = new XMLWriter(writer, project, false/*don't print XML version*/);
decodeUnknownNode(node, xmlWriter, true/*insert new line*/);
xmlWriter.flush();
xmlWriter.close();
buffer.append(writer.toString());
}

private static void decodeUnknownNode(Node node, XMLWriter xmlWriter, boolean insertNewLine) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,9 +595,7 @@ public void saveExternalLibTimeStamps() throws CoreException {
}

File timestamps = getTimeStampsFile();
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(timestamps)));
try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(timestamps)))){
out.writeInt(this.externalTimeStamps.size() - toRemove.size());
Iterator<Entry<IPath, Long>> entries = this.externalTimeStamps.entrySet().iterator();
while (entries.hasNext()) {
Expand All @@ -612,14 +610,6 @@ public void saveExternalLibTimeStamps() throws CoreException {
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving timestamps", e); //$NON-NLS-1$
throw new CoreException(status);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
// nothing we can do: ignore
}
}
}
}

Expand Down
Loading

0 comments on commit 07d8466

Please sign in to comment.