diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java index 6b534474b6f..dd89c862dc5 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java @@ -2550,11 +2550,15 @@ public interface IProblem { int SealedLocalDirectSuperTypeSealed = TypeRelated + 1864; /** @since 3.28 */ int SealedAnonymousClassCannotExtendSealedType = TypeRelated + 1865; - /** @since 3.28 */ + /** @since 3.28 + * @deprecated problem no longer generated + */ int SealedSuperTypeInDifferentPackage = TypeRelated + 1866; - /** @since 3.28 */ + /** @since 3.28 + * @deprecated problem no longer generated + */ int SealedSuperTypeDisallowed = TypeRelated + 1867; - /* Java15 errors - end */ + /* Java17 Sealed types errors - end */ /** * @since 3.28 diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java index e254e3af717..ae0a9f56079 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java @@ -5842,7 +5842,6 @@ private int generateTypeAnnotationAttributeForTypeDeclaration() { superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts); } } - // TODO: permittedTypes codegen TypeParameter[] typeParameters = typeDeclaration.typeParameters; if (typeParameters != null) { for (int i = 0, max = typeParameters.length; i < max; i++) { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java index 5b9315289d9..c6639e7131f 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java @@ -556,7 +556,7 @@ && isTypeUseDeprecated(type, scope)) { public boolean isTypeReference() { return true; } -public boolean isImplicit() { +public boolean isSynthetic() { return false; } public boolean isWildcard() { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java index 39d145c3ae3..74ee28648a9 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java @@ -103,7 +103,7 @@ void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding anonymousType.tagBits |= TagBits.HierarchyHasProblems; anonymousType.setSuperInterfaces(Binding.NO_SUPERINTERFACES); } if (supertype.isSealed()) { - problemReporter().sealedAnonymousClassCannotExtendSealedType(typeReference, supertype); + problemReporter().anonymousClassCannotExtendSealedType(typeReference, supertype); anonymousType.tagBits |= TagBits.HierarchyHasProblems; anonymousType.setSuperInterfaces(Binding.NO_SUPERINTERFACES); } @@ -133,7 +133,7 @@ void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding anonymousType.tagBits |= TagBits.HierarchyHasProblems; anonymousType.setSuperClass(getJavaLangObject()); } else if (supertype.isSealed()) { - problemReporter().sealedAnonymousClassCannotExtendSealedType(typeReference, supertype); + problemReporter().anonymousClassCannotExtendSealedType(typeReference, supertype); anonymousType.tagBits |= TagBits.HierarchyHasProblems; anonymousType.setSuperClass(getJavaLangObject()); } @@ -577,7 +577,7 @@ private void checkAndSetModifiers() { switch (modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed | ClassFileConstants.AccFinal)) { case ExtraCompilerModifiers.AccSealed, ExtraCompilerModifiers.AccNonSealed, ClassFileConstants.AccFinal, ClassFileConstants.AccDefault : break; default : - problemReporter().IllegalModifierCombinationForType(sourceType); + problemReporter().illegalModifierCombinationForType(sourceType); break; } if (sourceType.isRecord()) { @@ -1190,6 +1190,14 @@ private boolean connectSuperclass() { } else { return connectRecordSuperclass(); } + } else if (superclass.isSealed() && sourceType.isLocalType()) { + sourceType.setSuperClass(superclass); + problemReporter().localTypeMayNotBePermittedType(sourceType, superclassRef, superclass); + return false; + } else if (superclass.isSealed() && !(sourceType.isFinal() || sourceType.isSealed() || sourceType.isNonSealed())) { + sourceType.setSuperClass(superclass); + problemReporter().permittedTypeNeedsModifier(sourceType, this.referenceContext, superclass); + return false; } else if ((superclass.tagBits & TagBits.HierarchyHasProblems) != 0 || !superclassRef.resolvedType.isValidBinding()) { sourceType.setSuperClass(superclass); @@ -1246,23 +1254,64 @@ private boolean connectEnumSuperclass() { return !foundCycle; } + /* Check that the permitted subtype and the sealed type are located in close proximity: either in the same module (if the superclass is in a named module) + * or in the same package (if the superclass is in the unnamed module) + * Return true, if all is well. Report error and return false otherwise, + */ + private boolean checkSealingProximity(ReferenceBinding subType, TypeReference subTypeReference, ReferenceBinding sealedType) { + final PackageBinding sealedTypePackage = sealedType.getPackage(); + final ModuleBinding sealedTypeModule = sealedType.module(); + if (subType.getPackage() != sealedTypePackage) { + if (sealedTypeModule.isUnnamed()) + problemReporter().permittedTypeOutsideOfPackage(subType, sealedType, subTypeReference, sealedTypePackage); + else if (subType.module() != sealedTypeModule) + problemReporter().permittedTypeOutsideOfModule(subType, sealedType, subTypeReference, sealedTypeModule); + } + return true; + } + void connectPermittedTypes() { SourceTypeBinding sourceType = this.referenceContext.binding; - if (this.referenceContext.permittedTypes != null && (this.referenceContext.permittedTypes.length == 0 || !this.referenceContext.permittedTypes[0].isImplicit())) { + if (this.referenceContext.permittedTypes != null && (this.referenceContext.permittedTypes.length == 0 || !this.referenceContext.permittedTypes[0].isSynthetic())) { sourceType.setPermittedTypes(Binding.NO_PERMITTED_TYPES); try { sourceType.tagBits |= TagBits.SealingTypeHierarchy; + if (!sourceType.isSealed()) + problemReporter().missingSealedModifier(sourceType, this.referenceContext); int length = this.referenceContext.permittedTypes.length; ReferenceBinding[] permittedTypeBindings = new ReferenceBinding[length]; int count = 0; nextPermittedType : for (int i = 0; i < length; i++) { TypeReference permittedTypeRef = this.referenceContext.permittedTypes[i]; ReferenceBinding permittedType = findPermittedtype(permittedTypeRef); - if (permittedType == null) { + if (permittedType == null || !permittedType.isValidBinding()) { continue nextPermittedType; } + if (sourceType.isClass()) { + ReferenceBinding superClass = permittedType.superclass(); + superClass = superClass == null ? null : superClass.actualType(); + if (!TypeBinding.equalsEquals(sourceType, superClass)) + problemReporter().sealedClassNotDirectSuperClassOf(permittedType, permittedTypeRef, sourceType); + } else if (sourceType.isInterface()) { + ReferenceBinding[] superInterfaces = permittedType.superInterfaces(); + boolean hierarchyOK = false; + if (superInterfaces != null) { + for (ReferenceBinding superInterface : superInterfaces) { + superInterface = superInterface == null ? null : superInterface.actualType(); + if (TypeBinding.equalsEquals(sourceType, superInterface)) { + hierarchyOK = true; + break; + } + } + if (!hierarchyOK) + problemReporter().sealedInterfaceNotDirectSuperInterfaceOf(permittedType, permittedTypeRef, sourceType); + } + } + + checkSealingProximity(permittedType, permittedTypeRef, sourceType); + for (int j = 0; j < i; j++) { if (TypeBinding.equalsEquals(permittedTypeBindings[j], permittedType)) { problemReporter().duplicatePermittedType(sourceType, permittedTypeRef, permittedType); @@ -1287,7 +1336,7 @@ void connectPermittedTypes() { sourceType.setPermittedTypes(Binding.NO_PERMITTED_TYPES); if (sourceType.isSealed()) { if (!sourceType.isLocalType() && !sourceType.isRecord() && !sourceType.isEnum()) // error flagged alread - problemReporter().sealedSealedTypeMissingPermits(sourceType, this.referenceContext); + problemReporter().sealedTypeMissingPermits(sourceType, this.referenceContext); } } } @@ -1320,70 +1369,89 @@ private boolean connectRecordSuperclass() { */ private boolean connectSuperInterfaces() { SourceTypeBinding sourceType = this.referenceContext.binding; - sourceType.setSuperInterfaces(Binding.NO_SUPERINTERFACES); - if (this.referenceContext.superInterfaces == null) { - if (sourceType.isAnnotationType() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { // do not connect if source < 1.5 as annotation already got flagged as syntax error) { - ReferenceBinding annotationType = getJavaLangAnnotationAnnotation(); - boolean foundCycle = detectHierarchyCycle(sourceType, annotationType, null); - sourceType.setSuperInterfaces(new ReferenceBinding[] { annotationType }); - return !foundCycle; - } - return true; - } - if (sourceType.id == TypeIds.T_JavaLangObject) // already handled the case of redefining java.lang.Object - return true; - + boolean hasSealedSupertype = sourceType.superclass == null ? false : sourceType.superclass.isSealed(); boolean noProblems = true; - int length = this.referenceContext.superInterfaces.length; - ReferenceBinding[] interfaceBindings = new ReferenceBinding[length]; - int count = 0; - nextInterface : for (int i = 0; i < length; i++) { - TypeReference superInterfaceRef = this.referenceContext.superInterfaces[i]; - ReferenceBinding superInterface = findSupertype(superInterfaceRef); - if (superInterface == null) { // detected cycle - sourceType.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextInterface; + try { + sourceType.setSuperInterfaces(Binding.NO_SUPERINTERFACES); + if (this.referenceContext.superInterfaces == null) { + if (sourceType.isAnnotationType() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { // do not connect if source < 1.5 as annotation already got flagged as syntax error) { + ReferenceBinding annotationType = getJavaLangAnnotationAnnotation(); + boolean foundCycle = detectHierarchyCycle(sourceType, annotationType, null); + sourceType.setSuperInterfaces(new ReferenceBinding[] { annotationType }); + return !foundCycle; + } + return true; } + if (sourceType.id == TypeIds.T_JavaLangObject) // already handled the case of redefining java.lang.Object + return true; - // check for simple interface collisions - // Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I) - for (int j = 0; j < i; j++) { - if (TypeBinding.equalsEquals(interfaceBindings[j], superInterface)) { - problemReporter().duplicateSuperinterface(sourceType, superInterfaceRef, superInterface); + int length = this.referenceContext.superInterfaces.length; + ReferenceBinding[] interfaceBindings = new ReferenceBinding[length]; + int count = 0; + nextInterface : for (int i = 0; i < length; i++) { + TypeReference superInterfaceRef = this.referenceContext.superInterfaces[i]; + ReferenceBinding superInterface = findSupertype(superInterfaceRef); + if (superInterface == null) { // detected cycle sourceType.tagBits |= TagBits.HierarchyHasProblems; noProblems = false; continue nextInterface; } + + if (superInterface.isSealed()) + hasSealedSupertype = true; + + // check for simple interface collisions + // Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I) + for (int j = 0; j < i; j++) { + if (TypeBinding.equalsEquals(interfaceBindings[j], superInterface)) { + problemReporter().duplicateSuperinterface(sourceType, superInterfaceRef, superInterface); + sourceType.tagBits |= TagBits.HierarchyHasProblems; + noProblems = false; + continue nextInterface; + } + } + if (!superInterface.isInterface() && (superInterface.tagBits & TagBits.HasMissingType) == 0) { + problemReporter().superinterfaceMustBeAnInterface(sourceType, superInterfaceRef, superInterface); + sourceType.tagBits |= TagBits.HierarchyHasProblems; + noProblems = false; + continue nextInterface; + } else if (superInterface.isAnnotationType()){ + problemReporter().annotationTypeUsedAsSuperinterface(sourceType, superInterfaceRef, superInterface); + } + if ((superInterface.tagBits & TagBits.HasDirectWildcard) != 0) { + problemReporter().superTypeCannotUseWildcard(sourceType, superInterfaceRef, superInterface); + sourceType.tagBits |= TagBits.HierarchyHasProblems; + noProblems = false; + continue nextInterface; + } + if ((superInterface.tagBits & TagBits.HierarchyHasProblems) != 0 + || !superInterfaceRef.resolvedType.isValidBinding()) { + sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype + noProblems &= superInterfaceRef.resolvedType.isValidBinding(); + } + if (superInterface.isSealed() && sourceType.isLocalType()) { + problemReporter().localTypeMayNotBePermittedType(sourceType, superInterfaceRef, superInterface); + noProblems = false; + } else if (superInterface.isSealed() && !(sourceType.isFinal() || sourceType.isSealed() || sourceType.isNonSealed())) { + problemReporter().permittedTypeNeedsModifier(sourceType, this.referenceContext, superInterface); + noProblems = false; + } + + // only want to reach here when no errors are reported + sourceType.typeBits |= (superInterface.typeBits & TypeIds.InheritableBits); + interfaceBindings[count++] = superInterface; } - if (!superInterface.isInterface() && (superInterface.tagBits & TagBits.HasMissingType) == 0) { - problemReporter().superinterfaceMustBeAnInterface(sourceType, superInterfaceRef, superInterface); - sourceType.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextInterface; - } else if (superInterface.isAnnotationType()){ - problemReporter().annotationTypeUsedAsSuperinterface(sourceType, superInterfaceRef, superInterface); - } - if ((superInterface.tagBits & TagBits.HasDirectWildcard) != 0) { - problemReporter().superTypeCannotUseWildcard(sourceType, superInterfaceRef, superInterface); - sourceType.tagBits |= TagBits.HierarchyHasProblems; - noProblems = false; - continue nextInterface; + // hold onto all correctly resolved superinterfaces + if (count > 0) { + if (count != length) + System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[count], 0, count); + sourceType.setSuperInterfaces(interfaceBindings); } - if ((superInterface.tagBits & TagBits.HierarchyHasProblems) != 0 - || !superInterfaceRef.resolvedType.isValidBinding()) { - sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype - noProblems &= superInterfaceRef.resolvedType.isValidBinding(); + } finally { + if (sourceType.isNonSealed() && !hasSealedSupertype) { + if (!sourceType.isRecord() && !sourceType.isLocalType() && !sourceType.isEnum() && !sourceType.isSealed()) // avoid double jeopardy + problemReporter().disallowedNonSealedModifier(sourceType, this.referenceContext); } - // only want to reach here when no errors are reported - sourceType.typeBits |= (superInterface.typeBits & TypeIds.InheritableBits); - interfaceBindings[count++] = superInterface; - } - // hold onto all correctly resolved superinterfaces - if (count > 0) { - if (count != length) - System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[count], 0, count); - sourceType.setSuperInterfaces(interfaceBindings); } return noProblems; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java index 9c6f58857ce..d436a36ba5c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java @@ -55,7 +55,6 @@ *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1098,201 +1097,49 @@ private void checkAnnotationsInType() { void faultInTypesForFieldsAndMethods() { if (!isPrototype()) throw new IllegalStateException(); - checkPermitsInType(); + if (!this.isLocalType()) + complainIfUnpermittedSubtyping(); // this has nothing to do with fields and methods but time is ripe for this check. checkAnnotationsInType(); internalFaultInTypeForFieldsAndMethods(); } -private Map.Entry getFirstSealedSuperTypeOrInterface(TypeDeclaration typeDecl) { - boolean isAnySuperTypeSealed = typeDecl.superclass != null && this.superclass != null ? this.superclass.isSealed() : false; - if (isAnySuperTypeSealed) - return new AbstractMap.SimpleEntry<>(typeDecl.superclass, this.superclass); +private boolean isAnUnpermittedSubtypeOf(ReferenceBinding superType) { - ReferenceBinding[] superInterfaces1 = this.superInterfaces(); - int l = superInterfaces1 != null ? superInterfaces1.length : 0; - for (int i = 0; i < l; ++i) { - ReferenceBinding superInterface = superInterfaces1[i]; - if (superInterface.isSealed()) { - return new AbstractMap.SimpleEntry<>(typeDecl.superInterfaces[i], superInterface); - } + if (superType == null || !superType.isSealed()) + return false; + + for (ReferenceBinding permittedType : superType.actualType().permittedTypes()) { + if (TypeBinding.equalsEquals(this, permittedType)) + return false; } - return null; + + return true; } -private void checkPermitsInType() { +private void complainIfUnpermittedSubtyping() { + + // Diagnose unauthorized subtyping: This cannot be correctly hoisted into ClassScope.{ connectSuperclass() | connectSuperInterfaces() | connectPermittedTypes() } + // but can be taken up now + TypeDeclaration typeDecl = this.scope.referenceContext; - boolean hasPermittedTypes = this.permittedTypes != null && this.permittedTypes.length > 0; - if (hasPermittedTypes) { - if (!this.isSealed()) - this.scope.problemReporter().sealedMissingSealedModifier(this, typeDecl); - ModuleBinding sourceModuleBinding = this.module(); - boolean isUnnamedModule = sourceModuleBinding.isUnnamed(); - if (isUnnamedModule) { - PackageBinding sourceTypePackage = this.getPackage(); - for (int i =0, l = this.permittedTypes.length; i < l; i++) { - ReferenceBinding permType = this.permittedTypes[i]; - if (!permType.isValidBinding()) continue; - if (sourceTypePackage != permType.getPackage()) { - TypeReference permittedTypeRef = typeDecl.permittedTypes[i]; - this.scope.problemReporter().sealedPermittedTypeOutsideOfPackage(permType, this, permittedTypeRef, sourceTypePackage); - } - } - } else { - for (int i = 0, l = this.permittedTypes.length; i < l; i++) { - ReferenceBinding permType = this.permittedTypes[i]; - if (!permType.isValidBinding()) continue; - ModuleBinding permTypeModule = permType.module(); - if (permTypeModule != null && sourceModuleBinding != permTypeModule) { - TypeReference permittedTypeRef = typeDecl.permittedTypes[i]; - this.scope.problemReporter().sealedPermittedTypeOutsideOfModule(permType, this, permittedTypeRef, sourceModuleBinding); - } - } - } + if (this.isAnUnpermittedSubtypeOf(this.superclass)) { + this.scope.problemReporter().sealedSupertypeDoesNotPermit(this, typeDecl.superclass, this.superclass); } -// ReferenceBinding superType = this.superclass(); - Map.Entry sealedEntry = getFirstSealedSuperTypeOrInterface(typeDecl); - boolean foundSealedSuperTypeOrInterface = sealedEntry != null; - if (this.isLocalType()) { - if (this.isSealed() || this.isNonSealed()) - return; // already handled elsewhere - if (foundSealedSuperTypeOrInterface) { - this.scope.problemReporter().sealedLocalDirectSuperTypeSealed(this, sealedEntry.getKey(), sealedEntry.getValue()); - return; - } - } else if (this.isNonSealed()) { - 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) { - if (!(this.isFinal() || this.isSealed() || this.isNonSealed())) { - if (this.isClass()) - this.scope.problemReporter().sealedMissingClassModifier(this, typeDecl, sealedEntry.getValue()); - else if (this.isInterface()) - this.scope.problemReporter().sealedMissingInterfaceModifier(this, typeDecl, sealedEntry.getValue()); - } - if (!typeDecl.isRecord() && typeDecl.superclass != null && !checkPermitsAndAdd(this.superclass)) { - reportSealedSuperTypeDoesNotPermitProblem(typeDecl.superclass, this.superclass); - } - for (int i = 0, l = this.superInterfaces.length; i < l; ++i) { - ReferenceBinding superInterface = this.superInterfaces[i]; - if (superInterface != null && !checkPermitsAndAdd(superInterface)) { - TypeReference superInterfaceRef = typeDecl.superInterfaces[i]; - reportSealedSuperTypeDoesNotPermitProblem(superInterfaceRef, superInterface); - } + for (int i = 0, l = this.superInterfaces.length; i < l; ++i) { + ReferenceBinding superInterface = this.superInterfaces[i]; + if (this.isAnUnpermittedSubtypeOf(superInterface)) { + TypeReference superInterfaceRef = typeDecl.superInterfaces[i]; + this.scope.problemReporter().sealedSupertypeDoesNotPermit(this, superInterfaceRef, superInterface); } } + for (ReferenceBinding memberType : this.memberTypes) - ((SourceTypeBinding) memberType).checkPermitsInType(); + ((SourceTypeBinding) memberType).complainIfUnpermittedSubtyping(); - if (this.scope.referenceContext.permittedTypes == null) { - // Ignore implicitly permitted case - return; - } - // In case of errors, be safe. - int l = this.permittedTypes.length <= this.scope.referenceContext.permittedTypes.length ? - this.permittedTypes.length : this.scope.referenceContext.permittedTypes.length; - for (int i = 0; i < l; i++) { - TypeReference permittedTypeRef = this.scope.referenceContext.permittedTypes[i]; - ReferenceBinding permittedType = this.permittedTypes[i]; - if (permittedType == null || !permittedType.isValidBinding()) - continue; - if (this.isClass()) { - ReferenceBinding permSuperType = permittedType.superclass(); - permSuperType = permSuperType.actualType(); - if (!TypeBinding.equalsEquals(this, permSuperType)) { - this.scope.problemReporter().sealedNotDirectSuperClass(permittedType, permittedTypeRef, this); - continue; - } - } else if (this.isInterface()) { - ReferenceBinding[] permSuperInterfaces = permittedType.superInterfaces(); - boolean foundSuperInterface = false; - if (permSuperInterfaces != null) { - for (ReferenceBinding psi : permSuperInterfaces) { - psi = psi.actualType(); - if (TypeBinding.equalsEquals(this, psi)) { - foundSuperInterface = true; - break; - } - } - if (!foundSuperInterface) { - this.scope.problemReporter().sealedNotDirectSuperInterface(permittedType, permittedTypeRef, this); - continue; - } - } - } - } return; } -private void reportSealedSuperTypeDoesNotPermitProblem(TypeReference superTypeRef, TypeBinding superType) { - ModuleBinding sourceModuleBinding = this.module(); - boolean isUnnamedModule = sourceModuleBinding.isUnnamed(); - boolean isClass = false; - if (superType.isClass()) { - isClass = true; - } - boolean sealedSuperTypeDoesNotPermit = false; - ReferenceBinding superReferenceBinding = null; - if (superType instanceof ReferenceBinding) { - superReferenceBinding = (ReferenceBinding) superType; - if (isUnnamedModule) { - PackageBinding superTypePackage = superReferenceBinding.getPackage(); - PackageBinding pkg = this.getPackage(); - sealedSuperTypeDoesNotPermit = pkg!= null && pkg.equals(superTypePackage); - } else { - ModuleBinding superTypeModule = superReferenceBinding.module(); - ModuleBinding mod = this.module(); - sealedSuperTypeDoesNotPermit = mod!= null && mod.equals(superTypeModule); - } - } - if (sealedSuperTypeDoesNotPermit) { - if (isClass) { - this.scope.problemReporter().sealedSuperClassDoesNotPermit(this, superTypeRef, superType); - } else { - this.scope.problemReporter().sealedSuperInterfaceDoesNotPermit(this, superTypeRef, superType); - } - } else { - if (superReferenceBinding instanceof SourceTypeBinding && isUnnamedModule) { - PackageBinding superTypePackage = superReferenceBinding.getPackage(); - if (isClass) { - this.scope.problemReporter().sealedSuperClassInDifferentPackage(this, superTypeRef, superType, superTypePackage); - } else { - this.scope.problemReporter().sealedSuperInterfaceInDifferentPackage(this, superTypeRef, superType, superTypePackage); - } - } else { - if (isClass) { - this.scope.problemReporter().sealedSuperClassDisallowed(this, superTypeRef, superType); - } else { - this.scope.problemReporter().sealedSuperInterfaceDisallowed(this, superTypeRef, superType); - } - } - } -} - -private boolean checkPermitsAndAdd(ReferenceBinding superType) { - if (superType == null - || superType.equals(this.scope.getJavaLangObject()) - || !superType.isSealed()) - return true; - if (superType.isSealed()) { - superType = superType.actualType(); - ReferenceBinding[] superPermittedTypes = superType.permittedTypes(); - for (ReferenceBinding permittedType : superPermittedTypes) { - permittedType = permittedType.actualType(); - if (permittedType.isValidBinding() && TypeBinding.equalsEquals(this, permittedType)) - return true; - } - } - return false; -} - @Override public RecordComponentBinding[] components() { @@ -3229,7 +3076,7 @@ public ReferenceBinding setSuperClass(ReferenceBinding 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.scope.referenceContext.permittedTypes == null || (sourceSuperType.scope.referenceContext.permittedTypes.length > 0 && sourceSuperType.scope.referenceContext.permittedTypes[0].isSynthetic()))) { sourceSuperType.setImplicitPermittedType(this); if (this.isAnonymousType() && superClass.isEnum()) this.modifiers |= ClassFileConstants.AccFinal; @@ -3269,7 +3116,7 @@ private void setImplicitPermittedType(SourceTypeBinding permittedType) { 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.scope.referenceContext.permittedTypes == null || (sourceSuperType.scope.referenceContext.permittedTypes.length > 0 && sourceSuperType.scope.referenceContext.permittedTypes[0].isSynthetic()))) { sourceSuperType.setImplicitPermittedType(this); } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index 4f2b75af875..bfd57a0227b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -3343,7 +3343,7 @@ public void illegalVisibilityModifierCombinationForField(ReferenceBinding type, fieldDecl.sourceStart, fieldDecl.sourceEnd); } -public void IllegalModifierCombinationForType(SourceTypeBinding type) { +public void illegalModifierCombinationForType(SourceTypeBinding type) { String[] arguments = new String[] {new String(type.sourceName())}; this.handle( IProblem.IllegalModifierCombinationForType, @@ -12230,107 +12230,54 @@ public void illegalModifierForLocalEnumDeclaration(SourceTypeBinding type) { type.sourceStart(), type.sourceEnd()); } -private void sealedMissingModifier(int problem, SourceTypeBinding type, TypeDeclaration typeDecl, TypeBinding superTypeBinding) { + +public void permittedTypeNeedsModifier(SourceTypeBinding type, TypeDeclaration typeDecl, TypeBinding superTypeBinding) { String name = new String(type.sourceName()); String superTypeFullName = new String(superTypeBinding.readableName()); String superTypeShortName = new String(superTypeBinding.shortReadableName()); if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName; this.handle( - problem, + type.isClass() ? IProblem.SealedMissingClassModifier : IProblem.SealedMissingInterfaceModifier, new String[] {superTypeFullName, name}, new String[] {superTypeShortName, name}, typeDecl.sourceStart, typeDecl.sourceEnd); } -public void sealedMissingClassModifier(SourceTypeBinding type, TypeDeclaration typeDecl, TypeBinding superTypeBinding) { - sealedMissingModifier(IProblem.SealedMissingClassModifier, type, typeDecl, superTypeBinding); -} -public void sealedMissingInterfaceModifier(SourceTypeBinding type, TypeDeclaration typeDecl, TypeBinding superTypeBinding) { - sealedMissingModifier(IProblem.SealedMissingInterfaceModifier, type, typeDecl, superTypeBinding); -} -public void sealedDisAllowedNonSealedModifierInClass(SourceTypeBinding type, TypeDeclaration typeDecl) { +public void disallowedNonSealedModifier(SourceTypeBinding type, TypeDeclaration typeDecl) { String name = new String(type.sourceName()); this.handle( - IProblem.SealedDisAllowedNonSealedModifierInClass, + type.isClass() ? IProblem.SealedDisAllowedNonSealedModifierInClass : IProblem.SealedDisAllowedNonSealedModifierInInterface, new String[] { name }, new String[] { name }, typeDecl.sourceStart, typeDecl.sourceEnd); } -private void sealedSuperTypeDoesNotPermit(int problem, SourceTypeBinding type, TypeReference superType, TypeBinding superTypeBinding) { - String name = new String(type.sourceName()); - String superTypeFullName = new String(superTypeBinding.readableName()); - String superTypeShortName = new String(superTypeBinding.shortReadableName()); - if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName; - this.handle( - problem, - new String[] {name, superTypeFullName}, - new String[] {name, superTypeShortName}, - superType.sourceStart, - superType.sourceEnd); -} - -public void sealedSuperTypeInDifferentPackage(int problem, SourceTypeBinding type, TypeReference curType, TypeBinding superTypeBinding, PackageBinding superPackageBinding) { - String typeName = new String(type.sourceName); - String name = new String(superTypeBinding.sourceName()); - String packageName = superPackageBinding.compoundName == CharOperation.NO_CHAR_CHAR ? "default" : //$NON-NLS-1$ - CharOperation.toString(superPackageBinding.compoundName); - String[] arguments = new String[] {typeName, packageName, name}; - this.handle(problem, - arguments, - arguments, - curType.sourceStart, - curType.sourceEnd); -} - -public void sealedSuperTypeDisallowed(int problem, SourceTypeBinding type, TypeReference curType, TypeBinding superTypeBinding) { - String typeName = new String(type.sourceName); - String name = new String(superTypeBinding.sourceName()); - String[] arguments = new String[] {typeName, name}; - this.handle(problem, - arguments, - arguments, - curType.sourceStart, - curType.sourceEnd); -} - -public void sealedSuperClassDoesNotPermit(SourceTypeBinding type, TypeReference superType, TypeBinding superTypeBinding) { - sealedSuperTypeDoesNotPermit(IProblem.SealedSuperClassDoesNotPermit, type, superType, superTypeBinding); -} - -public void sealedSuperClassInDifferentPackage(SourceTypeBinding type, TypeReference curType, TypeBinding superTypeBinding, PackageBinding superPackageBinding) { - sealedSuperTypeInDifferentPackage(IProblem.SealedSuperTypeInDifferentPackage, type, curType, superTypeBinding, superPackageBinding); -} - -public void sealedSuperClassDisallowed(SourceTypeBinding type, TypeReference curType, TypeBinding superTypeBinding) { - sealedSuperTypeDisallowed(IProblem.SealedSuperTypeDisallowed, type, curType, superTypeBinding); -} - -public void sealedSuperInterfaceDoesNotPermit(SourceTypeBinding type, TypeReference superType, TypeBinding superTypeBinding) { +public void sealedSupertypeDoesNotPermit(SourceTypeBinding type, TypeReference superType, TypeBinding superTypeBinding) { String name = new String(type.sourceName()); String superTypeFullName = new String(superTypeBinding.readableName()); String superTypeShortName = new String(superTypeBinding.shortReadableName()); - String keyword = type.isClass() ? new String(TypeConstants.IMPLEMENTS) : new String(TypeConstants.KEYWORD_EXTENDS); if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName; - this.handle( - IProblem.SealedSuperInterfaceDoesNotPermit, - new String[] {name, superTypeFullName, keyword}, - new String[] {name, superTypeShortName, keyword}, - superType.sourceStart, - superType.sourceEnd); -} - -public void sealedSuperInterfaceInDifferentPackage(SourceTypeBinding type, TypeReference curType, TypeBinding superTypeBinding, PackageBinding superPackageBinding) { - sealedSuperTypeInDifferentPackage(IProblem.SealedSuperTypeInDifferentPackage, type, curType, superTypeBinding, superPackageBinding); -} - -public void sealedSuperInterfaceDisallowed(SourceTypeBinding type, TypeReference curType, TypeBinding superTypeBinding) { - sealedSuperTypeDisallowed(IProblem.SealedSuperTypeDisallowed, type, curType, superTypeBinding); + if (superTypeBinding.isClass()) { + this.handle( + IProblem.SealedSuperClassDoesNotPermit, + new String[] {name, superTypeFullName}, + new String[] {name, superTypeShortName}, + superType.sourceStart, + superType.sourceEnd); + } else { + String keyword = type.isClass() ? new String(TypeConstants.IMPLEMENTS) : new String(TypeConstants.KEYWORD_EXTENDS); + this.handle( + IProblem.SealedSuperInterfaceDoesNotPermit, + new String[] {name, superTypeFullName, keyword}, + new String[] {name, superTypeShortName, keyword}, + superType.sourceStart, + superType.sourceEnd); + } } -public void sealedMissingSealedModifier(SourceTypeBinding type, ASTNode node) { +public void missingSealedModifier(SourceTypeBinding type, ASTNode node) { String name = new String(type.sourceName()); this.handle(IProblem.SealedMissingSealedModifier, new String[] { name }, new String[] { name }, node.sourceStart, node.sourceEnd); @@ -12349,7 +12296,7 @@ public void duplicatePermittedType(SourceTypeBinding type, TypeReference referen reference.sourceEnd); } -public void sealedNotDirectSuperClass(ReferenceBinding type, TypeReference reference, SourceTypeBinding superType) { +public void sealedClassNotDirectSuperClassOf(ReferenceBinding type, TypeReference reference, SourceTypeBinding superType) { this.handle( IProblem.SealedNotDirectSuperClass, new String[] { @@ -12361,9 +12308,9 @@ public void sealedNotDirectSuperClass(ReferenceBinding type, TypeReference refer reference.sourceStart, reference.sourceEnd); } -public void sealedPermittedTypeOutsideOfModule(ReferenceBinding permType, SourceTypeBinding type, ASTNode node, ModuleBinding moduleBinding) { +public void permittedTypeOutsideOfModule(ReferenceBinding permType, ReferenceBinding sealedType, ASTNode node, ModuleBinding moduleBinding) { String permTypeName = new String(permType.sourceName); - String name = new String(type.sourceName()); + String name = new String(sealedType.sourceName()); String moduleName = new String(moduleBinding.name()); String[] arguments = new String[] {permTypeName, moduleName, name}; this.handle(IProblem.SealedPermittedTypeOutsideOfModule, @@ -12372,15 +12319,9 @@ public void sealedPermittedTypeOutsideOfModule(ReferenceBinding permType, Source node.sourceStart, node.sourceEnd); } -public void sealedPermittedTypeOutsideOfModule(SourceTypeBinding type, ASTNode node) { - String name = new String(type.sourceName()); - this.handle(IProblem.SealedPermittedTypeOutsideOfModule, new String[] { name }, new String[] { name }, - node.sourceStart, node.sourceEnd); -} - -public void sealedPermittedTypeOutsideOfPackage(ReferenceBinding permType, SourceTypeBinding type, ASTNode node, PackageBinding packageBinding) { +public void permittedTypeOutsideOfPackage(ReferenceBinding permType, ReferenceBinding sealedType, ASTNode node, PackageBinding packageBinding) { String permTypeName = new String(permType.sourceName); - String name = new String(type.sourceName()); + String name = new String(sealedType.sourceName()); String packageName = packageBinding.compoundName == CharOperation.NO_CHAR_CHAR ? "default" : //$NON-NLS-1$ CharOperation.toString(packageBinding.compoundName); String[] arguments = new String[] {permTypeName, packageName, name}; @@ -12391,23 +12332,13 @@ public void sealedPermittedTypeOutsideOfPackage(ReferenceBinding permType, Sourc node.sourceEnd); } -public void sealedSealedTypeMissingPermits(SourceTypeBinding type, ASTNode node) { +public void sealedTypeMissingPermits(SourceTypeBinding type, ASTNode node) { String name = new String(type.sourceName()); this.handle(IProblem.SealedSealedTypeMissingPermits, 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( - IProblem.SealedDisAllowedNonSealedModifierInInterface, - new String[] { name }, - new String[] { name }, - typeDecl.sourceStart, - typeDecl.sourceEnd); -} - -public void sealedNotDirectSuperInterface(ReferenceBinding type, TypeReference reference, SourceTypeBinding superType) { +public void sealedInterfaceNotDirectSuperInterfaceOf(ReferenceBinding type, TypeReference reference, SourceTypeBinding superType) { this.handle( IProblem.SealedNotDirectSuperInterface, new String[] { @@ -12420,7 +12351,7 @@ public void sealedNotDirectSuperInterface(ReferenceBinding type, TypeReference r reference.sourceEnd); } -public void sealedLocalDirectSuperTypeSealed(SourceTypeBinding type, TypeReference superclass, TypeBinding superTypeBinding) { +public void localTypeMayNotBePermittedType(SourceTypeBinding type, TypeReference superclass, TypeBinding superTypeBinding) { String name = new String(type.sourceName()); String superTypeFullName = new String(superTypeBinding.readableName()); String superTypeShortName = new String(superTypeBinding.shortReadableName()); @@ -12432,7 +12363,7 @@ public void sealedLocalDirectSuperTypeSealed(SourceTypeBinding type, TypeReferen superclass.sourceStart, superclass.sourceEnd); } -public void sealedAnonymousClassCannotExtendSealedType(TypeReference reference, TypeBinding type) { +public void anonymousClassCannotExtendSealedType(TypeReference reference, TypeBinding type) { this.handle( IProblem.SealedAnonymousClassCannotExtendSealedType, new String[] {new String(type.readableName())}, diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties index 5796ad53262..1aac0cda513 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties @@ -1131,7 +1131,7 @@ # Java 16 1820 = {0} is a value-based type which is a discouraged argument for the synchronized statement -# Java 15 Preview - cont +# Sealed types - Java 17 1850 = The class {1} with a sealed direct superclass or a sealed direct superinterface {0} should be declared either final, sealed, or non-sealed 1851 = A class {0} declared as non-sealed should have either a sealed direct superclass or a sealed direct superinterface 1852 = The type {0} extending a sealed class {1} should be a permitted subtype of {1} @@ -1143,13 +1143,13 @@ 1858 = Permitted type {0} in a named module {1} should be declared in the same module {1} of declaring type {2} 1859 = Permitted type {0} in an unnamed module should be declared in the same package {1} of declaring type {2} 1860 = Sealed class or interface lacks the permits clause and no class or interface from the same compilation unit declares {0} as its direct superclass or superinterface -1861 = An interface {0} is declared both sealed and non-sealed +###[obsolete] 1861 = An interface {0} is declared both sealed and non-sealed 1862 = An interface {0} declared as non-sealed should have a sealed direct superinterface 1863 = Permitted type {0} does not declare {1} as direct super interface -1864 = A local class {1} cannot have a sealed direct superclass or a sealed direct superinterface {0} +1864 = The local type {1} may not have a sealed supertype {0} 1865 = An anonymous class cannot subclass a sealed type {0} -1866 = Sealed type {2} and sub type {0} in an unnamed module should be declared in the same package {1} -1867 = Sealed type {1} cannot be super type of {0} as it is from a different package or split package or module +###[obsolete] 1866 = Sealed type {2} and sub type {0} in an unnamed module should be declared in the same package {1} +###[obsolete] 1867 = Sealed type {1} cannot be super type of {0} as it is from a different package or split package or module # Switch Patterns - Java 21 1900 = Local variable {0} referenced from a guard must be final or effectively final diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java index 79c0e51e9a6..e546688db04 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java @@ -626,7 +626,7 @@ public void testBug563806_010() { "1. ERROR in p2\\Y.java (at line 2)\n" + " public final class Y extends p1.X{}\n" + " ^^^^\n" + - "Sealed type X and sub type Y in an unnamed module should be declared in the same package p1\n" + + "The type Y extending a sealed class X should be a permitted subtype of X\n" + "----------\n"); } public void testBug563806_011() { @@ -660,7 +660,7 @@ public void testBug563806_012() { "1. ERROR in p2\\Y.java (at line 2)\n" + " public final class Y implements p1.X{}\n" + " ^^^^\n" + - "Sealed type X and sub type Y in an unnamed module should be declared in the same package p1\n" + + "The type Y that implements a sealed interface X should be a permitted subtype of X\n" + "----------\n"); } public void testBug563806_013() { @@ -705,7 +705,7 @@ public void testBug563806_014() { "2. ERROR in p2\\Y.java (at line 2)\n" + " public interface Y extends p1.X{}\n" + " ^^^^\n" + - "Sealed type X and sub type Y in an unnamed module should be declared in the same package p1\n" + + "The type Y that extends a sealed interface X should be a permitted subtype of X\n" + "----------\n"); } public void testBug563806_015() { @@ -1219,7 +1219,7 @@ public void testBug563806_039() { "2. ERROR in p1\\X.java (at line 5)\n" + " class Y extends A{}\n" + " ^\n" + - "A local class Y cannot have a sealed direct superclass or a sealed direct superinterface A\n" + + "The local type Y may not have a sealed supertype A\n" + "----------\n"); } public void testBug564191_001() throws IOException, ClassFormatException { @@ -5547,12 +5547,12 @@ public void testBug568854_007() { "1. ERROR in X.java (at line 5)\n" + " class Y implements I {}\n" + " ^\n" + - "A local class Y cannot have a sealed direct superclass or a sealed direct superinterface I\n" + + "The local type Y may not have a sealed supertype I\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + " class Z implements I{}\n" + " ^\n" + - "A local class Z cannot have a sealed direct superclass or a sealed direct superinterface I\n" + + "The local type Z may not have a sealed supertype I\n" + "----------\n"); } public void testBug568854_008() { @@ -5576,12 +5576,12 @@ public void testBug568854_008() { "1. ERROR in X.java (at line 6)\n" + " class Y implements I {}\n" + " ^\n" + - "A local class Y cannot have a sealed direct superclass or a sealed direct superinterface I\n" + + "The local type Y may not have a sealed supertype I\n" + "----------\n" + "2. ERROR in X.java (at line 10)\n" + " class Z implements I{}\n" + " ^\n" + - "A local class Z cannot have a sealed direct superclass or a sealed direct superinterface I\n" + + "The local type Z may not have a sealed supertype I\n" + "----------\n"); } public void testBug571332_001() { @@ -5623,7 +5623,7 @@ public void testBug570605_001() { "1. ERROR in X.java (at line 6)\n" + " class L extends Y {}\n" + " ^\n" + - "A local class L cannot have a sealed direct superclass or a sealed direct superinterface Y\n" + + "The local type L may not have a sealed supertype Y\n" + "----------\n"); } public void testBug570218_001() { @@ -5669,7 +5669,7 @@ public void testBug572205_001() { "1. ERROR in X.java (at line 3)\n" + " class Circle implements Shape{}\n" + " ^^^^^\n" + - "A local class Circle cannot have a sealed direct superclass or a sealed direct superinterface X.Shape\n" + + "The local type Circle may not have a sealed supertype X.Shape\n" + "----------\n" + "2. ERROR in X.java (at line 5)\n" + " sealed interface Shape {}\n" + diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java index b0ef7dae9e3..34e348feed8 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java @@ -1017,7 +1017,7 @@ public String toString() { return new String(this.token); } @Override - public boolean isImplicit() { + public boolean isSynthetic() { return true; } }