1
1
package com .ibm .cldk ;
2
2
3
- import java .io .IOException ;
4
- import java .nio .file .Path ;
5
- import java .nio .file .Paths ;
6
- import java .util .ArrayList ;
7
- import java .util .Collections ;
8
- import java .util .HashMap ;
9
- import java .util .HashSet ;
10
- import java .util .LinkedHashMap ;
11
- import java .util .List ;
12
- import java .util .Map ;
13
- import java .util .Objects ;
14
- import java .util .Optional ;
15
- import java .util .Set ;
16
- import java .util .stream .Collectors ;
17
- import java .util .stream .IntStream ;
18
-
19
3
import com .github .javaparser .*;
20
4
import com .github .javaparser .ast .*;
21
5
import com .github .javaparser .ast .body .*;
22
6
import com .github .javaparser .ast .comments .Comment ;
23
7
import com .github .javaparser .ast .comments .JavadocComment ;
24
8
import com .github .javaparser .ast .expr .*;
25
9
import com .github .javaparser .ast .nodeTypes .NodeWithJavadoc ;
26
- import com .github .javaparser .ast .stmt .*;
27
- import com .github .javaparser .printer .lexicalpreservation .LexicalPreservingPrinter ;
28
- import com .ibm .cldk .entities .*;
29
- import com .ibm .cldk .javaee .EntrypointsFinderFactory ;
30
- import org .apache .commons .lang3 .tuple .Pair ;
31
-
32
10
import com .github .javaparser .ast .nodeTypes .NodeWithName ;
11
+ import com .github .javaparser .ast .stmt .*;
33
12
import com .github .javaparser .ast .type .ReferenceType ;
34
13
import com .github .javaparser .ast .type .Type ;
14
+ import com .github .javaparser .printer .lexicalpreservation .LexicalPreservingPrinter ;
35
15
import com .github .javaparser .resolution .declarations .ResolvedMethodDeclaration ;
16
+ import com .github .javaparser .resolution .declarations .ResolvedMethodLikeDeclaration ;
36
17
import com .github .javaparser .resolution .types .ResolvedType ;
37
18
import com .github .javaparser .symbolsolver .JavaSymbolSolver ;
38
19
import com .github .javaparser .symbolsolver .resolution .typesolvers .CombinedTypeSolver ;
42
23
import com .github .javaparser .utils .SourceRoot ;
43
24
import com .google .common .collect .Table ;
44
25
import com .google .common .collect .Tables ;
26
+ import com .ibm .cldk .entities .*;
45
27
import com .ibm .cldk .javaee .CRUDFinderFactory ;
28
+ import com .ibm .cldk .javaee .EntrypointsFinderFactory ;
46
29
import com .ibm .cldk .javaee .utils .enums .CRUDOperationType ;
47
30
import com .ibm .cldk .javaee .utils .enums .CRUDQueryType ;
48
31
import com .ibm .cldk .utils .Log ;
32
+ import java .io .IOException ;
33
+ import java .nio .file .Path ;
34
+ import java .nio .file .Paths ;
35
+ import java .util .*;
36
+ import java .util .regex .Pattern ;
37
+ import java .util .stream .Collectors ;
38
+ import java .util .stream .IntStream ;
39
+ import org .apache .commons .lang3 .tuple .Pair ;
49
40
50
41
@ SuppressWarnings ({"unchecked" , "rawtypes" })
51
42
public class SymbolTable {
@@ -501,7 +492,7 @@ private static Pair<String, Callable> processCallableDeclaration(CallableDeclara
501
492
callableNode .setFilePath (filePath );
502
493
503
494
// add callable signature
504
- callableNode .setSignature (callableDecl . getSignature (). asString ( ));
495
+ callableNode .setSignature (getTypeErasureSignature ( callableDecl ));
505
496
506
497
// add comment associated with method/constructor
507
498
callableNode .setComments (
@@ -581,11 +572,62 @@ private static Pair<String, Callable> processCallableDeclaration(CallableDeclara
581
572
callableNode .setVariableDeclarations (getVariableDeclarations (body ));
582
573
callableNode .setCyclomaticComplexity (getCyclomaticComplexity (callableDecl ));
583
574
584
- String callableSignature = (callableDecl instanceof MethodDeclaration ) ? callableDecl .getSignature ().asString ()
585
- : callableDecl .getSignature ().asString ().replace (callableDecl .getSignature ().getName (), "<init>" );
575
+ String callableSignature = getTypeErasureSignature (callableDecl );
586
576
return Pair .of (callableSignature , callableNode );
587
577
}
588
578
579
+ /**
580
+ * Returns type erasure signature for the given callable. Returns regular signature if an
581
+ * error occurs in getting erased types.
582
+ *
583
+ * @param callableDecl: Callable to compute type erasure signature for
584
+ * @return String representing type erasure or regular signature
585
+ */
586
+ private static String getTypeErasureSignature (CallableDeclaration callableDecl ) {
587
+ try {
588
+ StringBuilder signature = new StringBuilder (
589
+ (callableDecl instanceof MethodDeclaration ) ? callableDecl .getNameAsString () : "<init>"
590
+ );
591
+ List <String > erasureParameterTypes = new ArrayList <>();
592
+ for (Object param : callableDecl .getParameters ()) {
593
+ Parameter parameter = (Parameter ) param ;
594
+ ResolvedType resolvedType = parameter .getType ().resolve ();
595
+ if (parameter .isVarArgs ()) {
596
+ erasureParameterTypes .add (resolvedType .describe () + "[]" );
597
+ } else {
598
+ erasureParameterTypes .add (resolvedType .erasure ().describe ());
599
+ }
600
+ }
601
+ signature .append ("(" );
602
+ signature .append (String .join (", " , erasureParameterTypes ));
603
+ signature .append (")" );
604
+ return signature .toString ();
605
+ } catch (Throwable e ) {
606
+ Log .warn ("Could not compute type erasure signature for " +callableDecl .getSignature ().asString ()+
607
+ "; computing regular signature" );
608
+ return callableDecl .getSignature ().asString ();
609
+ }
610
+ }
611
+
612
+ /**
613
+ * Returns type erasure signature for the given method or constructor declaration
614
+ * resolved for a call site.
615
+ *
616
+ * @param methodDecl: Resolved method/constructor to compute type erasure signature for
617
+ * @return String representing type erasure signature
618
+ */
619
+ private static String getTypeErasureSignature (ResolvedMethodLikeDeclaration methodDecl ) {
620
+ StringBuilder signature = new StringBuilder (methodDecl .getName ());
621
+ List <String > erasureParameterTypes = new ArrayList <>();
622
+ for (int i = 0 ; i < methodDecl .getNumberOfParams (); i ++) {
623
+ erasureParameterTypes .add (methodDecl .getParam (i ).getType ().erasure ().describe ());
624
+ }
625
+ signature .append ("(" );
626
+ signature .append (String .join (", " , erasureParameterTypes ));
627
+ signature .append (")" );
628
+ return signature .toString ();
629
+ }
630
+
589
631
private static boolean isEntryPointMethod (CallableDeclaration callableDecl ) {
590
632
return EntrypointsFinderFactory .getEntrypointFinders ()
591
633
.anyMatch (finder -> finder .isEntrypointMethod (callableDecl ));
@@ -835,8 +877,8 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
835
877
// resolve callee and get signature
836
878
String calleeSignature = "" ;
837
879
try {
838
- calleeSignature = methodCallExpr .resolve (). getSignature ( );
839
- } catch (RuntimeException exception ) {
880
+ calleeSignature = getTypeErasureSignature ( methodCallExpr .resolve ());
881
+ } catch (Throwable exception ) {
840
882
Log .debug ("Could not resolve method call: " + methodCallExpr + ": " + exception .getMessage ());
841
883
}
842
884
@@ -845,12 +887,12 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
845
887
try {
846
888
ResolvedMethodDeclaration resolvedMethodDeclaration = methodCallExpr .resolve ();
847
889
accessSpecifier = resolvedMethodDeclaration .accessSpecifier ();
848
- } catch (RuntimeException exception ) {
890
+ } catch (Throwable exception ) {
849
891
Log .debug ("Could not resolve access specifier for method call: " + methodCallExpr + ": "
850
892
+ exception .getMessage ());
851
893
}
852
894
// resolve arguments of the method call to types
853
- List <String > arguments = methodCallExpr .getArguments ().stream ().map (SymbolTable ::resolveExpression )
895
+ List <String > argumentTypes = methodCallExpr .getArguments ().stream ().map (SymbolTable ::resolveExpression )
854
896
.collect (Collectors .toList ());
855
897
// Get argument string from the callsite
856
898
List <String > listOfArgumentStrings = methodCallExpr .getArguments ().stream ().map (Expression ::toString )
@@ -886,7 +928,7 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
886
928
887
929
888
930
callSites .add (createCallSite (methodCallExpr , methodCallExpr .getNameAsString (), receiverName , declaringType ,
889
- arguments , returnType , calleeSignature , isStaticCall , false , crudOperation , crudQuery ,
931
+ argumentTypes , listOfArgumentStrings , returnType , calleeSignature , isStaticCall , false , crudOperation , crudQuery ,
890
932
accessSpecifier ));
891
933
}
892
934
@@ -895,14 +937,18 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
895
937
String instantiatedType = resolveType (objectCreationExpr .getType ());
896
938
897
939
// resolve arguments of the constructor call to types
898
- List <String > arguments = objectCreationExpr .getArguments ().stream ().map (SymbolTable ::resolveExpression )
940
+ List <String > argumentTypes = objectCreationExpr .getArguments ().stream ().map (SymbolTable ::resolveExpression )
941
+ .collect (Collectors .toList ());
942
+
943
+ // get argument expressions for constructor call
944
+ List <String > argumentExpressions = objectCreationExpr .getArguments ().stream ().map (Expression ::toString )
899
945
.collect (Collectors .toList ());
900
946
901
947
// resolve callee and get signature
902
948
String calleeSignature = "" ;
903
949
try {
904
- calleeSignature = objectCreationExpr .resolve (). getSignature ( );
905
- } catch (RuntimeException exception ) {
950
+ calleeSignature = getTypeErasureSignature ( objectCreationExpr .resolve ());
951
+ } catch (Throwable exception ) {
906
952
Log .debug ("Could not resolve constructor call: " + objectCreationExpr + ": " + exception .getMessage ());
907
953
}
908
954
@@ -911,7 +957,7 @@ private static List<CallSite> getCallSites(Optional<BlockStmt> callableBody) {
911
957
.add (createCallSite (objectCreationExpr , "<init>" ,
912
958
objectCreationExpr .getScope ().isPresent () ? objectCreationExpr .getScope ().get ().toString ()
913
959
: "" ,
914
- instantiatedType , arguments , instantiatedType , calleeSignature , false , true , null , null ,
960
+ instantiatedType , argumentTypes , argumentExpressions , instantiatedType , calleeSignature , false , true , null , null ,
915
961
AccessSpecifier .NONE ));
916
962
}
917
963
@@ -962,17 +1008,24 @@ private static Optional<CRUDOperationType> findCRUDOperation(String declaringTyp
962
1008
* @param calleeName
963
1009
* @param receiverExpr
964
1010
* @param receiverType
965
- * @param arguments
1011
+ * @param argumentTypes
1012
+ * @param argumentExpr
1013
+ * @param returnType
1014
+ * @param calleeSignature
966
1015
* @param isStaticCall
967
1016
* @param isConstructorCall
1017
+ * @param crudOperation,
1018
+ * @param crudQuery,
1019
+ * @param accessSpecifier
968
1020
* @return
969
1021
*/
970
1022
private static CallSite createCallSite (
971
1023
Expression callExpr ,
972
1024
String calleeName ,
973
1025
String receiverExpr ,
974
1026
String receiverType ,
975
- List <String > arguments ,
1027
+ List <String > argumentTypes ,
1028
+ List <String > argumentExpr ,
976
1029
String returnType ,
977
1030
String calleeSignature ,
978
1031
boolean isStaticCall ,
@@ -998,7 +1051,8 @@ private static CallSite createCallSite(
998
1051
callSite .setMethodName (calleeName );
999
1052
callSite .setReceiverExpr (receiverExpr );
1000
1053
callSite .setReceiverType (receiverType );
1001
- callSite .setArgumentTypes (arguments );
1054
+ callSite .setArgumentTypes (argumentTypes );
1055
+ callSite .setArgumentExpr (argumentExpr );
1002
1056
callSite .setReturnType (returnType );
1003
1057
callSite .setCalleeSignature (calleeSignature );
1004
1058
callSite .setStaticCall (isStaticCall );
@@ -1039,7 +1093,7 @@ private static String resolveExpression(Expression expression) {
1039
1093
if (resolvedType .isReferenceType () || resolvedType .isUnionType ()) {
1040
1094
return resolvedType .describe ();
1041
1095
}
1042
- } catch (RuntimeException exception ) {
1096
+ } catch (Throwable exception ) {
1043
1097
Log .debug ("Could not resolve expression: " + expression + ": " + exception .getMessage ());
1044
1098
unresolvedExpressions .add (expression .toString ());
1045
1099
}
@@ -1060,7 +1114,7 @@ private static String resolveType(Type type) {
1060
1114
if (!unresolvedTypes .contains (type .asString ())) {
1061
1115
try {
1062
1116
return type .resolve ().describe ();
1063
- } catch (RuntimeException e ) {
1117
+ } catch (Throwable e ) {
1064
1118
Log .warn ("Could not resolve type: " + type .asString () + ": " + e .getMessage ());
1065
1119
unresolvedTypes .add (type .asString ());
1066
1120
}
@@ -1079,6 +1133,20 @@ private static String resolveType(Type type) {
1079
1133
* project
1080
1134
* @throws IOException
1081
1135
*/
1136
+ private static final String [] EXCLUDED_SOURCE_ROOTS = {
1137
+ Paths .get ("src" , "test" , "resources" ).toString (),
1138
+ Paths .get ("src" , "it" , "resources" ).toString (),
1139
+ Paths .get ("src" , "xdocs-examples" ).toString ()
1140
+ };
1141
+ private static boolean excludeSourceRoot (Path sourceRoot ) {
1142
+ for (String excludedSrcRoot : EXCLUDED_SOURCE_ROOTS ) {
1143
+ if (Pattern .compile (excludedSrcRoot ).matcher (sourceRoot .toString ()).find ()) {
1144
+ return true ;
1145
+ }
1146
+ }
1147
+ return false ;
1148
+ }
1149
+
1082
1150
public static Pair <Map <String , JavaCompilationUnit >, Map <String , List <Problem >>> extractAll (Path projectRootPath )
1083
1151
throws IOException {
1084
1152
SymbolSolverCollectionStrategy symbolSolverCollectionStrategy = new SymbolSolverCollectionStrategy ();
@@ -1088,6 +1156,9 @@ public static Pair<Map<String, JavaCompilationUnit>, Map<String, List<Problem>>>
1088
1156
Map <String , JavaCompilationUnit > symbolTable = new LinkedHashMap <>();
1089
1157
Map <String , List <Problem >> parseProblems = new HashMap <>();
1090
1158
for (SourceRoot sourceRoot : projectRoot .getSourceRoots ()) {
1159
+ if (excludeSourceRoot (sourceRoot .getRoot ())) {
1160
+ continue ;
1161
+ }
1091
1162
for (ParseResult <CompilationUnit > parseResult : sourceRoot .tryToParse ()) {
1092
1163
if (parseResult .isSuccessful ()) {
1093
1164
CompilationUnit compilationUnit = LexicalPreservingPrinter .setup (parseResult .getResult ().get ());
0 commit comments