Skip to content

Commit f4dbed0

Browse files
Merge branch 'master' into BETA_JAVA26
2 parents f805ba9 + d5cfab4 commit f4dbed0

File tree

36 files changed

+1190
-250
lines changed

36 files changed

+1190
-250
lines changed

org.eclipse.jdt.core.compiler.batch/.settings/org.eclipse.jdt.core.prefs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
154154
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
155155
org.eclipse.jdt.core.compiler.release=enabled
156156
org.eclipse.jdt.core.compiler.source=17
157+
org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
158+
org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,NORMAL
159+
org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,NON-JLS
157160
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
158161
org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
159162
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,15 @@ public void generateCode(ClassScope classScope, ClassFile classFile) {
321321
}
322322
int problemResetPC = 0;
323323
CompilationResult unitResult = null;
324+
CategorizedProblem problems[] = new CategorizedProblem[0];
324325
int problemCount = 0;
325326
if (classScope != null) {
326327
TypeDeclaration referenceContext = classScope.referenceContext;
327328
if (referenceContext != null) {
328329
unitResult = referenceContext.compilationResult();
329330
problemCount = unitResult.problemCount;
331+
if (problemCount > 0)
332+
System.arraycopy(unitResult.problems, 0, (problems = new CategorizedProblem[problemCount]), 0, problemCount);
330333
}
331334
}
332335
boolean restart = false;
@@ -347,6 +350,7 @@ public void generateCode(ClassScope classScope, ClassFile classFile) {
347350
// reset the problem count to prevent reporting the same warning twice
348351
if (unitResult != null) {
349352
unitResult.problemCount = problemCount;
353+
unitResult.problems = problems;
350354
}
351355
restart = true;
352356
} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
@@ -356,6 +360,7 @@ public void generateCode(ClassScope classScope, ClassFile classFile) {
356360
// reset the problem count to prevent reporting the same warning twice
357361
if (unitResult != null) {
358362
unitResult.problemCount = problemCount;
363+
unitResult.problems = problems;
359364
}
360365
restart = true;
361366
} else {
@@ -367,8 +372,7 @@ public void generateCode(ClassScope classScope, ClassFile classFile) {
367372
// produce a problem method accounting for this fatal error
368373
if (abort) {
369374
int problemsLength;
370-
CategorizedProblem[] problems =
371-
this.scope.referenceCompilationUnit().compilationResult.getAllProblems();
375+
problems = this.scope.referenceCompilationUnit().compilationResult.getAllProblems();
372376
CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
373377
System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
374378
classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC);

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,8 @@ public TypeBinding reportError(BlockScope scope) {
991991
scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
992992
} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
993993
scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
994+
} else if (this.binding instanceof ProblemLocalVariableBinding plvb && plvb.problemId() == ProblemReasons.NonStaticReferenceInStaticContext) {
995+
scope.problemReporter().recordStaticReferenceToOuterLocalVariable(plvb.closestMatch, this);
994996
} else {
995997
scope.problemReporter().unresolvableReference(this, this.binding);
996998
}

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,8 @@ public TypeBinding reportError(BlockScope scope) {
983983
scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
984984
} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
985985
scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
986+
} else if (this.binding instanceof ProblemLocalVariableBinding plvb && plvb.problemId() == ProblemReasons.NonStaticReferenceInStaticContext) {
987+
scope.problemReporter().recordStaticReferenceToOuterLocalVariable(plvb.closestMatch, this);
986988
} else {
987989
scope.problemReporter().unresolvableReference(this, this.binding);
988990
}

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,9 +1181,7 @@ public StringBuilder printHeader(int indent, StringBuilder output) {
11811181
output.append('(');
11821182
for (int i = 0, length = this.recordComponents.length; i < length; i++) {
11831183
if (i > 0) output.append(", "); //$NON-NLS-1$
1184-
output.append(this.recordComponents[i].type.getTypeName()[0]);
1185-
output.append(' ');
1186-
output.append(this.recordComponents[i].name);
1184+
this.recordComponents[i].print(indent, output);
11871185
}
11881186
output.append(')');
11891187
}

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,6 @@ private void decodeLocalVariableAttribute(int offset, int codeLength) {
518518
if (!CharOperation.equals(localVariableName, ConstantPool.This)) {
519519
names[argumentNamesIndex++] = CharDeduplication.intern(localVariableName);
520520
}
521-
} else {
522-
break;
523521
}
524522
readOffset += 10;
525523
}

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4364,7 +4364,7 @@ public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declari
43644364
case Opcodes.OPC_invokespecial :
43654365
receiverAndArgsSize = 1; // receiver
43664366
if (methodBinding.isConstructor()) {
4367-
if (declaringClass.isNestedType()) {
4367+
if (declaringClass.hasEnclosingInstanceContext()) {
43684368
ReferenceBinding nestedType = (ReferenceBinding) declaringClass;
43694369
// enclosing instances
43704370
receiverAndArgsSize += nestedType.getEnclosingInstancesSlotSize();

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java

Lines changed: 59 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.*;
2323
import java.util.Map.Entry;
24+
import java.util.stream.Collectors;
2425
import java.util.stream.Stream;
2526
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
2627
import org.eclipse.jdt.internal.compiler.util.Tuples.Pair;
@@ -56,7 +57,6 @@ private static class ThreeSets {
5657
Set<TypeBound> sameBounds;
5758
Set<TypeBound> subBounds;
5859
TypeBinding instantiation;
59-
Map<InferenceVariable,TypeBound> inverseBounds; // from right inference variable to bound
6060
Set<InferenceVariable> dependencies;
6161
public ThreeSets() {
6262
// empty, the sets are lazily initialized
@@ -138,18 +138,6 @@ public TypeBinding[] upperBounds(boolean onlyProper, InferenceVariable variable)
138138
InferenceContext18.sortTypes(rights);
139139
return rights;
140140
}
141-
// pre: beta is a prototype
142-
public boolean hasDependency(InferenceVariable beta) {
143-
if(this.dependencies != null && this.dependencies.contains(beta))
144-
return true;
145-
if (this.inverseBounds != null) {
146-
if (this.inverseBounds.containsKey(beta)) {
147-
// TODO: not yet observed in tests
148-
return true;
149-
}
150-
}
151-
return false;
152-
}
153141
/** Total number of type bounds in this container. */
154142
public int size() {
155143
int size = 0;
@@ -322,6 +310,16 @@ else if (type.hasNullTypeAnnotations())
322310
* On both sides we only enter types with nonnull arguments.
323311
*/
324312
HashMap<ParameterizedTypeBinding,ParameterizedTypeBinding> captures = new LinkedHashMap<>();
313+
/**
314+
* NON-JLS: maintain a separate set alongside {@link #captures}:
315+
* <dl>
316+
* <dt>captures<dd>IC18.resumeSuspendedInference() will reset these to avoid captures from nested
317+
* inference spilling blindly into the current inference.<br>
318+
* {@link InferenceContext18#collectDependencies(BoundSet, boolean, boolean[])} considers only "local" {@link #captures}.
319+
* <dt>allCaptures<dd>Still {@link #hasCaptureBound(Set)} and {@link #incorporate(InferenceContext18)} will
320+
* operate on {@link #allCaptures}.
321+
*/
322+
HashMap<ParameterizedTypeBinding,ParameterizedTypeBinding> allCaptures = new LinkedHashMap<>();
325323
/** 18.1.3 bullet 5: throws α */
326324
Set<InferenceVariable> inThrows = new LinkedHashSet<>();
327325

@@ -375,6 +373,7 @@ public BoundSet copy() {
375373
}
376374
copy.inThrows.addAll(this.inThrows);
377375
copy.captures.putAll(this.captures);
376+
copy.allCaptures.putAll(this.allCaptures);
378377
if (this.incorporatedBounds.length > 0)
379378
System.arraycopy(this.incorporatedBounds, 0, copy.incorporatedBounds = new TypeBound[this.incorporatedBounds.length], 0, this.incorporatedBounds.length);
380379
if (this.unincorporatedBoundsCount > 0)
@@ -435,9 +434,6 @@ else if (boundNullBits != 0) // combine bits from both sources, even if this cre
435434
three = this.boundsPerVariable.get(rightIV);
436435
if (three == null)
437436
this.boundsPerVariable.put(rightIV, (three = new ThreeSets()));
438-
if (three.inverseBounds == null)
439-
three.inverseBounds = new HashMap<>();
440-
three.inverseBounds.put(rightIV, bound);
441437
}
442438
}
443439
}
@@ -458,6 +454,7 @@ public void addBounds(BoundSet that, LookupEnvironment environment, boolean incl
458454
this.inThrows.addAll(that.inThrows);
459455
if (includeCaptureBounds) {
460456
this.captures.putAll(that.captures);
457+
this.allCaptures.putAll(that.allCaptures);
461458
}
462459
}
463460

@@ -491,7 +488,7 @@ public int numUninstantiatedVariables(InferenceVariable[] variables) {
491488

492489
// Driver for the real workhorse - Implements generational incorporation a la generational garbage collector.
493490
boolean incorporate(InferenceContext18 context) throws InferenceFailureException {
494-
if (this.unincorporatedBoundsCount == 0 && this.captures.isEmpty())
491+
if (this.unincorporatedBoundsCount == 0 && this.allCaptures.isEmpty())
495492
return true;
496493

497494
try {
@@ -634,7 +631,8 @@ boolean incorporate(InferenceContext18 context, TypeBound [] first, TypeBound []
634631
} while (first != next && ++iteration <= 2);
635632
}
636633
}
637-
for (Entry<ParameterizedTypeBinding, ParameterizedTypeBinding> capt : this.captures.entrySet()) {
634+
Set<ParameterizedTypeBinding> capturesToRemove = new HashSet<>();
635+
for (Entry<ParameterizedTypeBinding, ParameterizedTypeBinding> capt : this.allCaptures.entrySet()) {
638636
ParameterizedTypeBinding gAlpha = capt.getKey();
639637
ParameterizedTypeBinding gA = capt.getValue();
640638
ReferenceBinding g = (ReferenceBinding) gA.original();
@@ -693,7 +691,8 @@ protected TypeBinding getP(int i) {
693691
System.arraycopy(otherBounds, 0, allBounds, 1, n-1);
694692
bi = context.environment.createIntersectionType18(allBounds);
695693
}
696-
addTypeBoundsFromWildcardBound(context, theta, wildcardBinding.boundKind, t, r, bi);
694+
if (addTypeBoundsFromWildcardBound(context, theta, wildcardBinding.boundKind, t, r, bi))
695+
capturesToRemove.add(gAlpha);
697696
}
698697
}
699698
}
@@ -704,33 +703,38 @@ protected TypeBinding getP(int i) {
704703
while (it.hasNext()) {
705704
TypeBound bound = it.next();
706705
if (!(bound.right instanceof InferenceVariable)) {
707-
if (wildcardBinding.boundKind == Wildcard.SUPER)
706+
if (wildcardBinding.boundKind == Wildcard.SUPER) {
708707
reduceOneConstraint(context, ConstraintTypeFormula.create(bound.right, t, ReductionResult.SUBTYPE));
709-
else
708+
capturesToRemove.add(gAlpha);
709+
} else {
710710
return false;
711+
}
711712
}
712713
}
713714
}
714715
}
715716
} else {
716717
addBound(new TypeBound(alpha, ai, ReductionResult.SAME), context.environment);
718+
capturesToRemove.add(gAlpha);
717719
}
718720
}
719721
}
720722
if (InferenceContext18.DEBUG) {
721-
if (!this.captures.isEmpty()) {
722-
for (Entry<ParameterizedTypeBinding, ParameterizedTypeBinding> entry : this.captures.entrySet()) {
723-
System.out.println("Dropping capture bound " + //$NON-NLS-1$
724-
String.valueOf(entry.getKey().shortReadableName()) +
725-
"=capture("+String.valueOf(entry.getKey().shortReadableName())+")"); //$NON-NLS-1$ //$NON-NLS-2$
723+
if (!capturesToRemove.isEmpty()) {
724+
for (ParameterizedTypeBinding toRemove : capturesToRemove) {
725+
System.out.println("Removing capture bound " + //$NON-NLS-1$
726+
String.valueOf(toRemove.shortReadableName()) +
727+
"=capture("+String.valueOf(this.captures.get(toRemove).shortReadableName())+")"); //$NON-NLS-1$ //$NON-NLS-2$
726728
}
727729
}
728730
}
729-
this.captures.clear();
731+
capturesToRemove.stream().forEach(c -> this.allCaptures.remove(c));
730732
return true;
731733
}
732734

733-
void addTypeBoundsFromWildcardBound(InferenceContext18 context, InferenceSubstitution theta, int boundKind, TypeBinding t,
735+
// try to infer and reduce a new constraint based on details of a given capture bound
736+
// return true iff a new constraint has been added indeed
737+
boolean addTypeBoundsFromWildcardBound(InferenceContext18 context, InferenceSubstitution theta, int boundKind, TypeBinding t,
734738
TypeBinding r, TypeBinding bi) throws InferenceFailureException {
735739
ConstraintFormula formula = null;
736740
if (boundKind == Wildcard.EXTENDS) {
@@ -741,8 +745,11 @@ void addTypeBoundsFromWildcardBound(InferenceContext18 context, InferenceSubstit
741745
} else {
742746
formula = ConstraintTypeFormula.create(theta.substitute(theta, bi), r, ReductionResult.SUBTYPE);
743747
}
744-
if (formula != null)
748+
if (formula != null) {
745749
reduceOneConstraint(context, formula);
750+
return true;
751+
}
752+
return false;
746753
}
747754

748755
private ConstraintTypeFormula combineSameSame(TypeBound boundS, TypeBound boundT, Map<InferenceVariable,TypeBound> properTypesByInferenceVariable) {
@@ -1030,85 +1037,9 @@ public boolean reduceOneConstraint(InferenceContext18 context, ConstraintFormula
10301037
return true; // no FALSE encountered
10311038
}
10321039

1033-
/**
1034-
* Helper for resolution (18.4):
1035-
* Does this bound set define a direct dependency between the two given inference variables?
1036-
*/
1037-
public boolean dependsOnResolutionOf(InferenceVariable alpha, InferenceVariable beta) {
1038-
alpha = alpha.prototype();
1039-
beta = beta.prototype();
1040-
if (TypeBinding.equalsEquals(alpha, beta))
1041-
return true; // An inference variable α depends on the resolution of itself.
1042-
boolean betaIsInCaptureLhs = false;
1043-
for (Entry<ParameterizedTypeBinding, ParameterizedTypeBinding> entry : this.captures.entrySet()) { // TODO: optimization: consider separate index structure (by IV)
1044-
ParameterizedTypeBinding g = entry.getKey();
1045-
for (int i = 0; i < g.arguments.length; i++) {
1046-
if (TypeBinding.equalsEquals(g.arguments[i], alpha)) {
1047-
// An inference variable α appearing on the left-hand side of a bound of the form G<..., α, ...> = capture(G<...>)
1048-
// depends on the resolution of every other inference variable mentioned in this bound (on both sides of the = sign).
1049-
ParameterizedTypeBinding captured = entry.getValue();
1050-
if (captured.mentionsAny(new TypeBinding[]{beta}, -1/*don't care about index*/))
1051-
return true;
1052-
if (g.mentionsAny(new TypeBinding[]{beta}, i)) // exclude itself
1053-
return true;
1054-
} else if (TypeBinding.equalsEquals(g.arguments[i], beta)) {
1055-
betaIsInCaptureLhs = true;
1056-
}
1057-
}
1058-
}
1059-
if (betaIsInCaptureLhs) { // swap α and β in the rule text to cover "then β depends on the resolution of α"
1060-
ThreeSets sets = this.boundsPerVariable.get(beta);
1061-
if (sets != null && sets.hasDependency(alpha))
1062-
return true;
1063-
} else {
1064-
ThreeSets sets = this.boundsPerVariable.get(alpha);
1065-
if (sets != null && sets.hasDependency(beta))
1066-
return true;
1067-
}
1068-
return false;
1069-
}
1070-
1071-
List<Set<InferenceVariable>> computeConnectedComponents(InferenceVariable[] inferenceVariables) {
1072-
// create all dependency edges (as bi-directional):
1073-
Map<InferenceVariable, Set<InferenceVariable>> allEdges = new HashMap<>();
1074-
for (int i = 0; i < inferenceVariables.length; i++) {
1075-
InferenceVariable iv1 = inferenceVariables[i];
1076-
Set<InferenceVariable> targetSet = new LinkedHashSet<>();
1077-
allEdges.put(iv1, targetSet); // eventually ensures: forall iv in inferenceVariables : allEdges.get(iv) != null
1078-
for (int j = 0; j < i; j++) {
1079-
InferenceVariable iv2 = inferenceVariables[j];
1080-
if (dependsOnResolutionOf(iv1, iv2) || dependsOnResolutionOf(iv2, iv1)) {
1081-
targetSet.add(iv2);
1082-
allEdges.get(iv2).add(iv1);
1083-
}
1084-
}
1085-
}
1086-
// collect all connected IVs into one component:
1087-
Set<InferenceVariable> visited = new LinkedHashSet<>();
1088-
List<Set<InferenceVariable>> allComponents = new ArrayList<>();
1089-
for (InferenceVariable inferenceVariable : inferenceVariables) {
1090-
Set<InferenceVariable> component = new LinkedHashSet<>();
1091-
addConnected(component, inferenceVariable, allEdges, visited);
1092-
if (!component.isEmpty())
1093-
allComponents.add(component);
1094-
}
1095-
return allComponents;
1096-
}
1097-
1098-
private void addConnected(Set<InferenceVariable> component, InferenceVariable seed,
1099-
Map<InferenceVariable, Set<InferenceVariable>> allEdges, Set<InferenceVariable> visited)
1100-
{
1101-
if (visited.add(seed)) {
1102-
// add all IVs starting from seed and reachable via any in allEdges:
1103-
component.add(seed);
1104-
for (InferenceVariable next : allEdges.get(seed))
1105-
addConnected(component, next, allEdges, visited);
1106-
}
1107-
}
1108-
11091040
// helper for 18.4
11101041
public boolean hasCaptureBound(Set<InferenceVariable> variableSet) {
1111-
for (ParameterizedTypeBinding g : this.captures.keySet()) {
1042+
for (ParameterizedTypeBinding g : this.allCaptures.keySet()) {
11121043
for (TypeBinding argument : g.arguments)
11131044
if (variableSet.contains(argument))
11141045
return true;
@@ -1159,6 +1090,13 @@ TypeBinding[] lowerBounds(InferenceVariable variable, boolean onlyProper) {
11591090
// appears as RHS the bound is by construction an inference variable,too.
11601091
}
11611092

1093+
public TypeBinding[] sameBounds(InferenceVariable variable) {
1094+
ThreeSets three = this.boundsPerVariable.get(variable.prototype());
1095+
if (three == null || three.sameBounds == null)
1096+
return Binding.NO_TYPES;
1097+
return three.sameBounds.stream().map(b -> b.right).collect(Collectors.toList()).toArray(TypeBinding[]::new);
1098+
}
1099+
11621100
// debugging:
11631101
@Override
11641102
public String toString() {
@@ -1167,7 +1105,7 @@ public String toString() {
11671105
for (TypeBound bound : flattened) {
11681106
buf.append('\t').append(bound.toString()).append('\n');
11691107
}
1170-
buf.append("Capture Bounds:"); //$NON-NLS-1$
1108+
buf.append("Local Capture Bounds:"); //$NON-NLS-1$
11711109
if (this.captures.isEmpty()) {
11721110
buf.append(" <empty>\n"); //$NON-NLS-1$
11731111
} else {
@@ -1178,6 +1116,20 @@ public String toString() {
11781116
buf.append('\t').append(lhs).append(" = capt(").append(rhs).append(")\n"); //$NON-NLS-1$ //$NON-NLS-2$
11791117
}
11801118
}
1119+
buf.append("Other Capture Bounds:"); //$NON-NLS-1$
1120+
if (this.allCaptures.isEmpty()) {
1121+
buf.append(" <empty>\n"); //$NON-NLS-1$
1122+
} else {
1123+
buf.append('\n');
1124+
for (Entry<ParameterizedTypeBinding, ParameterizedTypeBinding> entry : this.allCaptures.entrySet()) {
1125+
if (this.captures.containsKey(entry.getKey()))
1126+
continue;
1127+
String lhs = String.valueOf(entry.getKey().shortReadableName());
1128+
String rhs = String.valueOf(entry.getValue().shortReadableName());
1129+
buf.append('\t');
1130+
buf.append(lhs).append(" = capt(").append(rhs).append(")\n"); //$NON-NLS-1$ //$NON-NLS-2$
1131+
}
1132+
}
11811133
return buf.toString();
11821134
}
11831135

0 commit comments

Comments
 (0)