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 | */ |
21 | package com.github.javaparser.ast.body; |
22 | |
23 | import com.github.javaparser.ast.*; |
24 | import com.github.javaparser.ast.expr.AnnotationExpr; |
25 | import com.github.javaparser.ast.expr.SimpleName; |
26 | import com.github.javaparser.ast.nodeTypes.*; |
27 | import com.github.javaparser.ast.nodeTypes.modifiers.*; |
28 | import com.github.javaparser.ast.observer.ObservableProperty; |
29 | import com.github.javaparser.ast.stmt.BlockStmt; |
30 | import com.github.javaparser.ast.type.ClassOrInterfaceType; |
31 | import com.github.javaparser.ast.type.ReferenceType; |
32 | import com.github.javaparser.ast.type.Type; |
33 | import com.github.javaparser.ast.type.TypeParameter; |
34 | import com.github.javaparser.ast.visitor.GenericVisitor; |
35 | import com.github.javaparser.ast.visitor.VoidVisitor; |
36 | import java.util.Optional; |
37 | import static com.github.javaparser.utils.Utils.assertNotNull; |
38 | import com.github.javaparser.ast.visitor.CloneVisitor; |
39 | import com.github.javaparser.metamodel.MethodDeclarationMetaModel; |
40 | import com.github.javaparser.metamodel.JavaParserMetaModel; |
41 | import com.github.javaparser.TokenRange; |
42 | import com.github.javaparser.metamodel.OptionalProperty; |
43 | import com.github.javaparser.resolution.Resolvable; |
44 | import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; |
45 | import java.util.function.Consumer; |
46 | import com.github.javaparser.ast.Node; |
47 | import com.github.javaparser.ast.Generated; |
48 | |
49 | /** |
50 | * A method declaration. "public int abc() {return 1;}" in this example: {@code class X { public int abc() {return 1;} |
51 | * }} |
52 | * <p> |
53 | * <br>All annotations preceding the return type will be set on this object, not on the return type. |
54 | * JavaParser doesn't know if it they are applicable to the method or the type. |
55 | * |
56 | * @author Julio Vilmar Gesser |
57 | */ |
58 | public class MethodDeclaration extends CallableDeclaration<MethodDeclaration> implements NodeWithType<MethodDeclaration, Type>, NodeWithOptionalBlockStmt<MethodDeclaration>, NodeWithJavadoc<MethodDeclaration>, NodeWithDeclaration, NodeWithSimpleName<MethodDeclaration>, NodeWithParameters<MethodDeclaration>, NodeWithThrownExceptions<MethodDeclaration>, NodeWithTypeParameters<MethodDeclaration>, NodeWithAccessModifiers<MethodDeclaration>, NodeWithAbstractModifier<MethodDeclaration>, NodeWithStaticModifier<MethodDeclaration>, NodeWithFinalModifier<MethodDeclaration>, NodeWithStrictfpModifier<MethodDeclaration>, Resolvable<ResolvedMethodDeclaration> { |
59 | |
60 | private Type type; |
61 | |
62 | @OptionalProperty |
63 | private BlockStmt body; |
64 | |
65 | public MethodDeclaration() { |
66 | this(null, new NodeList<>(), new NodeList<>(), new NodeList<>(), new ClassOrInterfaceType(), new SimpleName(), new NodeList<>(), new NodeList<>(), new BlockStmt(), null); |
67 | } |
68 | |
69 | public MethodDeclaration(final NodeList<Modifier> modifiers, final Type type, final String name) { |
70 | this(null, modifiers, new NodeList<>(), new NodeList<>(), type, new SimpleName(name), new NodeList<>(), new NodeList<>(), new BlockStmt(), null); |
71 | } |
72 | |
73 | public MethodDeclaration(final NodeList<Modifier> modifiers, final String name, final Type type, final NodeList<Parameter> parameters) { |
74 | this(null, modifiers, new NodeList<>(), new NodeList<>(), type, new SimpleName(name), parameters, new NodeList<>(), new BlockStmt(), null); |
75 | } |
76 | |
77 | public MethodDeclaration(final NodeList<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final NodeList<TypeParameter> typeParameters, final Type type, final SimpleName name, final NodeList<Parameter> parameters, final NodeList<ReferenceType> thrownExceptions, final BlockStmt body) { |
78 | this(null, modifiers, annotations, typeParameters, type, name, parameters, thrownExceptions, body, null); |
79 | } |
80 | |
81 | @AllFieldsConstructor |
82 | public MethodDeclaration(final NodeList<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final NodeList<TypeParameter> typeParameters, final Type type, final SimpleName name, final NodeList<Parameter> parameters, final NodeList<ReferenceType> thrownExceptions, final BlockStmt body, ReceiverParameter receiverParameter) { |
83 | this(null, modifiers, annotations, typeParameters, type, name, parameters, thrownExceptions, body, receiverParameter); |
84 | } |
85 | |
86 | /** |
87 | * This constructor is used by the parser and is considered private. |
88 | */ |
89 | @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator") |
90 | public MethodDeclaration(TokenRange tokenRange, NodeList<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, Type type, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, BlockStmt body, ReceiverParameter receiverParameter) { |
91 | super(tokenRange, modifiers, annotations, typeParameters, name, parameters, thrownExceptions, receiverParameter); |
92 | setType(type); |
93 | setBody(body); |
94 | customInitialization(); |
95 | } |
96 | |
97 | @Override |
98 | @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") |
99 | public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) { |
100 | return v.visit(this, arg); |
101 | } |
102 | |
103 | @Override |
104 | @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") |
105 | public <A> void accept(final VoidVisitor<A> v, final A arg) { |
106 | v.visit(this, arg); |
107 | } |
108 | |
109 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
110 | public Optional<BlockStmt> getBody() { |
111 | return Optional.ofNullable(body); |
112 | } |
113 | |
114 | /** |
115 | * Sets the body |
116 | * |
117 | * @param body the body, can be null |
118 | * @return this, the MethodDeclaration |
119 | */ |
120 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
121 | public MethodDeclaration setBody(final BlockStmt body) { |
122 | if (body == this.body) { |
123 | return (MethodDeclaration) this; |
124 | } |
125 | notifyPropertyChange(ObservableProperty.BODY, this.body, body); |
126 | if (this.body != null) |
127 | this.body.setParentNode(null); |
128 | this.body = body; |
129 | setAsParentNodeOf(body); |
130 | return this; |
131 | } |
132 | |
133 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
134 | public Type getType() { |
135 | return type; |
136 | } |
137 | |
138 | @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") |
139 | public MethodDeclaration setType(final Type type) { |
140 | assertNotNull(type); |
141 | if (type == this.type) { |
142 | return (MethodDeclaration) this; |
143 | } |
144 | notifyPropertyChange(ObservableProperty.TYPE, this.type, type); |
145 | if (this.type != null) |
146 | this.type.setParentNode(null); |
147 | this.type = type; |
148 | setAsParentNodeOf(type); |
149 | return this; |
150 | } |
151 | |
152 | @Override |
153 | public MethodDeclaration setModifiers(final NodeList<Modifier> modifiers) { |
154 | return super.setModifiers(modifiers); |
155 | } |
156 | |
157 | @Override |
158 | public MethodDeclaration setName(final SimpleName name) { |
159 | return super.setName(name); |
160 | } |
161 | |
162 | @Override |
163 | public MethodDeclaration setParameters(final NodeList<Parameter> parameters) { |
164 | return super.setParameters(parameters); |
165 | } |
166 | |
167 | @Override |
168 | public MethodDeclaration setThrownExceptions(final NodeList<ReferenceType> thrownExceptions) { |
169 | return super.setThrownExceptions(thrownExceptions); |
170 | } |
171 | |
172 | @Override |
173 | public MethodDeclaration setTypeParameters(final NodeList<TypeParameter> typeParameters) { |
174 | return super.setTypeParameters(typeParameters); |
175 | } |
176 | |
177 | /** |
178 | * The declaration returned has this schema: |
179 | * <p> |
180 | * [accessSpecifier] [static] [abstract] [final] [native] |
181 | * [synchronized] returnType methodName ([paramType [paramName]]) |
182 | * [throws exceptionsList] |
183 | * |
184 | * @return method declaration as String |
185 | */ |
186 | @Override |
187 | public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName) { |
188 | StringBuilder sb = new StringBuilder(); |
189 | if (includingModifiers) { |
190 | AccessSpecifier accessSpecifier = getAccessSpecifier(); |
191 | sb.append(accessSpecifier.asString()).append(" "); |
192 | if (isStatic()) { |
193 | sb.append("static "); |
194 | } |
195 | if (isAbstract()) { |
196 | sb.append("abstract "); |
197 | } |
198 | if (isFinal()) { |
199 | sb.append("final "); |
200 | } |
201 | if (isNative()) { |
202 | sb.append("native "); |
203 | } |
204 | if (isSynchronized()) { |
205 | sb.append("synchronized "); |
206 | } |
207 | } |
208 | sb.append(getType().toString(prettyPrinterNoCommentsConfiguration)); |
209 | sb.append(" "); |
210 | sb.append(getName()); |
211 | sb.append("("); |
212 | boolean firstParam = true; |
213 | for (Parameter param : getParameters()) { |
214 | if (firstParam) { |
215 | firstParam = false; |
216 | } else { |
217 | sb.append(", "); |
218 | } |
219 | if (includingParameterName) { |
220 | sb.append(param.toString(prettyPrinterNoCommentsConfiguration)); |
221 | } else { |
222 | sb.append(param.getType().toString(prettyPrinterNoCommentsConfiguration)); |
223 | if (param.isVarArgs()) { |
224 | sb.append("..."); |
225 | } |
226 | } |
227 | } |
228 | sb.append(")"); |
229 | sb.append(appendThrowsIfRequested(includingThrows)); |
230 | return sb.toString(); |
231 | } |
232 | |
233 | public boolean isNative() { |
234 | return hasModifier(Modifier.Keyword.NATIVE); |
235 | } |
236 | |
237 | public boolean isSynchronized() { |
238 | return hasModifier(Modifier.Keyword.SYNCHRONIZED); |
239 | } |
240 | |
241 | public boolean isDefault() { |
242 | return hasModifier(Modifier.Keyword.DEFAULT); |
243 | } |
244 | |
245 | public MethodDeclaration setNative(boolean set) { |
246 | return setModifier(Modifier.Keyword.NATIVE, set); |
247 | } |
248 | |
249 | public MethodDeclaration setSynchronized(boolean set) { |
250 | return setModifier(Modifier.Keyword.SYNCHRONIZED, set); |
251 | } |
252 | |
253 | public MethodDeclaration setDefault(boolean set) { |
254 | return setModifier(Modifier.Keyword.DEFAULT, set); |
255 | } |
256 | |
257 | @Override |
258 | @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") |
259 | public boolean remove(Node node) { |
260 | if (node == null) |
261 | return false; |
262 | if (body != null) { |
263 | if (node == body) { |
264 | removeBody(); |
265 | return true; |
266 | } |
267 | } |
268 | return super.remove(node); |
269 | } |
270 | |
271 | @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") |
272 | public MethodDeclaration removeBody() { |
273 | return setBody((BlockStmt) null); |
274 | } |
275 | |
276 | @Override |
277 | @Generated("com.github.javaparser.generator.core.node.CloneGenerator") |
278 | public MethodDeclaration clone() { |
279 | return (MethodDeclaration) accept(new CloneVisitor(), null); |
280 | } |
281 | |
282 | @Override |
283 | @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator") |
284 | public MethodDeclarationMetaModel getMetaModel() { |
285 | return JavaParserMetaModel.methodDeclarationMetaModel; |
286 | } |
287 | |
288 | @Override |
289 | @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator") |
290 | public boolean replace(Node node, Node replacementNode) { |
291 | if (node == null) |
292 | return false; |
293 | if (body != null) { |
294 | if (node == body) { |
295 | setBody((BlockStmt) replacementNode); |
296 | return true; |
297 | } |
298 | } |
299 | if (node == type) { |
300 | setType((Type) replacementNode); |
301 | return true; |
302 | } |
303 | return super.replace(node, replacementNode); |
304 | } |
305 | |
306 | @Override |
307 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
308 | public boolean isMethodDeclaration() { |
309 | return true; |
310 | } |
311 | |
312 | @Override |
313 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
314 | public MethodDeclaration asMethodDeclaration() { |
315 | return this; |
316 | } |
317 | |
318 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
319 | public void ifMethodDeclaration(Consumer<MethodDeclaration> action) { |
320 | action.accept(this); |
321 | } |
322 | |
323 | @Override |
324 | public ResolvedMethodDeclaration resolve() { |
325 | return getSymbolResolver().resolveDeclaration(this, ResolvedMethodDeclaration.class); |
326 | } |
327 | |
328 | @Override |
329 | @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator") |
330 | public Optional<MethodDeclaration> toMethodDeclaration() { |
331 | return Optional.of(this); |
332 | } |
333 | } |
334 |
Members