From 70560b964a5d77867533b990ce74d4f17584045f Mon Sep 17 00:00:00 2001 From: David Thompson Date: Wed, 22 May 2024 17:27:11 -0400 Subject: [PATCH] Remove AbstractUnnamedTypeDeclaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rework hierarchy so ImplicitTypeDeclaration depends directly on AbstractTypeDeclaration - use subclass of `SimpleName` "EmptyName" as the `typeName` for `ImplicitTypeDeclaration`, since `SimpleName` cannot have the empty string as the type name - delete AbstractUnnamedTypeDeclaration - revert AbstractTypeDeclaration to pre-ImplicitTypeDeclaration - reincorporate Jörg's fix in AbstractTypeDeclaration that makes `typeName` volatile Signed-off-by: David Thompson --- .../jdt/core/dom/AbstractTypeDeclaration.java | 107 +++++++++++++++- .../dom/AbstractUnnamedTypeDeclaration.java | 121 ------------------ .../eclipse/jdt/core/dom/BindingResolver.java | 4 + .../eclipse/jdt/core/dom/CompilationUnit.java | 4 +- .../jdt/core/dom/DefaultBindingResolver.java | 18 +++ .../jdt/core/dom/ImplicitTypeDeclaration.java | 57 ++++++++- 6 files changed, 185 insertions(+), 126 deletions(-) delete mode 100644 org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractUnnamedTypeDeclaration.java diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java index a8ff65bca21..fa9f3787c8a 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.jdt.core.dom; +import java.util.List; + /** * Abstract subclass for type declaration, enum declaration, * and annotation type declaration AST node types. @@ -26,7 +28,7 @@ * @since 3.0 */ @SuppressWarnings("rawtypes") -public abstract class AbstractTypeDeclaration extends AbstractUnnamedTypeDeclaration { +public abstract class AbstractTypeDeclaration extends BodyDeclaration { /** * The type name; lazily initialized; defaults to a unspecified, @@ -35,6 +37,32 @@ public abstract class AbstractTypeDeclaration extends AbstractUnnamedTypeDeclara */ volatile SimpleName typeName; + /** + * The body declarations (element type: {@link BodyDeclaration}). + * Defaults to an empty list. + * @since 2.0 (originally declared on {@link TypeDeclaration}) + */ + ASTNode.NodeList bodyDeclarations; + + /** + * Returns structural property descriptor for the "bodyDeclarations" property + * of this node (element type: {@link BodyDeclaration}). + * + * @return the property descriptor + */ + abstract ChildListPropertyDescriptor internalBodyDeclarationsProperty(); + + /** + * Returns structural property descriptor for the "bodyDeclarations" property + * of this node (element type: {@link BodyDeclaration}). + * + * @return the property descriptor + * @since 3.1 + */ + public final ChildListPropertyDescriptor getBodyDeclarationsProperty() { + return internalBodyDeclarationsProperty(); + } + /** * Returns structural property descriptor for the "name" property * of this node (child type: {@link SimpleName}). @@ -54,6 +82,16 @@ public final ChildPropertyDescriptor getNameProperty() { return internalNameProperty(); } + /** + * Creates and returns a structural property descriptor for the + * "bodyDeclaration" property declared on the given concrete node type (element type: {@link BodyDeclaration}). + * + * @return the property descriptor + */ + static final ChildListPropertyDescriptor internalBodyDeclarationPropertyFactory(Class nodeClass) { + return new ChildListPropertyDescriptor(nodeClass, "bodyDeclarations", BodyDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ + } + /** * Creates and returns a structural property descriptor for the * "name" property declared on the given concrete node type (child type: {@link SimpleName}). @@ -77,6 +115,7 @@ static final ChildPropertyDescriptor internalNamePropertyFactory(Class nodeClass */ AbstractTypeDeclaration(AST ast) { super(ast); + this.bodyDeclarations = new ASTNode.NodeList(internalBodyDeclarationsProperty()); } /** @@ -122,6 +161,70 @@ public void setName(SimpleName typeName) { postReplaceChild(oldChild, typeName, p); } + /** + * Returns the live ordered list of body declarations of this type + * declaration. + * + * @return the live list of body declarations + * (element type: {@link BodyDeclaration}) + * @since 2.0 (originally declared on {@link TypeDeclaration}) + */ + public List bodyDeclarations() { + return this.bodyDeclarations; + } + + /** + * Returns whether this type declaration is a package member (that is, + * a top-level type). + *

+ * Note that this is a convenience method that simply checks whether + * this node's parent is a compilation unit node. + *

