22
33import com .fasterxml .jackson .databind .ObjectMapper ;
44import com .fasterxml .jackson .datatype .jdk8 .Jdk8Module ;
5-
65import com .github .javaparser .StaticJavaParser ;
76import com .github .javaparser .ast .CompilationUnit ;
87import com .github .javaparser .ast .ImportDeclaration ;
2423import com .github .javaparser .ast .type .ClassOrInterfaceType ;
2524import com .github .javaparser .ast .type .Type ;
2625import com .github .javaparser .ast .type .WildcardType ;
27-
2826import java .io .File ;
29- import java .util .AbstractCollection ;
3027import java .util .ArrayList ;
31- import java .util .Collection ;
3228import java .util .HashSet ;
3329import java .util .List ;
3430import java .util .Optional ;
3531import java .util .function .Consumer ;
3632import java .util .stream .Collectors ;
37- import java .util .stream .Stream ;
3833
3934class Import {
40- Import (String name , boolean isStatic , boolean isAsterisk ) {
41- this .name = name ;
42- this .isStatic = isStatic ;
43- this .isAsterisk = isAsterisk ;
44- }
45-
46- public static Import fromImportDeclaration (ImportDeclaration imp ) {
47- return new Import (imp .getName ().toString (), imp .isStatic (), imp .isAsterisk ());
48- }
49-
50- public final String name ;
51- public final boolean isStatic ;
52- public final boolean isAsterisk ;
35+ Import (String name , boolean isStatic , boolean isAsterisk ) {
36+ this .name = name ;
37+ this .isStatic = isStatic ;
38+ this .isAsterisk = isAsterisk ;
39+ }
40+
41+ public static Import fromImportDeclaration (ImportDeclaration imp ) {
42+ return new Import (imp .getName ().toString (), imp .isStatic (), imp .isAsterisk ());
43+ }
44+
45+ public final String name ;
46+ public final boolean isStatic ;
47+ public final boolean isAsterisk ;
5348}
5449
5550class CompilationUnitAnalysis {
56- CompilationUnitAnalysis (
57- Optional <String > declaredPackage ,
58- ArrayList <Import > imports ,
59- ArrayList <String > topLevelTypes ,
60- ArrayList <String > consumedTypes ,
61- ArrayList <String > exportTypes
62- ) {
63- this .declaredPackage = declaredPackage ;
64- this .imports = imports ;
65- this .topLevelTypes = topLevelTypes ;
66- this .consumedTypes = consumedTypes ;
67- this .exportTypes = exportTypes ;
68- }
69-
70- public final Optional <String > declaredPackage ;
71- public final ArrayList <Import > imports ;
72- public final ArrayList <String > topLevelTypes ;
73- public final ArrayList <String > consumedTypes ;
74- public final ArrayList <String > exportTypes ;
51+ CompilationUnitAnalysis (
52+ Optional <String > declaredPackage ,
53+ ArrayList <Import > imports ,
54+ ArrayList <String > topLevelTypes ,
55+ ArrayList <String > consumedTypes ,
56+ ArrayList <String > exportTypes ) {
57+ this .declaredPackage = declaredPackage ;
58+ this .imports = imports ;
59+ this .topLevelTypes = topLevelTypes ;
60+ this .consumedTypes = consumedTypes ;
61+ this .exportTypes = exportTypes ;
62+ }
63+
64+ public final Optional <String > declaredPackage ;
65+ public final ArrayList <Import > imports ;
66+ public final ArrayList <String > topLevelTypes ;
67+ public final ArrayList <String > consumedTypes ;
68+ public final ArrayList <String > exportTypes ;
7569}
7670
7771/**
78- * TODO: The dependencies of this class are defined in two places:
79- * 1. `3rdparty/jvm` via import inference.
80- * 2. `java_parser_artifact_requirements`.
81- * See https://github.com/pantsbuild/pants/issues/13754.
72+ * TODO: The dependencies of this class are defined in two places: 1. `3rdparty/jvm` via import
73+ * inference. 2. `java_parser_artifact_requirements`. See
74+ * https://github.com/pantsbuild/pants/issues/13754.
8275 */
8376public class PantsJavaParserLauncher {
84- // Unwrap a `Type` and return the identifiers representing the "consumed" types.
85- private static List <String > unwrapIdentifiersForType (Type type ) {
86- if (type .isArrayType ()) {
87- return unwrapIdentifiersForType (type .asArrayType ().getComponentType ());
88- } else if (type .isWildcardType ()) {
89- WildcardType wildcardType = type .asWildcardType ();
90- ArrayList <String > result = new ArrayList <>();
91- if (wildcardType .getExtendedType ().isPresent ()) {
92- result .addAll (unwrapIdentifiersForType (wildcardType .getExtendedType ().get ()));
93- }
94- if (wildcardType .getSuperType ().isPresent ()) {
95- result .addAll (unwrapIdentifiersForType (wildcardType .getSuperType ().get ()));
96- }
97- return result ;
98- } else if (type .isClassOrInterfaceType ()) {
99- ArrayList <String > result = new ArrayList <>();
100- ClassOrInterfaceType classType = type .asClassOrInterfaceType ();
101- Optional <NodeList <Type >> typeArguments = classType .getTypeArguments ();
102- if (typeArguments .isPresent ()) {
103- for (Type argumentType : typeArguments .get ()) {
104- result .addAll (unwrapIdentifiersForType (argumentType ));
105- }
106- }
107- result .add (classType .getNameWithScope ());
108- return result ;
109- } else if (type .isIntersectionType ()) {
110- ArrayList <String > result = new ArrayList <>();
111- for (Type elementType : type .asIntersectionType ().getElements ()) {
112- result .addAll (unwrapIdentifiersForType (elementType ));
113- }
114- return result ;
77+ // Unwrap a `Type` and return the identifiers representing the "consumed" types.
78+ private static List <String > unwrapIdentifiersForType (Type type ) {
79+ if (type .isArrayType ()) {
80+ return unwrapIdentifiersForType (type .asArrayType ().getComponentType ());
81+ } else if (type .isWildcardType ()) {
82+ WildcardType wildcardType = type .asWildcardType ();
83+ ArrayList <String > result = new ArrayList <>();
84+ if (wildcardType .getExtendedType ().isPresent ()) {
85+ result .addAll (unwrapIdentifiersForType (wildcardType .getExtendedType ().get ()));
86+ }
87+ if (wildcardType .getSuperType ().isPresent ()) {
88+ result .addAll (unwrapIdentifiersForType (wildcardType .getSuperType ().get ()));
89+ }
90+ return result ;
91+ } else if (type .isClassOrInterfaceType ()) {
92+ ArrayList <String > result = new ArrayList <>();
93+ ClassOrInterfaceType classType = type .asClassOrInterfaceType ();
94+ Optional <NodeList <Type >> typeArguments = classType .getTypeArguments ();
95+ if (typeArguments .isPresent ()) {
96+ for (Type argumentType : typeArguments .get ()) {
97+ result .addAll (unwrapIdentifiersForType (argumentType ));
11598 }
99+ }
100+ result .add (classType .getNameWithScope ());
101+ return result ;
102+ } else if (type .isIntersectionType ()) {
103+ ArrayList <String > result = new ArrayList <>();
104+ for (Type elementType : type .asIntersectionType ().getElements ()) {
105+ result .addAll (unwrapIdentifiersForType (elementType ));
106+ }
107+ return result ;
108+ }
116109
117- // Not handled:
118- // - PrimitiveType
119- // - VarType (Java `var` keyword to be inferred by the compiler.
110+ // Not handled:
111+ // - PrimitiveType
112+ // - VarType (Java `var` keyword to be inferred by the compiler.
120113
121- return new ArrayList <>();
122- }
114+ return new ArrayList <>();
115+ }
123116
124- public static void main (String [] args ) throws Exception {
125- String analysisOutputPath = args [0 ];
126- String sourceToAnalyze = args [1 ];
117+ public static void main (String [] args ) throws Exception {
118+ String analysisOutputPath = args [0 ];
119+ String sourceToAnalyze = args [1 ];
127120
128- CompilationUnit cu = StaticJavaParser .parse (new File (sourceToAnalyze ));
121+ CompilationUnit cu = StaticJavaParser .parse (new File (sourceToAnalyze ));
129122
130- // Get the source's declare package.
131- Optional <String > declaredPackage = cu .getPackageDeclaration ()
132- .map (PackageDeclaration ::getName )
133- .map (Name ::toString );
123+ // Get the source's declare package.
124+ Optional <String > declaredPackage =
125+ cu .getPackageDeclaration ().map (PackageDeclaration ::getName ).map (Name ::toString );
134126
135- // Get the source's imports.
136- ArrayList <Import > imports = new ArrayList <Import >(
127+ // Get the source's imports.
128+ ArrayList <Import > imports =
129+ new ArrayList <Import >(
137130 cu .getImports ().stream ()
138131 .map (Import ::fromImportDeclaration )
139132 .collect (Collectors .toList ()));
140133
141- // Get the source's top level types
142- ArrayList <String > topLevelTypes = new ArrayList <String >(
134+ // Get the source's top level types
135+ ArrayList <String > topLevelTypes =
136+ new ArrayList <String >(
143137 cu .getTypes ().stream ()
144138 .filter (TypeDeclaration ::isTopLevelType )
145139 .map (TypeDeclaration ::getFullyQualifiedName )
@@ -149,78 +143,88 @@ public static void main(String[] args) throws Exception {
149143 .map (Optional ::get )
150144 .collect (Collectors .toList ()));
151145
152- HashSet <Type > candidateConsumedTypes = new HashSet <>();
153- HashSet <Type > candidateExportTypes = new HashSet <>();
154-
155- Consumer <Type > consumed = (type ) -> { candidateConsumedTypes .add (type ); };
156- Consumer <Type > export = (type ) -> { candidateConsumedTypes .add (type ); candidateExportTypes .add (type ); };
157-
158- HashSet <String > consumedIdentifiers = new HashSet <>();
159- HashSet <String > exportIdentifiers = new HashSet <>();
160-
161- cu .walk (new Consumer <Node >() {
162- @ Override
163- public void accept (Node node ) {
164- if (node instanceof NodeWithType ) {
165- NodeWithType <?, ?> typedNode = (NodeWithType <?, ?>) node ;
166- consumed .accept (typedNode .getType ());
167- }
168- if (node instanceof VariableDeclarator ) {
169- VariableDeclarator varDecl = (VariableDeclarator ) node ;
170- consumed .accept (varDecl .getType ());
171- }
172- if (node instanceof MethodDeclaration ) {
173- MethodDeclaration methodDecl = (MethodDeclaration ) node ;
174- export .accept (methodDecl .getType ());
175- for (Parameter param : methodDecl .getParameters ()) {
176- export .accept (param .getType ());
177- }
178- methodDecl .getThrownExceptions ().stream ().forEach (consumed );
179- }
180- if (node instanceof ClassOrInterfaceDeclaration ) {
181- ClassOrInterfaceDeclaration classOrIntfDecl = (ClassOrInterfaceDeclaration ) node ;
182- classOrIntfDecl .getExtendedTypes ().stream ().forEach (export );
183- classOrIntfDecl .getImplementedTypes ().stream ().forEach (export );
184- }
185- if (node instanceof AnnotationExpr ) {
186- AnnotationExpr annoExpr = (AnnotationExpr ) node ;
187- consumedIdentifiers .add (annoExpr .getNameAsString ());
188- }
189- if (node instanceof MethodCallExpr ) {
190- MethodCallExpr methodCallExpr = (MethodCallExpr ) node ;
191- Optional <Expression > scopeExprOpt = methodCallExpr .getScope ();
192- if (scopeExprOpt .isPresent ()) {
193- Expression scope = scopeExprOpt .get ();
194- if (scope instanceof NameExpr ) {
195- NameExpr nameExpr = (NameExpr ) scope ;
196- consumedIdentifiers .add (nameExpr .getNameAsString ());
197- }
198- }
199- }
200- if (node instanceof FieldAccessExpr ) {
201- FieldAccessExpr fieldAccessExpr = (FieldAccessExpr ) node ;
202- Expression scope = fieldAccessExpr .getScope ();
203- if (scope instanceof NameExpr ) {
204- NameExpr nameExpr = (NameExpr ) scope ;
205- consumedIdentifiers .add (nameExpr .getNameAsString ());
206- }
146+ HashSet <Type > candidateConsumedTypes = new HashSet <>();
147+ HashSet <Type > candidateExportTypes = new HashSet <>();
148+
149+ Consumer <Type > consumed =
150+ (type ) -> {
151+ candidateConsumedTypes .add (type );
152+ };
153+ Consumer <Type > export =
154+ (type ) -> {
155+ candidateConsumedTypes .add (type );
156+ candidateExportTypes .add (type );
157+ };
158+
159+ HashSet <String > consumedIdentifiers = new HashSet <>();
160+ HashSet <String > exportIdentifiers = new HashSet <>();
161+
162+ cu .walk (
163+ new Consumer <Node >() {
164+ @ Override
165+ public void accept (Node node ) {
166+ if (node instanceof NodeWithType ) {
167+ NodeWithType <?, ?> typedNode = (NodeWithType <?, ?>) node ;
168+ consumed .accept (typedNode .getType ());
169+ }
170+ if (node instanceof VariableDeclarator ) {
171+ VariableDeclarator varDecl = (VariableDeclarator ) node ;
172+ consumed .accept (varDecl .getType ());
173+ }
174+ if (node instanceof MethodDeclaration ) {
175+ MethodDeclaration methodDecl = (MethodDeclaration ) node ;
176+ export .accept (methodDecl .getType ());
177+ for (Parameter param : methodDecl .getParameters ()) {
178+ export .accept (param .getType ());
179+ }
180+ methodDecl .getThrownExceptions ().stream ().forEach (consumed );
181+ }
182+ if (node instanceof ClassOrInterfaceDeclaration ) {
183+ ClassOrInterfaceDeclaration classOrIntfDecl = (ClassOrInterfaceDeclaration ) node ;
184+ classOrIntfDecl .getExtendedTypes ().stream ().forEach (export );
185+ classOrIntfDecl .getImplementedTypes ().stream ().forEach (export );
186+ }
187+ if (node instanceof AnnotationExpr ) {
188+ AnnotationExpr annoExpr = (AnnotationExpr ) node ;
189+ consumedIdentifiers .add (annoExpr .getNameAsString ());
190+ }
191+ if (node instanceof MethodCallExpr ) {
192+ MethodCallExpr methodCallExpr = (MethodCallExpr ) node ;
193+ Optional <Expression > scopeExprOpt = methodCallExpr .getScope ();
194+ if (scopeExprOpt .isPresent ()) {
195+ Expression scope = scopeExprOpt .get ();
196+ if (scope instanceof NameExpr ) {
197+ NameExpr nameExpr = (NameExpr ) scope ;
198+ consumedIdentifiers .add (nameExpr .getNameAsString ());
207199 }
200+ }
208201 }
209- });
210-
211- for ( Type type : candidateConsumedTypes ) {
212- List < String > identifiersForType = unwrapIdentifiersForType ( type );
213- consumedIdentifiers . addAll ( identifiersForType ) ;
214- if ( candidateExportTypes . contains ( type )) {
215- exportIdentifiers . addAll ( identifiersForType );
202+ if ( node instanceof FieldAccessExpr ) {
203+ FieldAccessExpr fieldAccessExpr = ( FieldAccessExpr ) node ;
204+ Expression scope = fieldAccessExpr . getScope ();
205+ if ( scope instanceof NameExpr ) {
206+ NameExpr nameExpr = ( NameExpr ) scope ;
207+ consumedIdentifiers . add ( nameExpr . getNameAsString ());
208+ }
216209 }
217- }
210+ }
211+ });
218212
219- ArrayList < String > consumedTypes = new ArrayList <>( consumedIdentifiers );
220- ArrayList <String > exportTypes = new ArrayList <>( exportIdentifiers );
221- CompilationUnitAnalysis analysis = new CompilationUnitAnalysis ( declaredPackage , imports , topLevelTypes , consumedTypes , exportTypes );
222- ObjectMapper mapper = new ObjectMapper ();
223- mapper . registerModule ( new Jdk8Module () );
224- mapper . writeValue ( new File ( analysisOutputPath ), analysis );
213+ for ( Type type : candidateConsumedTypes ) {
214+ List <String > identifiersForType = unwrapIdentifiersForType ( type );
215+ consumedIdentifiers . addAll ( identifiersForType );
216+ if ( candidateExportTypes . contains ( type )) {
217+ exportIdentifiers . addAll ( identifiersForType );
218+ }
225219 }
220+
221+ ArrayList <String > consumedTypes = new ArrayList <>(consumedIdentifiers );
222+ ArrayList <String > exportTypes = new ArrayList <>(exportIdentifiers );
223+ CompilationUnitAnalysis analysis =
224+ new CompilationUnitAnalysis (
225+ declaredPackage , imports , topLevelTypes , consumedTypes , exportTypes );
226+ ObjectMapper mapper = new ObjectMapper ();
227+ mapper .registerModule (new Jdk8Module ());
228+ mapper .writeValue (new File (analysisOutputPath ), analysis );
229+ }
226230}
0 commit comments