Skip to content

Commit aea7697

Browse files
authored
Issue 1418 - changes suggested in comment (#1464)
* Issue 1418 - changes suggested in comment #1418 (comment)
1 parent e5ae734 commit aea7697

3 files changed

Lines changed: 71 additions & 43 deletions

File tree

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

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2021 IBM Corporation and others.
2+
* Copyright (c) 2000, 2023 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -47,6 +47,7 @@
4747
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
4848
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
4949
import org.eclipse.jdt.internal.compiler.ast.RecordComponent;
50+
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
5051
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
5152
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
5253
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -1309,40 +1310,70 @@ void connectImplicitPermittedTypes() {
13091310
void connectPermittedTypes() {
13101311
SourceTypeBinding sourceType = this.referenceContext.binding;
13111312
sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
1312-
if (this.referenceContext.permittedTypes == null) {
1313-
return;
1314-
}
13151313
if (sourceType.id == TypeIds.T_JavaLangObject || sourceType.isEnum()) // already handled
13161314
return;
13171315

1318-
int length = this.referenceContext.permittedTypes.length;
1319-
ReferenceBinding[] permittedTypeBindings = new ReferenceBinding[length];
1320-
int count = 0;
1321-
nextPermittedType : for (int i = 0; i < length; i++) {
1322-
TypeReference permittedTypeRef = this.referenceContext.permittedTypes[i];
1323-
ReferenceBinding permittedType = findPermittedtype(permittedTypeRef);
1324-
if (permittedType == null) { // detected cycle
1325-
continue nextPermittedType;
1326-
}
1327-
// check for simple interface collisions
1328-
// Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I)
1329-
for (int j = 0; j < i; j++) {
1330-
if (TypeBinding.equalsEquals(permittedTypeBindings[j], permittedType)) {
1331-
problemReporter().sealedDuplicateTypeInPermits(sourceType, permittedTypeRef, permittedType);
1316+
if (this.referenceContext.permittedTypes != null) {
1317+
int length = this.referenceContext.permittedTypes.length;
1318+
ReferenceBinding[] permittedTypeBindings = new ReferenceBinding[length];
1319+
int count = 0;
1320+
nextPermittedType : for (int i = 0; i < length; i++) {
1321+
TypeReference permittedTypeRef = this.referenceContext.permittedTypes[i];
1322+
ReferenceBinding permittedType = findPermittedtype(permittedTypeRef);
1323+
if (permittedType == null) { // detected cycle
13321324
continue nextPermittedType;
13331325
}
1326+
if (!isPermittedTypeInAllowedFormat(sourceType, permittedTypeRef, permittedType))
1327+
continue nextPermittedType;
1328+
1329+
// check for simple interface collisions
1330+
// Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I)
1331+
for (int j = 0; j < i; j++) {
1332+
if (TypeBinding.equalsEquals(permittedTypeBindings[j], permittedType)) {
1333+
problemReporter().sealedDuplicateTypeInPermits(sourceType, permittedTypeRef, permittedType);
1334+
continue nextPermittedType;
1335+
}
1336+
}
1337+
// only want to reach here when no errors are reported
1338+
permittedTypeBindings[count++] = permittedType;
1339+
}
1340+
// hold onto all correctly resolved superinterfaces
1341+
if (count > 0) {
1342+
if (count != length)
1343+
System.arraycopy(permittedTypeBindings, 0, permittedTypeBindings = new ReferenceBinding[count], 0, count);
1344+
sourceType.setPermittedTypes(permittedTypeBindings);
1345+
} else {
1346+
sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
13341347
}
1335-
// only want to reach here when no errors are reported
1336-
permittedTypeBindings[count++] = permittedType;
13371348
}
1338-
// hold onto all correctly resolved superinterfaces
1339-
if (count > 0) {
1340-
if (count != length)
1341-
System.arraycopy(permittedTypeBindings, 0, permittedTypeBindings = new ReferenceBinding[count], 0, count);
1342-
sourceType.setPermittedTypes(permittedTypeBindings);
1343-
} else {
1344-
sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
1349+
ReferenceBinding[] memberTypes = sourceType.memberTypes;
1350+
if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES) {
1351+
for (int j = 0, size = memberTypes.length; j < size; j++)
1352+
((SourceTypeBinding) memberTypes[j]).scope.connectPermittedTypes();
1353+
}
1354+
}
1355+
1356+
private boolean isPermittedTypeInAllowedFormat(SourceTypeBinding sourceType, TypeReference permittedTypeRef,
1357+
ReferenceBinding permittedType) {
1358+
if (!(permittedType.isMemberType() && permittedTypeRef instanceof SingleTypeReference))
1359+
return true;
1360+
ReferenceBinding enclosingType = permittedType.enclosingType();
1361+
while (enclosingType != null) {
1362+
if (TypeBinding.equalsEquals(sourceType, enclosingType)) {
1363+
CompilationUnitScope cu = this.compilationUnitScope();
1364+
if (cu.imports != null || cu.imports.length > 0) {
1365+
for (ImportBinding ib : cu.imports) {
1366+
Binding resolvedImport = cu.resolveSingleImport(ib, Binding.TYPE);
1367+
if (resolvedImport instanceof TypeBinding &&
1368+
TypeBinding.equalsEquals(permittedType, (TypeBinding) resolvedImport))
1369+
return true;
1370+
}
1371+
}
1372+
return false;
1373+
}
1374+
enclosingType = enclosingType.enclosingType();
13451375
}
1376+
return true;
13461377
}
13471378

13481379
private boolean connectRecordSuperclass() {
@@ -1447,7 +1478,7 @@ void connectTypeHierarchy() {
14471478
noProblems &= connectSuperInterfaces();
14481479
environment().typesBeingConnected.remove(sourceType);
14491480
sourceType.tagBits |= TagBits.EndHierarchyCheck;
1450-
connectPermittedTypes();
1481+
// connectPermittedTypes();
14511482
noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
14521483
sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
14531484
if (noProblems && sourceType.isHierarchyInconsistent())

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2020 IBM Corporation and others.
2+
* Copyright (c) 2000, 2023 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -401,9 +401,16 @@ void connectTypeHierarchy2() {
401401
for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
402402
this.topLevelTypes[i].scope.referenceType().updateSupertypesWithAnnotations(Collections.emptyMap());
403403
// ... checking on permitted types
404+
connectPermittedTypes();
404405
for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
405406
this.topLevelTypes[i].scope.connectImplicitPermittedTypes();
406407
}
408+
private void connectPermittedTypes() {
409+
for (int i = 0, length = this.topLevelTypes.length; i < length; i++) {
410+
SourceTypeBinding sourceType = this.topLevelTypes[i];
411+
sourceType.scope.connectPermittedTypes();
412+
}
413+
}
407414
void faultInImports() {
408415
if (this.tempImports != null)
409416
return; // faultInImports already in progress

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2020, 2022 IBM Corporation and others.
2+
* Copyright (c) 2020, 2023 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -31,7 +31,7 @@ public class SealedTypesTests extends AbstractRegressionTest9 {
3131
static {
3232
// TESTS_NUMBERS = new int [] { 40 };
3333
// TESTS_RANGE = new int[] { 1, -1 };
34-
// TESTS_NAMES = new String[] { "testBug564638_056"};
34+
// TESTS_NAMES = new String[] { "testBug564498_6"};
3535
}
3636

3737
public static Class<?> testClass() {
@@ -1611,12 +1611,7 @@ public void testBug564498_5() throws IOException, ClassFormatException {
16111611
"}",
16121612
},
16131613
"----------\n" +
1614-
"1. ERROR in p1\\X.java (at line 6)\n" +
1615-
" sealed class Y extends X permits SubInnerY {\n" +
1616-
" ^^^^^^^^^\n" +
1617-
"SubInnerY cannot be resolved to a type\n" +
1618-
"----------\n" +
1619-
"2. ERROR in p1\\X.java (at line 7)\n" +
1614+
"1. ERROR in p1\\X.java (at line 7)\n" +
16201615
" final class SubInnerY extends Y {}\n" +
16211616
" ^\n" +
16221617
"The type SubInnerY extending a sealed class A.Y should be a permitted subtype of A.Y\n" +
@@ -5711,12 +5706,7 @@ public void testBug573450_005() {
57115706
"}"
57125707
},
57135708
"----------\n"
5714-
+ "1. ERROR in X.java (at line 1)\n"
5715-
+ " public sealed class X permits Y {\n"
5716-
+ " ^\n"
5717-
+ "Y cannot be resolved to a type\n"
5718-
+ "----------\n"
5719-
+ "2. ERROR in X.java (at line 2)\n"
5709+
+ "1. ERROR in X.java (at line 2)\n"
57205710
+ " final class Y extends X {}\n"
57215711
+ " ^\n"
57225712
+ "The type Y extending a sealed class X should be a permitted subtype of X\n"

0 commit comments

Comments
 (0)