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.expr; 22 23 import com.github.javaparser.ast.AllFieldsConstructor; 24 import com.github.javaparser.ast.NodeList; 25 import com.github.javaparser.ast.body.BodyDeclaration; 26 import com.github.javaparser.ast.nodeTypes.NodeWithArguments; 27 import com.github.javaparser.ast.nodeTypes.NodeWithOptionalScope; 28 import com.github.javaparser.ast.nodeTypes.NodeWithType; 29 import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments; 30 import com.github.javaparser.ast.observer.ObservableProperty; 31 import com.github.javaparser.ast.type.ClassOrInterfaceType; 32 import com.github.javaparser.ast.type.Type; 33 import com.github.javaparser.ast.visitor.GenericVisitor; 34 import com.github.javaparser.ast.visitor.VoidVisitor; 35 import java.util.Optional; 36 import static com.github.javaparser.utils.Utils.assertNotNull; 37 import com.github.javaparser.ast.Node; 38 import com.github.javaparser.ast.visitor.CloneVisitor; 39 import com.github.javaparser.metamodel.ObjectCreationExprMetaModel; 40 import com.github.javaparser.metamodel.JavaParserMetaModel; 41 import javax.annotation.Generated; 42 import com.github.javaparser.TokenRange; 43 import com.github.javaparser.metamodel.OptionalProperty; 44 import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; 45 import java.util.function.Consumer; 46 47 /** 48 * A constructor call. 49 * <br/>In <code>new HashMap.Entry<String, Long>(15) {public String getKey() {return null;}};</code> 50 * HashMap.Entry is the type, String and Long are type arguments, 15 is an argument, and everything in { } 51 * is the anonymous class body. 52 * <p/>In <code>class B { class C { public void a() { new B().new C(); } } }</code> the scope is <code>new B()</code> 53 * of ObjectCreationExpr <code>new B().new C()</code> 54 * 55 * @author Julio Vilmar Gesser 56 */ 57 public final class ObjectCreationExpr extends Expression implements NodeWithTypeArguments<ObjectCreationExpr>, NodeWithType<ObjectCreationExpr, ClassOrInterfaceType>, NodeWithArguments<ObjectCreationExpr>, NodeWithOptionalScope<ObjectCreationExpr> { 58 59 @OptionalProperty 60 private Expression scope; 61 62 private ClassOrInterfaceType type; 63 64 @OptionalProperty 65 private NodeList<Type> typeArguments; 66 67 private NodeList<Expression> arguments; 68 69 @OptionalProperty 70 private NodeList<BodyDeclaration<?>> anonymousClassBody; 71 72 public ObjectCreationExpr() { 73 this(null, null, new ClassOrInterfaceType(), new NodeList<>(), new NodeList<>(), null); 74 } 75 76 /** 77 * Defines a call to a constructor. 78 * 79 * @param scope may be null 80 * @param type this is the class that the constructor is being called for. 81 * @param arguments Any arguments to pass to the constructor 82 */ 83 public ObjectCreationExpr(final Expression scope, final ClassOrInterfaceType type, final NodeList<Expression> arguments) { 84 this(null, scope, type, new NodeList<>(), arguments, null); 85 } 86 87 @AllFieldsConstructor 88 public ObjectCreationExpr(final Expression scope, final ClassOrInterfaceType type, final NodeList<Type> typeArguments, final NodeList<Expression> arguments, final NodeList<BodyDeclaration<?>> anonymousClassBody) { 89 this(null, scope, type, typeArguments, arguments, anonymousClassBody); 90 } 91 92 /** 93 * This constructor is used by the parser and is considered private. 94 */ 95 @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator") 96 public ObjectCreationExpr(TokenRange tokenRange, Expression scope, ClassOrInterfaceType type, NodeList<Type> typeArguments, NodeList<Expression> arguments, NodeList<BodyDeclaration<?>> anonymousClassBody) { 97 super(tokenRange); 98 setScope(scope); 99 setType(type); 100 setTypeArguments(typeArguments); 101 setArguments(arguments); 102 setAnonymousClassBody(anonymousClassBody); 103 customInitialization(); 104 } 105 106 @Override 107 @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") 108 public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) { 109 return v.visit(this, arg); 110 } 111 112 @Override 113 @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") 114 public <A> void accept(final VoidVisitor<A> v, final A arg) { 115 v.visit(this, arg); 116 } 117 118 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 119 public Optional<NodeList<BodyDeclaration<?>>> getAnonymousClassBody() { 120 return Optional.ofNullable(anonymousClassBody); 121 } 122 123 public void addAnonymousClassBody(BodyDeclaration<?> body) { 124 if (anonymousClassBody == null) 125 anonymousClassBody = new NodeList<>(); 126 anonymousClassBody.add(body); 127 } 128 129 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 130 public NodeList<Expression> getArguments() { 131 return arguments; 132 } 133 134 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 135 public Optional<Expression> getScope() { 136 return Optional.ofNullable(scope); 137 } 138 139 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 140 public ClassOrInterfaceType getType() { 141 return type; 142 } 143 144 /** 145 * Sets the anonymousClassBody<br> 146 * Null means no class body<br> 147 * Empty NodeList means new ClassName(){ } 148 * 149 * @param anonymousClassBody the anonymousClassBody, can be null or empty 150 * @return this, the ObjectCreationExpr 151 */ 152 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 153 public ObjectCreationExpr setAnonymousClassBody(final NodeList<BodyDeclaration<?>> anonymousClassBody) { 154 if (anonymousClassBody == this.anonymousClassBody) { 155 return (ObjectCreationExpr) this; 156 } 157 notifyPropertyChange(ObservableProperty.ANONYMOUS_CLASS_BODY, this.anonymousClassBody, anonymousClassBody); 158 if (this.anonymousClassBody != null) 159 this.anonymousClassBody.setParentNode(null); 160 this.anonymousClassBody = anonymousClassBody; 161 setAsParentNodeOf(anonymousClassBody); 162 return this; 163 } 164 165 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 166 public ObjectCreationExpr setArguments(final NodeList<Expression> arguments) { 167 assertNotNull(arguments); 168 if (arguments == this.arguments) { 169 return (ObjectCreationExpr) this; 170 } 171 notifyPropertyChange(ObservableProperty.ARGUMENTS, this.arguments, arguments); 172 if (this.arguments != null) 173 this.arguments.setParentNode(null); 174 this.arguments = arguments; 175 setAsParentNodeOf(arguments); 176 return this; 177 } 178 179 /** 180 * Sets the scope 181 * 182 * @param scope the scope, can be null 183 * @return this, the ObjectCreationExpr 184 */ 185 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 186 public ObjectCreationExpr setScope(final Expression scope) { 187 if (scope == this.scope) { 188 return (ObjectCreationExpr) this; 189 } 190 notifyPropertyChange(ObservableProperty.SCOPE, this.scope, scope); 191 if (this.scope != null) 192 this.scope.setParentNode(null); 193 this.scope = scope; 194 setAsParentNodeOf(scope); 195 return this; 196 } 197 198 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 199 public ObjectCreationExpr setType(final ClassOrInterfaceType type) { 200 assertNotNull(type); 201 if (type == this.type) { 202 return (ObjectCreationExpr) this; 203 } 204 notifyPropertyChange(ObservableProperty.TYPE, this.type, type); 205 if (this.type != null) 206 this.type.setParentNode(null); 207 this.type = type; 208 setAsParentNodeOf(type); 209 return this; 210 } 211 212 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 213 public Optional<NodeList<Type>> getTypeArguments() { 214 return Optional.ofNullable(typeArguments); 215 } 216 217 /** 218 * Sets the typeArguments 219 * 220 * @param typeArguments the typeArguments, can be null 221 * @return this, the ObjectCreationExpr 222 */ 223 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") 224 public ObjectCreationExpr setTypeArguments(final NodeList<Type> typeArguments) { 225 if (typeArguments == this.typeArguments) { 226 return (ObjectCreationExpr) this; 227 } 228 notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments); 229 if (this.typeArguments != null) 230 this.typeArguments.setParentNode(null); 231 this.typeArguments = typeArguments; 232 setAsParentNodeOf(typeArguments); 233 return this; 234 } 235 236 @Override 237 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") 238 public boolean remove(Node node) { 239 if (node == null) 240 return false; 241 if (anonymousClassBody != null) { 242 for (int i = 0; i < anonymousClassBody.size(); i++) { 243 if (anonymousClassBody.get(i) == node) { 244 anonymousClassBody.remove(i); 245 return true; 246 } 247 } 248 } 249 for (int i = 0; i < arguments.size(); i++) { 250 if (arguments.get(i) == node) { 251 arguments.remove(i); 252 return true; 253 } 254 } 255 if (scope != null) { 256 if (node == scope) { 257 removeScope(); 258 return true; 259 } 260 } 261 if (typeArguments != null) { 262 for (int i = 0; i < typeArguments.size(); i++) { 263 if (typeArguments.get(i) == node) { 264 typeArguments.remove(i); 265 return true; 266 } 267 } 268 } 269 return super.remove(node); 270 } 271 272 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") 273 public ObjectCreationExpr removeScope() { 274 return setScope((Expression) null); 275 } 276 277 @Override 278 @Generated("com.github.javaparser.generator.core.node.CloneGenerator") 279 public ObjectCreationExpr clone() { 280 return (ObjectCreationExpr) accept(new CloneVisitor(), null); 281 } 282 283 @Override 284 @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator") 285 public ObjectCreationExprMetaModel getMetaModel() { 286 return JavaParserMetaModel.objectCreationExprMetaModel; 287 } 288 289 @Override 290 @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator") 291 public boolean replace(Node node, Node replacementNode) { 292 if (node == null) 293 return false; 294 if (anonymousClassBody != null) { 295 for (int i = 0; i < anonymousClassBody.size(); i++) { 296 if (anonymousClassBody.get(i) == node) { 297 anonymousClassBody.set(i, (BodyDeclaration) replacementNode); 298 return true; 299 } 300 } 301 } 302 for (int i = 0; i < arguments.size(); i++) { 303 if (arguments.get(i) == node) { 304 arguments.set(i, (Expression) replacementNode); 305 return true; 306 } 307 } 308 if (scope != null) { 309 if (node == scope) { 310 setScope((Expression) replacementNode); 311 return true; 312 } 313 } 314 if (node == type) { 315 setType((ClassOrInterfaceType) replacementNode); 316 return true; 317 } 318 if (typeArguments != null) { 319 for (int i = 0; i < typeArguments.size(); i++) { 320 if (typeArguments.get(i) == node) { 321 typeArguments.set(i, (Type) replacementNode); 322 return true; 323 } 324 } 325 } 326 return super.replace(node, replacementNode); 327 } 328 329 @Override 330 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 331 public boolean isObjectCreationExpr() { 332 return true; 333 } 334 335 @Override 336 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 337 public ObjectCreationExpr asObjectCreationExpr() { 338 return this; 339 } 340 341 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 342 public void ifObjectCreationExpr(Consumer<ObjectCreationExpr> action) { 343 action.accept(this); 344 } 345 346 public ResolvedConstructorDeclaration resolveInvokedConstructor() { 347 return getSymbolResolver().resolveDeclaration(this, ResolvedConstructorDeclaration.class); 348 } 349 350 @Override 351 @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") 352 public Optional<ObjectCreationExpr> toObjectCreationExpr() { 353 return Optional.of(this); 354 } 355 } 356