33
33
import com .ibm .cldk .entities .*;
34
34
import com .ibm .cldk .utils .Log ;
35
35
import org .apache .commons .lang3 .tuple .Pair ;
36
+ import org .checkerframework .checker .units .qual .C ;
36
37
37
38
import java .io .IOException ;
38
39
import java .nio .file .Path ;
@@ -110,8 +111,7 @@ private static JavaCompilationUnit processCompilationUnit(CompilationUnit parseR
110
111
cUnit .setTypeDeclarations (parseResult .findAll (TypeDeclaration .class ).stream ().filter (typeDecl -> typeDecl .getFullyQualifiedName ().isPresent ()).map (typeDecl -> {
111
112
// get type name and initialize the type object
112
113
String typeName = typeDecl .getFullyQualifiedName ().get ().toString ();
113
- com .ibm .cldk .entities .Type typeNode = new com .ibm .cldk .entities .Type ();
114
-
114
+ com .ibm .cldk .entities .Type typeNode = new com .ibm .cldk .entities .Type ();;
115
115
if (typeDecl instanceof ClassOrInterfaceDeclaration ) {
116
116
ClassOrInterfaceDeclaration classDecl = (ClassOrInterfaceDeclaration ) typeDecl ;
117
117
@@ -146,8 +146,26 @@ private static JavaCompilationUnit processCompilationUnit(CompilationUnit parseR
146
146
147
147
// Add enum constants
148
148
typeNode .setEnumConstants (enumDecl .getEntries ().stream ().map (SymbolTable ::processEnumConstantDeclaration ).collect (Collectors .toList ()));
149
+ }
150
+ else if (typeDecl instanceof RecordDeclaration ) {
151
+ RecordDeclaration recordDecl = (RecordDeclaration ) typeDecl ;
149
152
150
- } else {
153
+ // Set that this is a record declaration
154
+ typeNode .setRecordDeclaration (typeDecl .isRecordDeclaration ());
155
+
156
+ // Add interfaces implemented by record
157
+ typeNode .setImplementsList (recordDecl .getImplementedTypes ().stream ().map (SymbolTable ::resolveType ).collect (Collectors .toList ()));
158
+
159
+ // Add record modifiers
160
+ typeNode .setModifiers (recordDecl .getModifiers ().stream ().map (m -> m .toString ().strip ()).collect (Collectors .toList ()));
161
+
162
+ // Add record annotations
163
+ typeNode .setAnnotations (recordDecl .getAnnotations ().stream ().map (a -> a .toString ().strip ()).collect (Collectors .toList ()));
164
+
165
+ // Add record components
166
+ typeNode .setRecordComponents (processRecordComponents (recordDecl ));
167
+ }
168
+ else {
151
169
// TODO: handle AnnotationDeclaration, RecordDeclaration
152
170
// set the common type attributes only
153
171
Log .warn ("Found unsupported type declaration: " + typeDecl .toString ());
@@ -162,7 +180,6 @@ private static JavaCompilationUnit processCompilationUnit(CompilationUnit parseR
162
180
typeNode .setClassOrInterfaceDeclaration (typeDecl .isClassOrInterfaceDeclaration ());
163
181
typeNode .setEnumDeclaration (typeDecl .isEnumDeclaration ());
164
182
typeNode .setAnnotationDeclaration (typeDecl .isAnnotationDeclaration ());
165
- typeNode .setRecordDeclaration (typeDecl .isRecordDeclaration ());
166
183
167
184
// Add class comment
168
185
typeNode .setComment (typeDecl .getComment ().isPresent () ? typeDecl .getComment ().get ().asString () : "" );
@@ -196,6 +213,40 @@ private static JavaCompilationUnit processCompilationUnit(CompilationUnit parseR
196
213
return cUnit ;
197
214
}
198
215
216
+
217
+ private static List <RecordComponent > processRecordComponents (RecordDeclaration recordDecl ) {
218
+ return recordDecl .getParameters ().stream ().map (
219
+ parameter -> {
220
+ RecordComponent recordComponent = new RecordComponent ();
221
+ recordComponent .setName (parameter .getNameAsString ());
222
+ recordComponent .setType (resolveType (parameter .getType ()));
223
+ recordComponent .setAnnotations (parameter .getAnnotations ().stream ().map (a -> a .toString ().strip ()).collect (Collectors .toList ()));
224
+ recordComponent .setModifiers (parameter .getModifiers ().stream ().map (a -> a .toString ().strip ()).collect (Collectors .toList ()));
225
+ recordComponent .setVarArgs (parameter .isVarArgs ());
226
+ recordComponent .setDefaultValue (mapRecordConstructorDefaults (recordDecl ).getOrDefault (parameter .getNameAsString (), null ));
227
+ return recordComponent ;
228
+ }
229
+ ).collect (Collectors .toList ());
230
+ }
231
+
232
+ private static Map <String , Object > mapRecordConstructorDefaults (RecordDeclaration recordDecl ) {
233
+
234
+ return recordDecl .getCompactConstructors ().stream ()
235
+ .flatMap (constructor -> constructor .findAll (AssignExpr .class ).stream ()) // Flatten all assignments
236
+ .filter (assignExpr -> assignExpr .getTarget ().isNameExpr ()) // Ensure assignment is to a parameter
237
+ .collect (Collectors .toMap (
238
+ assignExpr -> assignExpr .getTarget ().asNameExpr ().getNameAsString (), // Key: Parameter Name
239
+ assignExpr -> Optional .ofNullable (assignExpr .getValue ()).map (valueExpr -> { // Value: Default Value
240
+ return valueExpr .isStringLiteralExpr () ? valueExpr .asStringLiteralExpr ().asString ()
241
+ : valueExpr .isBooleanLiteralExpr () ? valueExpr .asBooleanLiteralExpr ().getValue ()
242
+ : valueExpr .isCharLiteralExpr () ? valueExpr .asCharLiteralExpr ().getValue ()
243
+ : valueExpr .isDoubleLiteralExpr () ? valueExpr .asDoubleLiteralExpr ().asDouble ()
244
+ : valueExpr .isIntegerLiteralExpr () ? valueExpr .asIntegerLiteralExpr ().asNumber ()
245
+ : valueExpr .isLongLiteralExpr () ? valueExpr .asLongLiteralExpr ().asNumber ()
246
+ : valueExpr .isNullLiteralExpr () ? null
247
+ : valueExpr .toString ();}).orElse ("null" ))); // Default: store as a string
248
+ }
249
+
199
250
private static boolean isEntryPointClass (TypeDeclaration typeDecl ) {
200
251
return isSpringEntrypointClass (typeDecl ) || isStrutsEntryPointClass (typeDecl ) || isCamelEntryPointClass (typeDecl ) || isJaxRSEntrypointClass (typeDecl ) || isJakartaServletEntryPointClass (typeDecl );
201
252
@@ -904,7 +955,7 @@ private static String resolveType(Type type) {
904
955
public static Pair <Map <String , JavaCompilationUnit >, Map <String , List <Problem >>> extractAll (Path projectRootPath ) throws IOException {
905
956
SymbolSolverCollectionStrategy symbolSolverCollectionStrategy = new SymbolSolverCollectionStrategy ();
906
957
ProjectRoot projectRoot = symbolSolverCollectionStrategy .collect (projectRootPath );
907
- javaSymbolSolver = (JavaSymbolSolver ) symbolSolverCollectionStrategy .getParserConfiguration ().getSymbolResolver ().get ();
958
+ javaSymbolSolver = (JavaSymbolSolver ) symbolSolverCollectionStrategy .getParserConfiguration ().setLanguageLevel ( ParserConfiguration . LanguageLevel . JAVA_21 ). getSymbolResolver ().get ();
908
959
Map <String , JavaCompilationUnit > symbolTable = new LinkedHashMap <>();
909
960
Map <String , List <Problem >> parseProblems = new HashMap <>();
910
961
for (SourceRoot sourceRoot : projectRoot .getSourceRoots ()) {
@@ -927,7 +978,7 @@ public static Pair<Map<String, JavaCompilationUnit>, Map<String, List<Problem>>>
927
978
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver ();
928
979
combinedTypeSolver .add (new ReflectionTypeSolver ());
929
980
930
- ParserConfiguration parserConfiguration = new ParserConfiguration ();
981
+ ParserConfiguration parserConfiguration = new ParserConfiguration (). setLanguageLevel ( ParserConfiguration . LanguageLevel . JAVA_21 ) ;
931
982
parserConfiguration .setSymbolResolver (new JavaSymbolSolver (combinedTypeSolver ));
932
983
933
984
JavaParser javaParser = new JavaParser (parserConfiguration );
@@ -958,7 +1009,8 @@ public static Pair<Map<String, JavaCompilationUnit>, Map<String, List<Problem>>>
958
1009
SymbolSolverCollectionStrategy symbolSolverCollectionStrategy = new SymbolSolverCollectionStrategy ();
959
1010
ProjectRoot projectRoot = symbolSolverCollectionStrategy .collect (projectRootPath );
960
1011
javaSymbolSolver = (JavaSymbolSolver ) symbolSolverCollectionStrategy .getParserConfiguration ().getSymbolResolver ().get ();
961
- ParserConfiguration parserConfiguration = new ParserConfiguration ();
1012
+ Log .info ("Setting parser language level to JAVA_21" );
1013
+ ParserConfiguration parserConfiguration = new ParserConfiguration ().setLanguageLevel (ParserConfiguration .LanguageLevel .JAVA_21 );
962
1014
parserConfiguration .setSymbolResolver (javaSymbolSolver );
963
1015
964
1016
// create java parser with the configuration
@@ -972,6 +1024,7 @@ public static Pair<Map<String, JavaCompilationUnit>, Map<String, List<Problem>>>
972
1024
ParseResult <CompilationUnit > parseResult = javaParser .parse (javaFilePath );
973
1025
if (parseResult .isSuccessful ()) {
974
1026
CompilationUnit compilationUnit = parseResult .getResult ().get ();
1027
+ System .out .println ("Successfully parsed file: " + javaFilePath .toString ());
975
1028
symbolTable .put (compilationUnit .getStorage ().get ().getPath ().toString (), processCompilationUnit (compilationUnit ));
976
1029
} else {
977
1030
Log .error (parseResult .getProblems ().toString ());
0 commit comments