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 Oct 20, 2024
2 parents 8439271 + a569f00 commit 0ab4ca3
Show file tree
Hide file tree
Showing 30 changed files with 1,660 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2538,7 +2538,9 @@ public interface IProblem {
int SealedPermittedTypeOutsideOfPackage = TypeRelated + 1859;
/** @since 3.28 */
int SealedSealedTypeMissingPermits = TypeRelated + 1860;
/** @since 3.28 */
/** @since 3.28
* @deprecated problem no longer generated
*/
int SealedInterfaceIsSealedAndNonSealed = TypeRelated + 1861;
/** @since 3.28 */
int SealedDisAllowedNonSealedModifierInInterface = TypeRelated + 1862;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,6 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
if (this.preSwitchInitStateIndex != -1) {
codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
}
defaultLabel.place();
/* a default case is not needed for an exhaustive switch expression
* we need to handle the default case to throw an error in order to make the stack map consistent.
* All cases will return a value on the stack except the missing default case.
Expand All @@ -895,9 +894,10 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
CompilerOptions compilerOptions = this.scope != null ? this.scope.compilerOptions() : null;
if (compilerOptions.complianceLevel >= ClassFileConstants.JDK19) {
// since 19 we have MatchException for this
if (codeStream.lastAbruptCompletion != codeStream.position) {
if (this.statements.length > 0 && this.statements[this.statements.length - 1].canCompleteNormally()) {
codeStream.goto_(this.breakLabel); // hop, skip and jump over match exception throw.
}
defaultLabel.place();
codeStream.newJavaLangMatchException();
codeStream.dup();
codeStream.aconst_null();
Expand All @@ -906,6 +906,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) {
codeStream.athrow();
} else {
// old style using IncompatibleClassChangeError:
defaultLabel.place();
codeStream.newJavaLangIncompatibleClassChangeError();
codeStream.dup();
codeStream.invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public class TypeDeclaration extends Statement implements ProblemSeverities, Ref
public int nRecordComponents;
public static Set<String> disallowedComponentNames;

// 15 Sealed Type preview support
// 17 Sealed Type support
public TypeReference[] permittedTypes;

// TEST ONLY: disable one fix here to challenge another related fix (in TypeSystem):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,13 @@ public static Classpath getClasspath(String classpathName, String encoding, Acce
return getClasspath(classpathName, encoding, false, accessRuleSet, null, options, release);
}
public static Classpath getJrtClasspath(String jdkHome, String encoding, AccessRuleSet accessRuleSet, Map<String, String> options) {
return new ClasspathJrt(new File(convertPathSeparators(jdkHome)), true, accessRuleSet, null);
ClasspathJrt classpathJrt = new ClasspathJrt(new File(convertPathSeparators(jdkHome)), true, accessRuleSet, null);
try {
classpathJrt.initialize();
} catch (IOException e) {
// Broken entry, but let clients have it anyway.
}
return classpathJrt;
}
public static Classpath getOlderSystemRelease(String jdkHome, String release, AccessRuleSet accessRuleSet) {
return isJRE12Plus ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,9 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
Expand Down Expand Up @@ -115,8 +111,6 @@ void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding
} else {
anonymousType.setSuperClass(supertype);
anonymousType.setSuperInterfaces(Binding.NO_SUPERINTERFACES);
if (supertype.isEnum() && supertype instanceof SourceTypeBinding superEnum)
implicitlySealEnumHierarchy(superEnum, anonymousType);
TypeReference typeReference = this.referenceContext.allocation.type;
if (typeReference != null) { // no check for enum constant body
this.referenceContext.superclass = typeReference;
Expand Down Expand Up @@ -152,21 +146,6 @@ void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding
anonymousType.verifyMethods(environment().methodVerifier());
}

private void implicitlySealEnumHierarchy(SourceTypeBinding superEnum, LocalTypeBinding anonymousType) {
if (JavaFeature.SEALED_CLASSES.isSupported(compilerOptions())) {
ReferenceBinding[] permittedTypes = superEnum.permittedTypes();
int sz = permittedTypes == null ? 0 : permittedTypes.length;
if (sz == 0) {
permittedTypes = new ReferenceBinding[] { anonymousType };
} else {
System.arraycopy(permittedTypes, 0, permittedTypes = new ReferenceBinding[sz + 1], 0, sz);
permittedTypes[sz] = anonymousType;
}
anonymousType.modifiers |= ClassFileConstants.AccFinal;
superEnum.setPermittedTypes(permittedTypes);
}
}

void buildComponents() {
SourceTypeBinding sourceType = this.referenceContext.binding;
if (!sourceType.isRecord()) return;
Expand Down Expand Up @@ -368,7 +347,6 @@ void buildLocalTypeBinding(SourceTypeBinding enclosingType) {

LocalTypeBinding localType = buildLocalType(enclosingType, enclosingType.fPackage);
connectTypeHierarchy();
connectImplicitPermittedTypes();
if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
checkParameterizedTypeBounds();
checkParameterizedSuperTypeCollisions();
Expand Down Expand Up @@ -1267,49 +1245,12 @@ private boolean connectEnumSuperclass() {
}
return !foundCycle;
}
private void connectImplicitPermittedTypes(SourceTypeBinding sourceType) {
List<SourceTypeBinding> types = new ArrayList<>();
for (TypeDeclaration typeDecl : this.referenceCompilationUnit().types) {
types.addAll(sourceType.collectAllTypeBindings(typeDecl, this.compilationUnitScope()));
}
Set<ReferenceBinding> permSubTypes = new LinkedHashSet<>();
for (ReferenceBinding type : types) {
if (!TypeBinding.equalsEquals(type, sourceType) && type.findSuperTypeOriginatingFrom(sourceType) != null) {
permSubTypes.add(type);
}
}
if (sourceType.isSealed() && sourceType.isLocalType()) {
// bug xxxx flag Error and return;
}
if (permSubTypes.size() == 0) {
if (!sourceType.isLocalType() && !sourceType.isRecord() && !sourceType.isEnum()) // error flagged already
problemReporter().sealedSealedTypeMissingPermits(sourceType, this.referenceContext);
return;
}
sourceType.setPermittedTypes(permSubTypes.toArray(new ReferenceBinding[0]));
}
void connectImplicitPermittedTypes() {
TypeDeclaration typeDecl = this.referenceContext;
SourceTypeBinding sourceType = typeDecl.binding;
if (sourceType.id == TypeIds.T_JavaLangObject) // already handled
return;
if (sourceType.isSealed() && (typeDecl.permittedTypes == null ||
typeDecl.permittedTypes.length == 0 || typeDecl.permittedTypes[0].isImplicit())) {
connectImplicitPermittedTypes(sourceType);
}
ReferenceBinding[] memberTypes = sourceType.memberTypes;
if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES) {
for (ReferenceBinding memberType : memberTypes)
((SourceTypeBinding) memberType).scope.connectImplicitPermittedTypes();
}
}

void connectPermittedTypes() {
SourceTypeBinding sourceType = this.referenceContext.binding;
sourceType.setPermittedTypes(Binding.NO_PERMITTED_TYPES);
if (sourceType.id == TypeIds.T_JavaLangObject || sourceType.isEnum()) // already handled
return;

if (this.referenceContext.permittedTypes != null) {
if (this.referenceContext.permittedTypes != null && (this.referenceContext.permittedTypes.length == 0 || !this.referenceContext.permittedTypes[0].isImplicit())) {
sourceType.setPermittedTypes(Binding.NO_PERMITTED_TYPES);
try {
sourceType.tagBits |= TagBits.SealingTypeHierarchy;
int length = this.referenceContext.permittedTypes.length;
Expand Down Expand Up @@ -1340,6 +1281,15 @@ void connectPermittedTypes() {
} finally {
sourceType.tagBits &= ~TagBits.SealingTypeHierarchy;
}
} else {
ReferenceBinding[] permittedTypes = sourceType.permittedTypes();
if (permittedTypes == null || permittedTypes.length == 0) {
sourceType.setPermittedTypes(Binding.NO_PERMITTED_TYPES);
if (sourceType.isSealed()) {
if (!sourceType.isLocalType() && !sourceType.isRecord() && !sourceType.isEnum()) // error flagged alread
problemReporter().sealedSealedTypeMissingPermits(sourceType, this.referenceContext);
}
}
}
ReferenceBinding[] memberTypes = sourceType.memberTypes;
if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,6 @@ void sealTypeHierarchy() {
for (SourceTypeBinding sourceType : this.topLevelTypes) {
sourceType.scope.connectPermittedTypes();
}
for (SourceTypeBinding topLevelType : this.topLevelTypes)
topLevelType.scope.connectImplicitPermittedTypes();
}
void integrateAnnotationsInHierarchy() {
// Only now that all hierarchy information is built we're ready for ...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationPosition;
Expand Down Expand Up @@ -1119,17 +1118,9 @@ private Map.Entry<TypeReference, ReferenceBinding> getFirstSealedSuperTypeOrInte
}
return null;
}
// TODO: Optimize the multiple loops - defer until the feature becomes standard.

private void checkPermitsInType() {
// if (/* this.isRecordDeclaration || */this.isEnum())
// return; // handled separately
TypeDeclaration typeDecl = this.scope.referenceContext;
if (this.isInterface()) {
if (isSealed() && isNonSealed()) {
this.scope.problemReporter().sealedInterfaceIsSealedAndNonSealed(this, typeDecl);
return;
}
}
boolean hasPermittedTypes = this.permittedTypes != null && this.permittedTypes.length > 0;
if (hasPermittedTypes) {
if (!this.isSealed())
Expand Down Expand Up @@ -1170,11 +1161,13 @@ private void checkPermitsInType() {
return;
}
} else if (this.isNonSealed()) {
if (!foundSealedSuperTypeOrInterface) {
if (this.isClass() && !this.isRecord()) // record to give only illegal modifier error.
this.scope.problemReporter().sealedDisAllowedNonSealedModifierInClass(this, typeDecl);
else if (this.isInterface())
this.scope.problemReporter().sealedDisAllowedNonSealedModifierInInterface(this, typeDecl);
if (!this.isSealed()) { // lest we bark again.
if (!foundSealedSuperTypeOrInterface) {
if (this.isClass() && !this.isRecord()) // record to give only illegal modifier error.
this.scope.problemReporter().sealedDisAllowedNonSealedModifierInClass(this, typeDecl);
else if (this.isInterface())
this.scope.problemReporter().sealedDisAllowedNonSealedModifierInInterface(this, typeDecl);
}
}
}
if (foundSealedSuperTypeOrInterface) {
Expand Down Expand Up @@ -1283,40 +1276,6 @@ private void reportSealedSuperTypeDoesNotPermitProblem(TypeReference superTypeRe
}
}

public List<SourceTypeBinding> collectAllTypeBindings(TypeDeclaration typeDecl, CompilationUnitScope unitScope) {
class TypeBindingsCollector extends ASTVisitor {
List<SourceTypeBinding> types = new ArrayList<>();
@Override
public boolean visit(
TypeDeclaration localTypeDeclaration,
BlockScope scope1) {
checkAndAddBinding(localTypeDeclaration.binding);
return true;
}
@Override
public boolean visit(
TypeDeclaration memberTypeDeclaration,
ClassScope scope1) {
checkAndAddBinding(memberTypeDeclaration.binding);
return true;
}
@Override
public boolean visit(
TypeDeclaration typeDeclaration,
CompilationUnitScope scope1) {
checkAndAddBinding(typeDeclaration.binding);
return true; // do nothing by default, keep traversing
}
private void checkAndAddBinding(SourceTypeBinding stb) {
if (stb != null)
this.types.add(stb);
}
}
TypeBindingsCollector typeCollector = new TypeBindingsCollector();
typeDecl.traverse(typeCollector, unitScope);
return typeCollector.types;
}

private boolean checkPermitsAndAdd(ReferenceBinding superType) {
if (superType == null
|| superType.equals(this.scope.getJavaLangObject())
Expand Down Expand Up @@ -3269,9 +3228,31 @@ public ReferenceBinding setSuperClass(ReferenceBinding superClass) {
annotatedType.superclass = superClass;
}
}
if (superClass != null && superClass.actualType() instanceof SourceTypeBinding sourceSuperType && sourceSuperType.isSealed()
&& (sourceSuperType.scope.referenceContext.permittedTypes == null || (sourceSuperType.scope.referenceContext.permittedTypes.length > 0 && sourceSuperType.scope.referenceContext.permittedTypes[0].isImplicit()))) {
sourceSuperType.setImplicitPermittedType(this);
if (this.isAnonymousType() && superClass.isEnum())
this.modifiers |= ClassFileConstants.AccFinal;
}
return this.superclass = superClass;
}

private void setImplicitPermittedType(SourceTypeBinding permittedType) {
ReferenceBinding[] typesPermitted = this.permittedTypes();
int sz = typesPermitted == null ? 0 : typesPermitted.length;
if (this.scope.referenceCompilationUnit() == permittedType.scope.referenceCompilationUnit()) {
if (sz == 0) {
typesPermitted = new ReferenceBinding[] { permittedType };
} else {
System.arraycopy(typesPermitted, 0, typesPermitted = new ReferenceBinding[sz + 1], 0, sz);
typesPermitted[sz] = permittedType;
}
this.setPermittedTypes(typesPermitted);
} else if (sz == 0) {
this.setPermittedTypes(Binding.NO_PERMITTED_TYPES);
}
}

// Propagate writes to all annotated variants so the clones evolve along.
public ReferenceBinding [] setSuperInterfaces(ReferenceBinding [] superInterfaces) {

Expand All @@ -3285,6 +3266,13 @@ public ReferenceBinding setSuperClass(ReferenceBinding superClass) {
annotatedType.superInterfaces = superInterfaces;
}
}
for (int i = 0, length = superInterfaces == null ? 0 : superInterfaces.length; i < length; i++) {
ReferenceBinding superInterface = superInterfaces[i];
if (superInterface.actualType() instanceof SourceTypeBinding sourceSuperType && sourceSuperType.isSealed()
&& (sourceSuperType.scope.referenceContext.permittedTypes == null || (sourceSuperType.scope.referenceContext.permittedTypes.length > 0 && sourceSuperType.scope.referenceContext.permittedTypes[0].isImplicit()))) {
sourceSuperType.setImplicitPermittedType(this);
}
}
return this.superInterfaces = superInterfaces;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12397,15 +12397,6 @@ public void sealedSealedTypeMissingPermits(SourceTypeBinding type, ASTNode node)
node.sourceEnd);
}

public void sealedInterfaceIsSealedAndNonSealed(SourceTypeBinding type, ASTNode node) {
String name = new String(type.sourceName());
this.handle(IProblem.SealedInterfaceIsSealedAndNonSealed,
new String[] { name },
new String[] { name },
node.sourceStart,
node.sourceEnd);
}

public void sealedDisAllowedNonSealedModifierInInterface(SourceTypeBinding type, TypeDeclaration typeDecl) {
String name = new String(type.sourceName());
this.handle(
Expand Down
Loading

0 comments on commit 0ab4ca3

Please sign in to comment.