44import com .github .javaparser .ast .NodeList ;
55import com .github .javaparser .ast .PackageDeclaration ;
66import com .github .javaparser .ast .body .ClassOrInterfaceDeclaration ;
7+ import com .github .javaparser .ast .body .MethodDeclaration ;
8+ import com .github .javaparser .ast .expr .AssignExpr ;
9+ import com .github .javaparser .ast .expr .Expression ;
10+ import com .github .javaparser .ast .expr .MethodCallExpr ;
711import com .github .javaparser .ast .expr .Name ;
12+ import com .github .javaparser .ast .expr .NameExpr ;
813import com .github .javaparser .ast .type .ClassOrInterfaceType ;
14+ import com .github .javaparser .ast .type .Type ;
915import com .github .javaparser .ast .type .TypeParameter ;
1016import com .github .javaparser .utils .CodeGenerationUtils ;
1117import com .github .javaparser .utils .SourceRoot ;
12-
1318import io .github .bldl .astParsing .util .ClassData ;
1419import io .github .bldl .astParsing .util .MethodData ;
1520import io .github .bldl .astParsing .visitors .CastInsertionVisitor ;
1823import io .github .bldl .astParsing .visitors .VariableCollector ;
1924import io .github .bldl .graph .ClassHierarchyGraph ;
2025import io .github .bldl .util .Pair ;
26+ import com .github .javaparser .ast .body .Parameter ;
2127
2228import java .io .File ;
2329import java .nio .file .Paths ;
@@ -33,17 +39,19 @@ public class AstManipulator {
3339 private final Messager messager ;
3440 private final String sourceFolder ;
3541 private final SourceRoot sourceRoot ;
42+ private final ClassHierarchyGraph <String > classHierarchy ;
3643
3744 public AstManipulator (Messager messager , String sourceFolder ) {
3845 this .messager = messager ;
3946 this .sourceFolder = sourceFolder ;
4047 sourceRoot = new SourceRoot (
4148 CodeGenerationUtils .mavenModuleRoot (AstManipulator .class ).resolve (sourceFolder ));
49+ classHierarchy = computeClassHierarchy ();
4250 }
4351
4452 public void applyChanges () {
4553 this .sourceRoot .getCompilationUnits ().forEach (cu -> {
46- messager .printMessage (Kind .NOTE , "Saving cu: " + cu .toString ());
54+ // messager.printMessage(Kind.NOTE, "Saving cu: " + cu.toString());
4755 changePackageDeclaration (cu );
4856 });
4957 this .sourceRoot .saveAll (
@@ -69,9 +77,7 @@ public void eraseTypesAndInsertCasts(String cls, String packageName, String type
6977 methodMap );
7078
7179 messager .printMessage (Kind .NOTE , "Collected methods:\n " + methodMap .toString ());
72-
7380 changeAST (dir , classData , methodMap , "" );
74-
7581 }
7682
7783 public ClassHierarchyGraph <String > computeClassHierarchy () {
@@ -114,6 +120,7 @@ private void changeAST(File dir, ClassData classData, Map<String, MethodData> me
114120 Set <Pair <String , String >> varsToWatch = new HashSet <>();
115121 cu .accept (new VariableCollector (classData ), varsToWatch );
116122 messager .printMessage (Kind .NOTE , "Collected variables to watch:\n " + varsToWatch );
123+ performSubtypingChecks (cu , classData , methodMap , varsToWatch );
117124 cu .accept (new TypeEraserVisitor (classData ), null );
118125 for (Pair <String , String > var : varsToWatch ) {
119126 CastInsertionVisitor castInsertionVisitor = new CastInsertionVisitor (var , methodMap );
@@ -165,4 +172,61 @@ private String appendPackageDeclaration(String existing, String toAppend) {
165172 return toAppend ;
166173 return existing + "." + toAppend ;
167174 }
175+
176+ private void performSubtypingChecks (CompilationUnit cu , ClassData classData ,
177+ Map <String , MethodData > methodMap ,
178+ Set <Pair <String , String >> varsToWatch ) {
179+ Map <String , Map <Integer , Type >> methodParams = collectMethodParams (cu , classData );
180+ cu .findAll (MethodCallExpr .class ).forEach (methodCall -> {
181+ if (!methodParams .containsKey (methodCall .getNameAsString ()))
182+ return ;
183+ for (Integer paramIndex : methodParams .get (methodCall .getNameAsString ()).keySet ()) {
184+ Expression e = methodCall .getArgument (paramIndex );
185+ if (!(e instanceof NameExpr )) {
186+ messager .printMessage (Kind .WARNING , "Cannot resolve type for expression: " + e .toString ());
187+ continue ;
188+ }
189+ String name = ((NameExpr ) e ).getNameAsString ();
190+ varsToWatch .forEach (p -> {
191+ if (p .first .equals (name )) {
192+ // check subtyping
193+ }
194+ });
195+ }
196+
197+ });
198+ cu .findAll (AssignExpr .class ).forEach (assignExpr -> {
199+
200+ messager .printMessage (Kind .NOTE , assignExpr .toString ());
201+ messager .printMessage (Kind .NOTE , assignExpr .getTarget ().getClass ().toString ());
202+ messager .printMessage (Kind .NOTE , assignExpr .getValue ().getClass ().toString ());
203+ });
204+ // cu.findAll(ForEachStmt.class).forEach(stmt -> {
205+
206+ // });
207+ }
208+
209+ private Map <String , Map <Integer , Type >> collectMethodParams (CompilationUnit cu , ClassData classData ) {
210+ Map <String , Map <Integer , Type >> mp = new HashMap <>();
211+ cu .findAll (MethodDeclaration .class ).forEach (dec -> {
212+ NodeList <Parameter > params = dec .getParameters ();
213+ for (int i = 0 ; i < params .size (); ++i ) {
214+ Parameter param = params .get (i );
215+ if (!(param .getType () instanceof ClassOrInterfaceType ))
216+ continue ;
217+ ClassOrInterfaceType type = ((ClassOrInterfaceType ) param .getType ());
218+ String methodName = dec .getNameAsString ();
219+ if (type .getNameAsString ().equals (classData .className ())) {
220+ mp .putIfAbsent (methodName , new HashMap <>());
221+ mp .get (methodName ).put (i , type .getTypeArguments ().get ().get (classData .indexOfParam ()));
222+ }
223+ }
224+ });
225+ return mp ;
226+ }
227+
228+ private String resolveType () {
229+ return null ;
230+ }
231+
168232}
0 commit comments