JavaParser Source Viewer

Home|JavaParser/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
1/*
2 * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2020 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 */
21package com.github.javaparser.ast.nodeTypes;
22
23import com.github.javaparser.ast.Modifier;
24import com.github.javaparser.ast.Node;
25import com.github.javaparser.ast.NodeList;
26import com.github.javaparser.ast.body.*;
27import com.github.javaparser.ast.expr.Expression;
28import com.github.javaparser.ast.stmt.BlockStmt;
29import com.github.javaparser.ast.type.Type;
30import com.github.javaparser.ast.type.VoidType;
31
32import java.util.List;
33import java.util.Optional;
34
35import static com.github.javaparser.StaticJavaParser.parseType;
36import static com.github.javaparser.ast.Modifier.Keyword;
37import static com.github.javaparser.ast.Modifier.Keyword.*;
38import static com.github.javaparser.ast.Modifier.createModifierList;
39import static java.util.Collections.unmodifiableList;
40import static java.util.stream.Collectors.toList;
41
42/**
43 * A node having members.
44 * <p>
45 * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getMembers
46 * method.
47 */
48public interface NodeWithMembers<N extends Node> extends NodeWithSimpleName<N> {
49    /**
50     * @return all members inside the braces of this node,
51     * like fields, methods, nested types, etc.
52     */
53    NodeList<BodyDeclaration<?>> getMembers();
54
55    void tryAddImportToParentCompilationUnit(Class<?> clazz);
56
57    default BodyDeclaration<?> getMember(int i) {
58        return getMembers().get(i);
59    }
60
61    @SuppressWarnings("unchecked")
62    default N setMember(int iBodyDeclaration<?> member) {
63        getMembers().set(imember);
64        return (N) this;
65    }
66
67    @SuppressWarnings("unchecked")
68    default N addMember(BodyDeclaration<?> member) {
69        getMembers().add(member);
70        return (N) this;
71    }
72
73    N setMembers(NodeList<BodyDeclaration<?>> members);
74
75    /**
76     * Add a field to this and automatically add the import of the type if needed
77     *
78     * @param typeClass the type of the field
79     * @param name      the name of the field
80     * @param modifiers the modifiers like {@link Modifier.Keyword#PUBLIC}
81     * @return the {@link FieldDeclaration} created
82     */
83    default FieldDeclaration addField(Class<?> typeClassString nameModifier.Keyword... modifiers) {
84        tryAddImportToParentCompilationUnit(typeClass);
85        return addField(typeClass.getSimpleName(), namemodifiers);
86    }
87
88    /**
89     * Add a field to this.
90     *
91     * @param type      the type of the field
92     * @param name      the name of the field
93     * @param modifiers the modifiers like {@link Modifier.Keyword#PUBLIC}
94     * @return the {@link FieldDeclaration} created
95     */
96    default FieldDeclaration addField(String typeString nameModifier.Keyword... modifiers) {
97        return addField(parseType(type), namemodifiers);
98    }
99
100    /**
101     * Add a field to this.
102     *
103     * @param type      the type of the field
104     * @param name      the name of the field
105     * @param modifiers the modifiers like {@link Modifier.Keyword#PUBLIC}
106     * @return the {@link FieldDeclaration} created
107     */
108    default FieldDeclaration addField(Type typeString nameModifier.Keyword... modifiers) {
109        FieldDeclaration fieldDeclaration = new FieldDeclaration();
110        VariableDeclarator variable = new VariableDeclarator(typename);
111        fieldDeclaration.getVariables().add(variable);
112        fieldDeclaration.setModifiers(createModifierList(modifiers));
113        getMembers().add(fieldDeclaration);
114        return fieldDeclaration;
115    }
116
117    /**
118     * Add a field to this and automatically add the import of the type if needed
119     *
120     * @param typeClass   the type of the field
121     * @param name        the name of the field
122     * @param initializer the initializer of the field
123     * @param modifiers   the modifiers like {@link Modifier.Keyword#PUBLIC}
124     * @return the {@link FieldDeclaration} created
125     */
126    default FieldDeclaration addFieldWithInitializer(Class<?> typeClassString nameExpression initializerModifier.Keyword... modifiers) {
127        tryAddImportToParentCompilationUnit(typeClass);
128        return addFieldWithInitializer(typeClass.getSimpleName(), nameinitializermodifiers);
129    }
130
131    /**
132     * Add a field to this.
133     *
134     * @param type        the type of the field
135     * @param name        the name of the field
136     * @param initializer the initializer of the field
137     * @param modifiers   the modifiers like {@link Modifier.Keyword#PUBLIC}
138     * @return the {@link FieldDeclaration} created
139     */
140    default FieldDeclaration addFieldWithInitializer(String typeString nameExpression initializerModifier.Keyword... modifiers) {
141        return addFieldWithInitializer(parseType(type), nameinitializermodifiers);
142    }
143
144    /**
145     * Add a field to this.
146     *
147     * @param type        the type of the field
148     * @param name        the name of the field
149     * @param initializer the initializer of the field
150     * @param modifiers   the modifiers like {@link Modifier.Keyword#PUBLIC}
151     * @return the {@link FieldDeclaration} created
152     */
153    default FieldDeclaration addFieldWithInitializer(Type typeString nameExpression initializerModifier.Keyword... modifiers) {
154        FieldDeclaration declaration = addField(typenamemodifiers);
155        declaration.getVariables().iterator().next().setInitializer(initializer);
156        return declaration;
157    }
158
159    /**
160     * Add a private field to this.
161     *
162     * @param typeClass the type of the field
163     * @param name      the name of the field
164     * @return the {@link FieldDeclaration} created
165     */
166    default FieldDeclaration addPrivateField(Class<?> typeClassString name) {
167        return addField(typeClassnamePRIVATE);
168    }
169
170    /**
171     * Add a private field to this and automatically add the import of the type if
172     * needed.
173     *
174     * @param type the type of the field
175     * @param name the name of the field
176     * @return the {@link FieldDeclaration} created
177     */
178    default FieldDeclaration addPrivateField(String typeString name) {
179        return addField(typenamePRIVATE);
180    }
181
182    /**
183     * Add a private field to this.
184     *
185     * @param type the type of the field
186     * @param name the name of the field
187     * @return the {@link FieldDeclaration} created
188     */
189    default FieldDeclaration addPrivateField(Type typeString name) {
190        return addField(typenamePRIVATE);
191    }
192
193    /**
194     * Add a public field to this.
195     *
196     * @param typeClass the type of the field
197     * @param name      the name of the field
198     * @return the {@link FieldDeclaration} created
199     */
200    default FieldDeclaration addPublicField(Class<?> typeClassString name) {
201        return addField(typeClassnamePUBLIC);
202    }
203
204    /**
205     * Add a public field to this and automatically add the import of the type if
206     * needed.
207     *
208     * @param type the type of the field
209     * @param name the name of the field
210     * @return the {@link FieldDeclaration} created
211     */
212    default FieldDeclaration addPublicField(String typeString name) {
213        return addField(typenamePUBLIC);
214    }
215
216    /**
217     * Add a public field to this.
218     *
219     * @param type the type of the field
220     * @param name the name of the field
221     * @return the {@link FieldDeclaration} created
222     */
223    default FieldDeclaration addPublicField(Type typeString name) {
224        return addField(typenamePUBLIC);
225    }
226
227    /**
228     * Add a protected field to this.
229     *
230     * @param typeClass the type of the field
231     * @param name      the name of the field
232     * @return the {@link FieldDeclaration} created
233     */
234    default FieldDeclaration addProtectedField(Class<?> typeClassString name) {
235        return addField(typeClassnamePROTECTED);
236    }
237
238    /**
239     * Add a protected field to this and automatically add the import of the type
240     * if needed.
241     *
242     * @param type the type of the field
243     * @param name the name of the field
244     * @return the {@link FieldDeclaration} created
245     */
246    default FieldDeclaration addProtectedField(String typeString name) {
247        return addField(typenamePROTECTED);
248    }
249
250    /**
251     * Add a protected field to this.
252     *
253     * @param type the type of the field
254     * @param name the name of the field
255     * @return the {@link FieldDeclaration} created
256     */
257    default FieldDeclaration addProtectedField(Type typeString name) {
258        return addField(typenamePROTECTED);
259    }
260
261    /**
262     * Adds a methods with void return by default to this.
263     *
264     * @param methodName the method name
265     * @param modifiers  the modifiers like {@link Modifier.Keyword#PUBLIC}
266     * @return the {@link MethodDeclaration} created
267     */
268    default MethodDeclaration addMethod(String methodNameKeyword... modifiers) {
269        MethodDeclaration methodDeclaration = new MethodDeclaration();
270        methodDeclaration.setName(methodName);
271        methodDeclaration.setType(new VoidType());
272        methodDeclaration.setModifiers(createModifierList(modifiers));
273        getMembers().add(methodDeclaration);
274        return methodDeclaration;
275    }
276
277    /**
278     * Adds a constructor to this node with members.
279     *
280     * @param modifiers the modifiers like {@link Modifier.Keyword#PUBLIC}
281     * @return the created constructor
282     */
283    default ConstructorDeclaration addConstructor(Modifier.Keyword... modifiers) {
284        ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration();
285        constructorDeclaration.setModifiers(createModifierList(modifiers));
286        constructorDeclaration.setName(getName());
287        getMembers().add(constructorDeclaration);
288        return constructorDeclaration;
289    }
290
291    /**
292     * Add an initializer block ({@link InitializerDeclaration}) to this.
293     */
294    default BlockStmt addInitializer() {
295        BlockStmt block = new BlockStmt();
296        InitializerDeclaration initializerDeclaration = new InitializerDeclaration(falseblock);
297        getMembers().add(initializerDeclaration);
298        return block;
299    }
300
301    /**
302     * Add a static initializer block ({@link InitializerDeclaration}) to this.
303     */
304    default BlockStmt addStaticInitializer() {
305        BlockStmt block = new BlockStmt();
306        InitializerDeclaration initializerDeclaration = new InitializerDeclaration(trueblock);
307        getMembers().add(initializerDeclaration);
308        return block;
309    }
310
311    /**
312     * Try to find a {@link MethodDeclaration} by its name
313     *
314     * @param name the name of the method
315     * @return the methods found (multiple in case of overloading)
316     */
317    default List<MethodDeclarationgetMethodsByName(String name) {
318        return unmodifiableList(getMethods().stream()
319                .filter(m -> m.getNameAsString().equals(name))
320                .collect(toList()));
321    }
322
323    /**
324     * Find all methods in the members of this node.
325     *
326     * @return the methods found. This list is immutable.
327     */
328    default List<MethodDeclarationgetMethods() {
329        return unmodifiableList(getMembers().stream()
330                .filter(m -> m instanceof MethodDeclaration)
331                .map(m -> (MethodDeclarationm)
332                .collect(toList()));
333    }
334
335    /**
336     * Try to find a {@link MethodDeclaration} by its parameter types. The given parameter types must <i>literally</i>
337     * match the declared types of this node's parameters, so passing the string {@code "List"} to this method will find
338     * all methods that have exactly one parameter whose type is declared as {@code List}, but not methods with exactly
339     * one parameter whose type is declared as {@code java.util.List} or {@code java.awt.List}. Conversely, passing the
340     * string {@code "java.util.List"} to this method will find all methods that have exactly one parameter whose type
341     * is declared as {@code java.util.List}, but not if the parameter type is declared as {@code List}. Similarly,
342     * note that generics are matched as well: If there is a method that has a parameter declared as
343     * {@code List&lt;String&gt;}, then it will be considered as a match only if the given string is
344     * {@code "List&lt;String&gt;"}, but not if the given string is only {@code "List"}.
345     *
346     * @param paramTypes the types of parameters like {@code "Map&lt;Integer, String&gt;", "int"} to match
347     *                   {@code void foo(Map&lt;Integer,String&gt; myMap, int number)}
348     * @return the methods found
349     */
350    default List<MethodDeclarationgetMethodsByParameterTypes(String... paramTypes) {
351        return unmodifiableList(getMethods().stream()
352                .filter(m -> m.hasParametersOfType(paramTypes))
353                .collect(toList()));
354    }
355
356    /**
357     * Try to find {@link MethodDeclaration}s by their name and parameter types. Parameter types are matched exactly as
358     * in the case of {@link #getMethodsByParameterTypes(String...)}.
359     *
360     * @param paramTypes the types of parameters like {@code "Map&lt;Integer, String&gt;", "int"} to match
361     *                   {@code void foo(Map&lt;Integer,String&gt; myMap, int number)}
362     * @return the methods found
363     */
364    default List<MethodDeclarationgetMethodsBySignature(String nameString... paramTypes) {
365        return unmodifiableList(getMethodsByName(name).stream()
366                .filter(m -> m.hasParametersOfType(paramTypes))
367                .collect(toList()));
368    }
369
370    /**
371     * Try to find a {@link MethodDeclaration} by its parameter types. Note that this is a match in SimpleName, so
372     * {@code java.awt.List} and {@code java.util.List} are identical to this algorithm. In addition, note that it is
373     * the erasure of each type which is considered, so passing {@code List.class} to this method will return all
374     * methods that have exactly one parameter whose type is named {@code List}, regardless of whether the parameter
375     * type is declared without generics as {@code List}, or with generics as {@code List&lt;String&gt;}, or
376     * {@code List&lt;Integer&gt;}, etc.
377     *
378     * @param paramTypes the types of parameters like {@code Map.class, int.class} to match
379     *                   {@code void foo(Map&lt;Integer,String&gt; myMap, int number)}
380     * @return the methods found
381     */
382    default List<MethodDeclarationgetMethodsByParameterTypes(Class<?>... paramTypes) {
383        return unmodifiableList(getMethods().stream()
384                .filter(m -> m.hasParametersOfType(paramTypes))
385                .collect(toList()));
386    }
387
388    /**
389     * Find all constructors in the members of this node.
390     *
391     * @return the constructors found. This list is immutable.
392     */
393    default List<ConstructorDeclarationgetConstructors() {
394        return unmodifiableList(getMembers().stream()
395                .filter(m -> m instanceof ConstructorDeclaration)
396                .map(m -> (ConstructorDeclarationm)
397                .collect(toList()));
398    }
399
400    /**
401     * Try to find a {@link ConstructorDeclaration} with no parameters.
402     *
403     * @return the constructor found, if any.
404     */
405    default Optional<ConstructorDeclarationgetDefaultConstructor() {
406        return getMembers().stream()
407                .filter(m -> m instanceof ConstructorDeclaration)
408                .map(m -> (ConstructorDeclarationm)
409                .filter(cd -> cd.getParameters().isEmpty())
410                .findFirst();
411    }
412
413    /**
414     * Try to find a {@link ConstructorDeclaration} by its parameter types. The given parameter types must
415     * <i>literally</i> match the declared types of the desired constructor, so passing the string {@code "List"} to
416     * this method will search for a constructor that has exactly one parameter whose type is declared as {@code List},
417     * but not for a constructor with exactly one parameter whose type is declared as {@code java.util.List} or
418     * {@code java.awt.List}. Conversely, passing the string {@code "java.util.List"} to this method will search for a
419     * constructor that has exactly one parameter whose type is declared as {@code java.util.List}, but not for a
420     * constructor whose type is declared as {@code List}. Similarly, note that generics are matched as well: If there
421     * is a constructor that has a parameter declared as {@code List&lt;String&gt;}, then it will be considered as a
422     * match only if the given string is {@code "List&lt;String&gt;"}, but not if the given string is only
423     * {@code "List"}.
424     *
425     * @param paramTypes the types of parameters like {@code "Map&lt;Integer, String&gt;", "int"} to match
426     *                   {@code Foo(Map&lt;Integer,String&gt; myMap, int number)}
427     * @return the constructor found, if any.
428     */
429    default Optional<ConstructorDeclarationgetConstructorByParameterTypes(String... paramTypes) {
430        return getConstructors().stream()
431                .filter(m -> m.hasParametersOfType(paramTypes))
432                .findFirst();
433    }
434
435    /**
436     * Try to find a {@link ConstructorDeclaration} by its parameter types.  Note that this is a match in SimpleName,
437     * so {@code java.awt.List} and {@code java.util.List} are identical to this algorithm. In addition, note that it is
438     * the erasure of each type which is considered, so passing {@code List.class} to this method will search for a
439     * constructor that has exactly one parameter whose type is named {@code List}, regardless of whether the parameter
440     * type is declared without generics as {@code List}, or with generics as {@code List&lt;String&gt;}, or
441     * {@code List&lt;Integer&gt;}, etc.
442     *
443     * @param paramTypes the types of parameters like {@code Map.class, int.class} to match
444     *                   {@code Foo(Map&lt;Integer,String&gt; myMap, int number)}
445     * @return the constructor found, if any.
446     */
447    default Optional<ConstructorDeclarationgetConstructorByParameterTypes(Class<?>... paramTypes) {
448        return getConstructors().stream()
449                .filter(m -> m.hasParametersOfType(paramTypes))
450                .findFirst();
451    }
452
453    /**
454     * Try to find a {@link FieldDeclaration} by its name
455     *
456     * @param name the name of the field
457     * @return null if not found, the FieldDeclaration otherwise
458     */
459    default Optional<FieldDeclarationgetFieldByName(String name) {
460        return getMembers().stream()
461                .filter(m -> m instanceof FieldDeclaration)
462                .map(f -> (FieldDeclarationf)
463                .filter(f -> f.getVariables().stream()
464                        .anyMatch(var -> var.getNameAsString().equals(name)))
465                .findFirst();
466    }
467
468    /**
469     * Find all fields in the members of this node.
470     *
471     * @return the fields found. This list is immutable.
472     */
473    default List<FieldDeclarationgetFields() {
474        return unmodifiableList(getMembers().stream()
475                .filter(m -> m instanceof FieldDeclaration)
476                .map(m -> (FieldDeclarationm)
477                .collect(toList()));
478    }
479
480    /**
481     * @return true if there are no members contained in this node.
482     */
483    default boolean isEmpty() {
484        return getMembers().isEmpty();
485    }
486}
487
MembersX
NodeWithMembers:tryAddImportToParentCompilationUnit
NodeWithMembers:addMethod
NodeWithMembers:getFieldByName
NodeWithMembers:getMethodsBySignature
NodeWithMembers:addFieldWithInitializer:Block:declaration
NodeWithMembers:addConstructor:Block:constructorDeclaration
NodeWithMembers:addInitializer
NodeWithMembers:addInitializer:Block:initializerDeclaration
NodeWithMembers:addStaticInitializer:Block:initializerDeclaration
NodeWithMembers:addPublicField
NodeWithMembers:addConstructor
NodeWithMembers:addMember
NodeWithMembers:addField:Block:variable
NodeWithMembers:getMethodsByName
NodeWithMembers:getFields
NodeWithMembers:addStaticInitializer:Block:block
NodeWithMembers:addField
NodeWithMembers:addMethod:Block:methodDeclaration
NodeWithMembers:getConstructorByParameterTypes
NodeWithMembers:getMembers
NodeWithMembers:getConstructors
NodeWithMembers:setMembers
NodeWithMembers:addProtectedField
NodeWithMembers:addPrivateField
NodeWithMembers:getDefaultConstructor
NodeWithMembers:getMethodsByParameterTypes
NodeWithMembers:addStaticInitializer
NodeWithMembers:getMethods
NodeWithMembers:getMember
NodeWithMembers:addInitializer:Block:block
NodeWithMembers:isEmpty
NodeWithMembers:setMember
NodeWithMembers:addFieldWithInitializer
NodeWithMembers:addField:Block:fieldDeclaration
Members
X