1 /*
2  * Copyright (C) 2007-2010 Júlio 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 
22 package com.github.javaparser.resolution.declarations;
23 
24 import com.github.javaparser.resolution.types.ResolvedType;
25 
26 import java.util.Collections;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.Optional;
30 
31 /**
32  * This is a common interface for MethodDeclaration and ConstructorDeclaration.
33  *
34  * @author Federico Tomassetti
35  */
36 public interface ResolvedMethodLikeDeclaration extends ResolvedDeclaration,
37         ResolvedTypeParametrizable, HasAccessSpecifier {
38     /**
39      * The package name of the declaring type.
40      */
getPackageName()41     default String getPackageName() {
42         return declaringType().getPackageName();
43     }
44 
45     /**
46      * The class(es) wrapping the declaring type.
47      */
getClassName()48     default String getClassName() {
49         return declaringType().getClassName();
50     }
51 
52     /**
53      * The qualified name of the method composed by the qualfied name of the declaring type
54      * followed by a dot and the name of the method.
55      */
getQualifiedName()56     default String getQualifiedName() {
57         return declaringType().getQualifiedName() + "." + this.getName();
58     }
59 
60     /**
61      * The signature of the method.
62      */
getSignature()63     default String getSignature() {
64         StringBuilder sb = new StringBuilder();
65         sb.append(getName());
66         sb.append("(");
67         for (int i = 0; i < getNumberOfParams(); i++) {
68             if (i != 0) {
69                 sb.append(", ");
70             }
71             sb.append(getParam(i).describeType());
72         }
73         sb.append(")");
74         return sb.toString();
75     }
76 
77     /**
78      * The qualified signature of the method. It is composed by the qualified name of the declaring type
79      * followed by the signature of the method.
80      */
getQualifiedSignature()81     default String getQualifiedSignature() {
82         return declaringType().getId() + "." + this.getSignature();
83     }
84 
85     /**
86      * The type in which the method is declared.
87      */
declaringType()88     ResolvedReferenceTypeDeclaration declaringType();
89 
90     /**
91      * Number of params.
92      */
getNumberOfParams()93     int getNumberOfParams();
94 
95     /**
96      * Get the ParameterDeclaration at the corresponding position or throw IllegalArgumentException.
97      */
getParam(int i)98     ResolvedParameterDeclaration getParam(int i);
99 
100     /**
101      * Utility method to get the last ParameterDeclaration. It throws UnsupportedOperationException if the method
102      * has no parameters.
103      * The last parameter can be variadic and sometimes it needs to be handled in a special way.
104      */
getLastParam()105     default ResolvedParameterDeclaration getLastParam() {
106         if (getNumberOfParams() == 0) {
107             throw new UnsupportedOperationException("This method has no typeParametersValues, therefore it has no a last parameter");
108         }
109         return getParam(getNumberOfParams() - 1);
110     }
111 
112     /**
113      * Has the method or construcor a variadic parameter?
114      * Note that when a method has a variadic parameter it should have an array type.
115      */
hasVariadicParameter()116     default boolean hasVariadicParameter() {
117         if (getNumberOfParams() == 0) {
118             return false;
119         } else {
120             return getParam(getNumberOfParams() - 1).isVariadic();
121         }
122     }
123 
124     @Override
findTypeParameter(String name)125     default Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name) {
126         for (ResolvedTypeParameterDeclaration tp : this.getTypeParameters()) {
127             if (tp.getName().equals(name)) {
128                 return Optional.of(tp);
129             }
130         }
131         return declaringType().findTypeParameter(name);
132     }
133 
134     /**
135      * Number of exceptions listed in the throws clause.
136      */
getNumberOfSpecifiedExceptions()137     int getNumberOfSpecifiedExceptions();
138 
139     /**
140      * Type of the corresponding entry in the throws clause.
141      *
142      * @throws IllegalArgumentException if the index is negative or it is equal or greater than the value returned by
143      *                                  getNumberOfSpecifiedExceptions
144      * @throws UnsupportedOperationException for those types of methods of constructor that do not declare exceptions
145      */
getSpecifiedException(int index)146     ResolvedType getSpecifiedException(int index);
147 
getSpecifiedExceptions()148     default List<ResolvedType> getSpecifiedExceptions() {
149         if (getNumberOfSpecifiedExceptions() == 0) {
150             return Collections.emptyList();
151         } else {
152             List<ResolvedType> exceptions = new LinkedList<>();
153             for (int i=0;i<getNumberOfSpecifiedExceptions();i++) {
154                 exceptions.add(getSpecifiedException(i));
155             }
156             return exceptions;
157         }
158     }
159 }
160