Home | History | Annotate | Download | only in expr
      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&lt;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