+ * + * @return true if this type declaration is a child of + * a compilation unit node, and false otherwise + * @since 2.0 (originally declared on {@link TypeDeclaration}) + */ + public boolean isPackageMemberTypeDeclaration() { + ASTNode parent = getParent(); + return (parent instanceof CompilationUnit); + } + + /** + * Returns whether this type declaration is a type member. + *

+ * Note that this is a convenience method that simply checks whether + * this node's parent is a type declaration node or an anonymous + * class declaration. + *

+ * + * @return true if this type declaration is a child of + * a type declaration node or an anonymous class declaration node, + * and false otherwise + * @since 2.0 (originally declared on {@link TypeDeclaration}) + */ + public boolean isMemberTypeDeclaration() { + ASTNode parent = getParent(); + return (parent instanceof AbstractTypeDeclaration) + || (parent instanceof AnonymousClassDeclaration); + } + + /** + * Returns whether this type declaration is a local type. + *

+ * Note that this is a convenience method that simply checks whether + * this node's parent is a type declaration statement node. + *

+ * + * @return true if this type declaration is a child of + * a type declaration statement node, and false otherwise + * @since 2.0 (originally declared on TypeDeclaration) + */ + public boolean isLocalTypeDeclaration() { + ASTNode parent = getParent(); + return (parent instanceof TypeDeclarationStatement); + } + /** * Resolves and returns the binding for the type declared in this type * declaration. @@ -149,7 +252,7 @@ public final ITypeBinding resolveBinding() { @Override int memSize() { - return super.memSize() + 4; + return super.memSize() + 2 * 4; } } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractUnnamedTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractUnnamedTypeDeclaration.java deleted file mode 100644 index c7250ea4872..00000000000 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractUnnamedTypeDeclaration.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.eclipse.jdt.core.dom; - -import java.util.List; - -/** - * @since 3.38 - */ -@SuppressWarnings("rawtypes") -public abstract class AbstractUnnamedTypeDeclaration extends BodyDeclaration { - - /** - * The body declarations (element type: {@link BodyDeclaration}). - * Defaults to an empty list. - * @since 2.0 (originally declared on {@link TypeDeclaration}) - */ - ASTNode.NodeList bodyDeclarations; - - /** - * Returns structural property descriptor for the "bodyDeclarations" property - * of this node (element type: {@link BodyDeclaration}). - * - * @return the property descriptor - */ - abstract ChildListPropertyDescriptor internalBodyDeclarationsProperty(); - - public AbstractUnnamedTypeDeclaration(AST ast) { - super(ast); - this.bodyDeclarations = new ASTNode.NodeList(internalBodyDeclarationsProperty()); - } - - /** - * Returns the live ordered list of body declarations of this type - * declaration. - * - * @return the live list of body declarations - * (element type: {@link BodyDeclaration}) - * @since 2.0 (originally declared on {@link TypeDeclaration}) - */ - public List bodyDeclarations() { - return this.bodyDeclarations; - } - - /** - * Creates and returns a structural property descriptor for the - * "bodyDeclaration" property declared on the given concrete node type (element type: {@link BodyDeclaration}). - * - * @return the property descriptor - */ - static final ChildListPropertyDescriptor internalBodyDeclarationPropertyFactory(Class nodeClass) { - return new ChildListPropertyDescriptor(nodeClass, "bodyDeclarations", BodyDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ - } - - /** - * Returns structural property descriptor for the "bodyDeclarations" property - * of this node (element type: {@link BodyDeclaration}). - * - * @return the property descriptor - * @since 3.1 (originally declared on {@link AbstractTypeDeclaration}) - */ - public final ChildListPropertyDescriptor getBodyDeclarationsProperty() { - return internalBodyDeclarationsProperty(); - } - - /** - * Returns whether this type declaration is a package member (that is, - * a top-level type). - *

- * Note that this is a convenience method that simply checks whether - * this node's parent is a compilation unit node. - *

- * - * @return true if this type declaration is a child of - * a compilation unit node, and false otherwise - * @since 2.0 (originally declared on {@link TypeDeclaration}) - */ - public boolean isPackageMemberTypeDeclaration() { - ASTNode parent = getParent(); - return (parent instanceof CompilationUnit); - } - - /** - * Returns whether this type declaration is a type member. - *

- * Note that this is a convenience method that simply checks whether - * this node's parent is a type declaration node or an anonymous - * class declaration. - *

- * - * @return true if this type declaration is a child of - * a type declaration node or an anonymous class declaration node, - * and false otherwise - * @since 2.0 (originally declared on {@link TypeDeclaration}) - */ - public boolean isMemberTypeDeclaration() { - ASTNode parent = getParent(); - return (parent instanceof AbstractTypeDeclaration) - || (parent instanceof AnonymousClassDeclaration); - } - - /** - * Returns whether this type declaration is a local type. - *

- * Note that this is a convenience method that simply checks whether - * this node's parent is a type declaration statement node. - *

- * - * @return true if this type declaration is a child of - * a type declaration statement node, and false otherwise - * @since 2.0 (originally declared on TypeDeclaration) - */ - public boolean isLocalTypeDeclaration() { - ASTNode parent = getParent(); - return (parent instanceof TypeDeclarationStatement); - } - - @Override - int memSize() { - return super.memSize() + 4; - } - -} diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java index 695828f3b4e..16800ba68e9 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java @@ -937,6 +937,10 @@ ITypeBinding resolveType(TypeDeclaration type) { return null; } + ITypeBinding resolveType(ImplicitTypeDeclaration type) { + return null; + } + /** * Resolves the given type parameter and returns the type binding for the * type parameter. diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java index 4a123819938..e0729f1dc2f 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java @@ -109,12 +109,12 @@ public class CompilationUnit extends ASTNode { private static final List PROPERTY_DESCRIPTORS_9_0; /** - * The "types" structural property of this node type (element type: {@link AbstractUnnamedTypeDeclaration}). + * The "types" structural property of this node type (element type: {@link AbstractTypeDeclaration}). * * @since 3.0 */ public static final ChildListPropertyDescriptor TYPES_PROPERTY = - new ChildListPropertyDescriptor(CompilationUnit.class, "types", AbstractUnnamedTypeDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ + new ChildListPropertyDescriptor(CompilationUnit.class, "types", AbstractTypeDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ static { List properyList = new ArrayList(4); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java index 41ef4a5658a..29ce757fd96 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java @@ -1879,6 +1879,24 @@ synchronized ITypeBinding resolveType(TypeDeclaration type) { return null; } + @Override + synchronized ITypeBinding resolveType(ImplicitTypeDeclaration type) { + final Object node = this.newAstToOldAst.get(type); + if (node instanceof org.eclipse.jdt.internal.compiler.ast.ImplicitTypeDeclaration implicitTypeDeclaration) { + ITypeBinding typeBinding = internalGetTypeBinding(implicitTypeDeclaration.binding, null); + if (typeBinding == null) { + return null; + } + this.bindingsToAstNodes.put(typeBinding, type); + String key = typeBinding.getKey(); + if (key != null) { + this.bindingTables.bindingKeysToBindings.put(key, typeBinding); + } + return typeBinding; + } + return null; + } + @Override synchronized ITypeBinding resolveTypeParameter(TypeParameter typeParameter) { final Object node = this.newAstToOldAst.get(typeParameter); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImplicitTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImplicitTypeDeclaration.java index e61bd88c76e..239986735d9 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImplicitTypeDeclaration.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImplicitTypeDeclaration.java @@ -6,7 +6,7 @@ /** * @since 3.38 */ -public class ImplicitTypeDeclaration extends AbstractUnnamedTypeDeclaration { +public class ImplicitTypeDeclaration extends AbstractTypeDeclaration { @Deprecated public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = @@ -21,6 +21,9 @@ public class ImplicitTypeDeclaration extends AbstractUnnamedTypeDeclaration { public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY = internalBodyDeclarationPropertyFactory(ImplicitTypeDeclaration.class); + public static final ChildPropertyDescriptor NAME_PROPERTY = + new ChildPropertyDescriptor(ImplicitTypeDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$ + /** * A list of property descriptors (element type: * {@link StructuralPropertyDescriptor}), @@ -40,6 +43,7 @@ public class ImplicitTypeDeclaration extends AbstractUnnamedTypeDeclaration { static { List propertyList = new ArrayList<>(8); createPropertyList(ImplicitTypeDeclaration.class, propertyList); + addProperty(NAME_PROPERTY, propertyList); addProperty(BODY_DECLARATIONS_PROPERTY, propertyList); addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS_PROPERTY, propertyList); @@ -47,6 +51,7 @@ public class ImplicitTypeDeclaration extends AbstractUnnamedTypeDeclaration { propertyList = new ArrayList<>(8); createPropertyList(ImplicitTypeDeclaration.class, propertyList); + addProperty(NAME_PROPERTY, propertyList); addProperty(BODY_DECLARATIONS_PROPERTY, propertyList); addProperty(JAVADOC_PROPERTY, propertyList); addProperty(MODIFIERS2_PROPERTY, propertyList); @@ -130,6 +135,13 @@ final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, bool setJavadoc((Javadoc) child); return null; } + } else if (property == NAME_PROPERTY) { + if (get) { + return getName(); + } else { + setName((SimpleName)child); + return null; + } } // allow default implementation to flag the error return super.internalGetSetChildProperty(property, get, child); @@ -161,4 +173,47 @@ final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean g return super.internalGetSetIntProperty(property, get, value); } + // from AbstractTypeDeclaration + + @Override + public SimpleName getName() { + if (this.typeName == null) { + synchronized (this) { + if (this.typeName == null) { + preLazyInit(); + this.typeName = new EmptyName(this.ast); + this.typeName.setSourceRange(this.getStartPosition(), 0); + postLazyInit(this.typeName, NAME_PROPERTY); + } + } + } + return this.typeName; + } + + @Override + public ChildPropertyDescriptor internalNameProperty() { + return NAME_PROPERTY; + } + + @Override + public ITypeBinding internalResolveBinding() { + return this.ast.getBindingResolver().resolveType(this); + } + + private final class EmptyName extends SimpleName { + private EmptyName(AST ast) { + super(ast); + } + + @Override + public String getIdentifier() { + return ""; //$NON-NLS-1$ + } + + @Override + public void setIdentifier(String newIdentifier) { + throw new IllegalArgumentException("Cannot change the name of an implicitly declared class; it must be the empty string"); //$NON-NLS-1$ + } + } + }