1 /* 2 * Copyright (C) 2007-2010 Jlio Vilmar Gesser. 3 * Copyright (C) 2011, 2013-2016 The JavaParser Team. 4 * 5 * This file is part of JavaParser. 6 * 7 * JavaParser can be used either under the terms of 8 * a) the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * b) the terms of the Apache License 12 * 13 * You should have received a copy of both licenses in LICENCE.LGPL and 14 * LICENCE.APACHE. Please refer to those files for details. 15 * 16 * JavaParser is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 */ 21 package com.github.javaparser.ast.body; 22 23 import com.github.javaparser.TokenRange; 24 import com.github.javaparser.ast.*; 25 import com.github.javaparser.ast.expr.AnnotationExpr; 26 import com.github.javaparser.ast.expr.SimpleName; 27 import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc; 28 import com.github.javaparser.ast.nodeTypes.NodeWithMembers; 29 import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; 30 import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers; 31 import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier; 32 import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier; 33 import com.github.javaparser.ast.observer.ObservableProperty; 34 import com.github.javaparser.ast.visitor.CloneVisitor; 35 import com.github.javaparser.metamodel.JavaParserMetaModel; 36 import com.github.javaparser.metamodel.TypeDeclarationMetaModel; 37 import javax.annotation.Generated; 38 import java.util.EnumSet; 39 import java.util.List; 40 import java.util.function.Consumer; 41 import static com.github.javaparser.utils.Utils.assertNotNull; 42 import static java.util.stream.Collectors.toList; 43 import com.github.javaparser.ast.Node; 44 import java.util.Optional; 45 46 /** 47 * A base class for all types of type declarations. 48 * 49 * @author Julio Vilmar Gesser 50 */ 51 public abstract class TypeDeclaration<T extends TypeDeclaration<?>> extends BodyDeclaration<T> implements NodeWithSimpleName<T>, NodeWithJavadoc<T>, NodeWithMembers<T>, NodeWithAccessModifiers<T>, NodeWithStaticModifier<T>, NodeWithStrictfpModifier<T> { 52 53 private SimpleName name; 54 55 private EnumSet<Modifier> modifiers; 56 57 private NodeList<BodyDeclaration<?>> members; 58 59 public TypeDeclaration() { 60 this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new SimpleName(), new NodeList<>()); 61 } 62 63 public TypeDeclaration(EnumSet<Modifier> modifiers, String name) { 64 this(null, modifiers, new NodeList<>(), new SimpleName(name), new NodeList<>()); 65 } 66 67 @AllFieldsConstructor 68 public TypeDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<BodyDeclaration<?>> members) { 69 this(null, modifiers, annotations, name, members); 70 } 71 72 /** 73 * This constructor is used by the parser and is considered private. 74 */ 75 @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator") 76 public TypeDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<BodyDeclaration<?>> members) { 77 super(tokenRange, annotations); 78 setModifiers(modifiers); 79 setName(name); 80 setMembers(members); 81 customInitialization(); 82 } 83 84 /** 85 * Adds the given declaration to the specified type. 86 * 87 * @param decl member declaration 88 */ 89 public T addMember(BodyDeclaration<?> decl) { 90 NodeList<BodyDeclaration<?>> members = getMembers(); 91 members.add(decl); 92 return (T) this; 93 } 94 95 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 96 public NodeList<BodyDeclaration<?>> getMembers() { 97 return members; 98 } 99 100 /** 101 * Return the modifiers of this type declaration. 102 * 103 * @return modifiers 104 * @see Modifier 105 */ 106 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 107 public EnumSet<Modifier> getModifiers() { 108 return modifiers; 109 } 110 111 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 112 @SuppressWarnings("unchecked") 113 public T setMembers(final NodeList<BodyDeclaration<?>> members) { 114 assertNotNull(members); 115 if (members == this.members) { 116 return (T) this; 117 } 118 notifyPropertyChange(ObservableProperty.MEMBERS, this.members, members); 119 if (this.members != null) 120 this.members.setParentNode(null); 121 this.members = members; 122 setAsParentNodeOf(members); 123 return (T) this; 124 } 125 126 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 127 @SuppressWarnings("unchecked") 128 public T setModifiers(final EnumSet<Modifier> modifiers) { 129 assertNotNull(modifiers); 130 if (modifiers == this.modifiers) { 131 return (T) this; 132 } 133 notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers); 134 this.modifiers = modifiers; 135 return (T) this; 136 } 137 138 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 139 @SuppressWarnings("unchecked") 140 public T setName(final SimpleName name) { 141 assertNotNull(name); 142 if (name == this.name) { 143 return (T) this; 144 } 145 notifyPropertyChange(ObservableProperty.NAME, this.name, name); 146 if (this.name != null) 147 this.name.setParentNode(null); 148 this.name = name; 149 setAsParentNodeOf(name); 150 return (T) this; 151 } 152 153 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 154 public SimpleName getName() { 155 return name; 156 } 157 158 @Override 159 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") 160 public boolean remove(Node node) { 161 if (node == null) 162 return false; 163 for (int i = 0; i < members.size(); i++) { 164 if (members.get(i) == node) { 165 members.remove(i); 166 return true; 167 } 168 } 169 return super.remove(node); 170 } 171 172 /** 173 * @return is this type's parent a CompilationUnit? 174 */ 175 public boolean isTopLevelType() { 176 return getParentNode().map(p -> p instanceof CompilationUnit).orElse(false); 177 } 178 179 /** 180 * @return methods or constructors whose signatures match the passed signature. 181 */ 182 public List<CallableDeclaration<?>> getCallablesWithSignature(CallableDeclaration.Signature signature) { 183 return getMembers().stream().filter(m -> m instanceof CallableDeclaration).map(m -> ((CallableDeclaration<?>) m)).filter(m -> m.getSignature().equals(signature)).collect(toList()); 184 } 185 186 /** 187 * @return is this type's parent a TypeDeclaration? 188 * NOTE: many people are confused over terminology. Refer to https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html . 189 */ 190 public boolean isNestedType() { 191 return getParentNode().map(p -> p instanceof TypeDeclaration).orElse(false); 192 } 193 194 @Override 195 @Generated("com.github.javaparser.generator.core.node.CloneGenerator") 196 public TypeDeclaration<?> clone() { 197 return (TypeDeclaration<?>) accept(new CloneVisitor(), null); 198 } 199 200 @Override 201 @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator") 202 public TypeDeclarationMetaModel getMetaModel() { 203 return JavaParserMetaModel.typeDeclarationMetaModel; 204 } 205 206 @Override 207 @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator") 208 public boolean replace(Node node, Node replacementNode) { 209 if (node == null) 210 return false; 211 for (int i = 0; i < members.size(); i++) { 212 if (members.get(i) == node) { 213 members.set(i, (BodyDeclaration) replacementNode); 214 return true; 215 } 216 } 217 if (node == name) { 218 setName((SimpleName) replacementNode); 219 return true; 220 } 221 return super.replace(node, replacementNode); 222 } 223 224 @Override 225 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 226 public boolean isTypeDeclaration() { 227 return true; 228 } 229 230 @Override 231 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 232 public TypeDeclaration asTypeDeclaration() { 233 return this; 234 } 235 236 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 237 public void ifTypeDeclaration(Consumer<TypeDeclaration> action) { 238 action.accept(this); 239 } 240 241 @Override 242 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 243 public Optional<TypeDeclaration> toTypeDeclaration() { 244 return Optional.of(this); 245 } 246 } 247