From d5f9151d84ee2416f245d81e35e5bc056ca47abd Mon Sep 17 00:00:00 2001 From: Suby S Surendran Date: Wed, 13 Nov 2024 12:27:28 +0530 Subject: [PATCH] Added more test & handled the upper 16 bits for sealed and non-sealed --- .../lookup/ExtraCompilerModifiers.java | 4 +- .../compiler/lookup/ReferenceBinding.java | 4 - .../core/tests/dom/ASTConverter_23Test.java | 213 ++++++++++++++++++ .../org/eclipse/jdt/core/dom/Modifier.java | 10 +- .../org/eclipse/jdt/core/dom/TypeBinding.java | 6 +- 5 files changed, 226 insertions(+), 11 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java index d509a5d8576..c28b24760df 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java @@ -45,14 +45,14 @@ public interface ExtraCompilerModifiers { // modifier constant final int AccUnresolved = ASTNode.Bit26; final int AccBlankFinal = ASTNode.Bit27; // for blank final variables final int AccIsDefaultConstructor = ASTNode.Bit27; // for default constructor - final int AccNonSealed = ASTNode.Bit29; // for class/interface + final int AccNonSealed = ASTNode.Bit27; // for class/interface final int AccLocallyUsed = ASTNode.Bit28; // used to diagnose unused (a) private/local members or (b) members of private classes // generally set when actual usage has been detected // or, (b) when member of a private class is exposed via a non-private subclass // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281 final int AccVisibilityMASK = ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate; - final int AccSealed = ASTNode.Bit26; // used for class/interface to set sealed + final int AccSealed = ASTNode.Bit29; // used for class/interface to set sealed final int AccOverriding = ASTNode.Bit29; // record fact a method overrides another one final int AccImplementing = ASTNode.Bit30; // record fact a method implements another one (it is concrete and overrides an abstract one) final int AccImplicitlyDeclared = ASTNode.Bit30; // used for implicitly declared classes diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java index d524682733d..33286162ac6 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java @@ -1083,10 +1083,6 @@ public final int getAccessFlags() { return this.modifiers & ExtraCompilerModifiers.AccJustFlag; } -public final int getAccessFlagsForSealedAndNonSealed() { - return ((this.modifiers >>> 16) & 0xFFFF) & ExtraCompilerModifiers.AccJustFlag; -} - /** * @return the JSR 175 annotations for this type. */ diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_23Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_23Test.java index fa30479822a..8e572537479 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_23Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_23Test.java @@ -188,6 +188,7 @@ non-sealed class C extends A {} assertEquals("'non-sealed' modifier is not set in binding", Modifier.isNonSealed(aBinding.getModifiers()), true); } + //public sealed public void test003_c() throws CoreException { ASTParser astParser = ASTParser.newParser(getAST23()); Map options = new HashMap<>(); @@ -212,10 +213,222 @@ non-sealed class C extends A {} TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); assertEquals("Modifier is not present in AST", Modifier.isSealed(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isPublic(a.getModifiers()), true); assertEquals("permitted types are not present in AST", a.permittedTypes().size(), 2); ITypeBinding aBinding = a.resolveBinding(); assertEquals("'sealed' modifier is not set in binding", Modifier.isSealed(aBinding.getModifiers()), true); + assertEquals("'public' modifier is not set in binding", Modifier.isPublic(aBinding.getModifiers()), true); + } + + //abstract final + public void test003_d() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + abstract final class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isAbstract(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isFinal(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'abstract' modifier is not set in binding", Modifier.isAbstract(aBinding.getModifiers()), true); + assertEquals("'final' modifier is not set in binding", Modifier.isFinal(aBinding.getModifiers()), true); + } + + //abstract non-sealed + public void test003_e() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + abstract non-sealed class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isAbstract(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isNonSealed(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'abstract' modifier is not set in binding", Modifier.isAbstract(aBinding.getModifiers()), true); + assertEquals("'non-sealed' modifier is not set in binding", Modifier.isNonSealed(aBinding.getModifiers()), true); + } + + //public final + public void test003_f() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + public final class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isPublic(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isFinal(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'public' modifier is not set in binding", Modifier.isPublic(aBinding.getModifiers()), true); + assertEquals("'final' modifier is not set in binding", Modifier.isFinal(aBinding.getModifiers()), true); + } + + //public non-sealed + public void test003_g() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + public non-sealed class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isPublic(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isNonSealed(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'public' modifier is not set in binding", Modifier.isPublic(aBinding.getModifiers()), true); + assertEquals("'final' modifier is not set in binding", Modifier.isNonSealed(aBinding.getModifiers()), true); + } + + //protected non-sealed + public void test003_h() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + protected non-sealed class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isProtected(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isNonSealed(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'public' modifier is not set in binding", Modifier.isProtected(aBinding.getModifiers()), true); + assertEquals("'final' modifier is not set in binding", Modifier.isNonSealed(aBinding.getModifiers()), true); + } + + //private non-sealed + public void test003_i() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + private non-sealed class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isPrivate(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isNonSealed(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'public' modifier is not set in binding", Modifier.isPrivate(aBinding.getModifiers()), true); + assertEquals("'final' modifier is not set in binding", Modifier.isNonSealed(aBinding.getModifiers()), true); + } + + //protected abstract + public void test003_j() throws CoreException { + ASTParser astParser = ASTParser.newParser(getAST23()); + Map options = new HashMap<>(); + options.put(JavaCore.COMPILER_COMPLIANCE, "23"); + options.put(JavaCore.COMPILER_SOURCE, "23"); + + astParser.setCompilerOptions(options); + astParser.setEnvironment(new String[] {}, new String[] {}, new String[] {}, true); + astParser.setUnitName("Example.java"); + astParser.setResolveBindings(true); + astParser.setBindingsRecovery(true); + + String source = """ + protected abstract class A {} + """; + astParser.setSource(source.toCharArray()); + + CompilationUnit compilationUnit = (CompilationUnit) astParser.createAST(null); + TypeDeclaration a = (TypeDeclaration) compilationUnit.types().get(0); + + assertEquals("Modifier is not present in AST", Modifier.isProtected(a.getModifiers()), true); + assertEquals("Modifier is not present in AST", Modifier.isAbstract(a.getModifiers()), true); + + ITypeBinding aBinding = a.resolveBinding(); + + assertEquals("'public' modifier is not set in binding", Modifier.isProtected(aBinding.getModifiers()), true); + assertEquals("'final' modifier is not set in binding", Modifier.isAbstract(aBinding.getModifiers()), true); } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java index 369c802eac9..33304fd0019 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java @@ -336,14 +336,14 @@ public String toString() { * Applicable only to types. * @since 3.24 */ - public static final int SEALED = 0x0200; + public static final int SEALED = 0x1000; /** * "non-sealed" modifier constant (bit mask). * Applicable only to types. * @since 3.24 */ - public static final int NON_SEALED = 0x1000; + public static final int NON_SEALED = 0x400; /** * "module" modifier constant (bit mask). @@ -537,6 +537,9 @@ public static boolean isDefault(int flags) { * @since 3.24 */ public static boolean isSealed(int flags) { + if(flags < -32768 || flags > 32767) { + return((flags >>> 16 ) & SEALED ) != 0; + } return (flags & SEALED) != 0; } @@ -550,6 +553,9 @@ public static boolean isSealed(int flags) { * @since 3.24 */ public static boolean isNonSealed(int flags) { + if(flags < -32768 || flags > 32767) { + return ((flags >>> 16 ) & NON_SEALED ) != 0; + } return (flags & NON_SEALED) != 0; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java index aa2030d518f..464c862e53c 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java @@ -588,13 +588,13 @@ public int getKind() { public int getModifiers() { if (isClass()) { ReferenceBinding referenceBinding = (ReferenceBinding) this.binding; - if (referenceBinding.isSealed() || referenceBinding.isNonSealed()) { - return referenceBinding.getAccessFlagsForSealedAndNonSealed(); - } final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS; if (referenceBinding.isAnonymousType()) { return accessFlags & ~Modifier.FINAL; } + if((referenceBinding.modifiers < -32768 || referenceBinding.modifiers > 32767) && (referenceBinding.isSealed() || referenceBinding.isNonSealed())) {//checks the modifiers has upper 16 bits + return referenceBinding.modifiers; + } return accessFlags; } else if (isAnnotation()) { ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;