Home | History | Annotate | Download | only in body
      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