2323
2424import static com .github .javaparser .resolution .Navigator .demandParentNode ;
2525
26+ import java .util .Optional ;
27+
2628import com .github .javaparser .ast .CompilationUnit ;
2729import com .github .javaparser .ast .Node ;
2830import com .github .javaparser .ast .body .*;
2931import com .github .javaparser .ast .expr .*;
32+ import com .github .javaparser .ast .stmt .CatchClause ;
3033import com .github .javaparser .ast .stmt .ExplicitConstructorInvocationStmt ;
3134import com .github .javaparser .ast .type .Type ;
3235import com .github .javaparser .ast .type .TypeParameter ;
3639import com .github .javaparser .resolution .UnsolvedSymbolException ;
3740import com .github .javaparser .resolution .declarations .*;
3841import com .github .javaparser .resolution .model .SymbolReference ;
42+ import com .github .javaparser .resolution .model .Value ;
3943import com .github .javaparser .resolution .types .ResolvedPrimitiveType ;
4044import com .github .javaparser .resolution .types .ResolvedType ;
4145import com .github .javaparser .symbolsolver .javaparsermodel .JavaParserFacade ;
46+ import com .github .javaparser .symbolsolver .javaparsermodel .JavaParserFactory ;
4247import com .github .javaparser .symbolsolver .javaparsermodel .declarations .*;
4348
4449/**
@@ -241,23 +246,51 @@ public <T> T resolveDeclaration(Node node, Class<T> resultClass) {
241246 throw new UnsolvedSymbolException ("We are unable to find the constructor declaration corresponding to " + node );
242247 }
243248 }
244- if (node instanceof Parameter ) {
245- if (ResolvedParameterDeclaration .class .equals (resultClass )) {
246- Parameter parameter = (Parameter ) node ;
247- CallableDeclaration callableDeclaration = node .findAncestor (CallableDeclaration .class ).get ();
248- ResolvedMethodLikeDeclaration resolvedMethodLikeDeclaration ;
249- if (callableDeclaration .isConstructorDeclaration ()) {
250- resolvedMethodLikeDeclaration = callableDeclaration .asConstructorDeclaration ().resolve ();
251- } else {
252- resolvedMethodLikeDeclaration = callableDeclaration .asMethodDeclaration ().resolve ();
253- }
254- for (int i = 0 ; i < resolvedMethodLikeDeclaration .getNumberOfParams (); i ++) {
255- if (resolvedMethodLikeDeclaration .getParam (i ).getName ().equals (parameter .getNameAsString ())) {
256- return resultClass .cast (resolvedMethodLikeDeclaration .getParam (i ));
257- }
258- }
259- }
260- }
249+ if (node instanceof Parameter ) {
250+ if (ResolvedParameterDeclaration .class .equals (resultClass )) {
251+ Parameter parameter = (Parameter ) node ;
252+ Optional <Node > parentNode = node .getParentNode ();
253+ if (!parentNode .isPresent ()) {
254+ throw new UnsolvedSymbolException (
255+ "We are unable to resolve the parameter declaration corresponding to " + node );
256+ }
257+ Node parent = (Node ) parentNode .get ();
258+ if (parent instanceof ConstructorDeclaration ) {
259+ Optional <ResolvedParameterDeclaration > resolvedParameterDeclaration = resolveParameterDeclaration (
260+ ((ConstructorDeclaration ) parent ).resolve (), parameter );
261+ return resolvedParameterDeclaration .map (rpd -> resultClass .cast (rpd ))
262+ .orElseThrow (() -> new UnsolvedSymbolException (
263+ "We are unable to resolve the parameter declaration corresponding to " + node ));
264+ } else if (parent instanceof MethodDeclaration ) {
265+ Optional <ResolvedParameterDeclaration > resolvedParameterDeclaration = resolveParameterDeclaration (
266+ ((MethodDeclaration ) parent ).resolve (), parameter );
267+ return resolvedParameterDeclaration .map (rpd -> resultClass .cast (rpd ))
268+ .orElseThrow (() -> new UnsolvedSymbolException (
269+ "We are unable to resolve the parameter declaration corresponding to " + node ));
270+ } else if (parent instanceof RecordDeclaration ) {
271+ Optional <ResolvedParameterDeclaration > resolvedParameterDeclaration = resolveParameterDeclaration (
272+ ((RecordDeclaration ) parent ).resolve (), parameter );
273+ return resolvedParameterDeclaration .map (rpd -> resultClass .cast (rpd ))
274+ .orElseThrow (() -> new UnsolvedSymbolException (
275+ "We are unable to resolve the parameter declaration corresponding to " + node ));
276+ } else if (parent instanceof LambdaExpr ) {
277+ Optional <ResolvedParameterDeclaration > resolvedParameterDeclaration = resolveParameterDeclaration (
278+ parameter );
279+ return resolvedParameterDeclaration .map (rpd -> resultClass .cast (rpd ))
280+ .orElseThrow (() -> new UnsolvedSymbolException (
281+ "We are unable to resolve the parameter declaration corresponding to " + node ));
282+ } else if (parent instanceof CatchClause ) {
283+ Optional <ResolvedParameterDeclaration > resolvedParameterDeclaration = resolveParameterDeclaration (
284+ parameter );
285+ return resolvedParameterDeclaration .map (rpd -> resultClass .cast (rpd ))
286+ .orElseThrow (() -> new UnsolvedSymbolException (
287+ "We are unable to resolve the parameter declaration corresponding to " + node ));
288+ } else {
289+ throw new UnsolvedSymbolException (
290+ "We are unable to resolve the parameter declaration corresponding to " + node );
291+ }
292+ }
293+ }
261294 if (node instanceof AnnotationExpr ) {
262295 SymbolReference <ResolvedAnnotationDeclaration > result = JavaParserFacade .get (typeSolver ).solve ((AnnotationExpr ) node );
263296 if (result .isSolved ()) {
@@ -281,7 +314,80 @@ public <T> T resolveDeclaration(Node node, Class<T> resultClass) {
281314 throw new UnsupportedOperationException ("Unable to find the declaration of type " + resultClass .getSimpleName ()
282315 + " from " + node .getClass ().getSimpleName ());
283316 }
317+
318+ /*
319+ * Resolves constructor or method parameter
320+ */
321+ private Optional <ResolvedParameterDeclaration > resolveParameterDeclaration (
322+ ResolvedMethodLikeDeclaration resolvedMethodLikeDeclaration , Parameter parameter ) {
323+ for (int i = 0 ; i < resolvedMethodLikeDeclaration .getNumberOfParams (); i ++) {
324+ if (resolvedMethodLikeDeclaration .getParam (i ).getName ().equals (parameter .getNameAsString ())) {
325+ return Optional .of (resolvedMethodLikeDeclaration .getParam (i ));
326+ }
327+ }
328+ return Optional .empty ();
329+ }
330+
331+ /*
332+ * Resolves record parameter
333+ */
334+ private Optional <ResolvedParameterDeclaration > resolveParameterDeclaration (
335+ ResolvedReferenceTypeDeclaration resolvedReferenceTypeDeclaration , Parameter parameter ) {
336+ ResolvedFieldDeclaration rfd = resolvedReferenceTypeDeclaration .getField (parameter .getNameAsString ());
337+ if (rfd == null ) return Optional .empty ();
338+ ResolvedParameterDeclaration resolvedParameterDeclaration = new ResolvedParameterDeclaration () {
339+
340+ @ Override
341+ public ResolvedType getType () {
342+ return rfd .getType ();
343+ }
344+
345+ @ Override
346+ public String getName () {
347+ return parameter .getNameAsString ();
348+ }
349+
350+ @ Override
351+ public boolean isVariadic () {
352+ return parameter .isVarArgs ();
353+ }
354+
355+ };
356+ return Optional .of (resolvedParameterDeclaration );
357+ }
358+
359+ /*
360+ * Resolves lambda expression parameters and catch clause parameters
361+ */
362+ private Optional <ResolvedParameterDeclaration > resolveParameterDeclaration (Parameter parameter ) {
363+ ResolvedParameterDeclaration resolvedParameterDeclaration = new ResolvedParameterDeclaration () {
364+
365+ @ Override
366+ public ResolvedType getType () {
367+ Node parentNode = parameter .getParentNode ().get ();
368+ if (parameter .getType ().isUnknownType () && parentNode instanceof LambdaExpr ) {
369+ Optional <Value > value = JavaParserFactory .getContext (parentNode , typeSolver )
370+ .solveSymbolAsValue (parameter .getNameAsString ());
371+ return value .map (v -> v .getType ()).orElseThrow (() -> new UnsolvedSymbolException (
372+ "We are unable to resolve the parameter declaration corresponding to " + parameter ));
373+ }
374+ return JavaParserFacade .get (typeSolver ).convertToUsage (parameter .getType ());
375+ }
376+
377+ @ Override
378+ public String getName () {
379+ return parameter .getNameAsString ();
380+ }
381+
382+ @ Override
383+ public boolean isVariadic () {
384+ return parameter .isVarArgs ();
385+ }
284386
387+ };
388+ return Optional .of (resolvedParameterDeclaration );
389+ }
390+
285391 @ Override
286392 public <T > T toResolvedType (Type javaparserType , Class <T > resultClass ) {
287393 ResolvedType resolvedType = JavaParserFacade .get (typeSolver ).convertToUsage (javaparserType );
0 commit comments