Skip to content

Commit 5291651

Browse files
committed
Add parsing for things that are not in a method or class declaration.
1 parent 0c47d5c commit 5291651

4 files changed

Lines changed: 119 additions & 8 deletions

File tree

src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/parser/visitors/FieldAccessParser.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
import com.github.javaparser.ast.body.CallableDeclaration;
55
import com.github.javaparser.ast.expr.*;
66
import com.github.javaparser.resolution.UnsolvedSymbolException;
7+
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
78
import com.github.javaparser.resolution.types.ResolvedType;
89
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
910
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassFieldLocation;
11+
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassLocalVariableLocation;
12+
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassParameterLocation;
1013
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassReferenceLocation;
1114

1215
import java.util.Objects;
@@ -20,6 +23,58 @@
2023
class FieldAccessParser
2124
{
2225

26+
/**
27+
* Solve a field that is accessed through a lambda and not within a method or constructor
28+
*
29+
* @param container The {@link ClassFileContainer}
30+
* @param expr The {@link FieldAccessExpr}
31+
* @param className The class name of the class that is accessing the field
32+
*/
33+
static void parse(ClassFileContainer container, FieldAccessExpr expr, String className)
34+
{
35+
Range fieldRange = Objects.requireNonNull(expr.getTokenRange().orElse(null)).getEnd().getRange().orElse(null);
36+
if (fieldRange == null)
37+
return;
38+
39+
Value fieldValue = new Value(expr.getName(), fieldRange);
40+
41+
Expression scope = expr.getScope();
42+
if (scope instanceof NameExpr)
43+
{
44+
NameExpr nameExpr = (NameExpr) scope;
45+
Range scopeRange = nameExpr.getRange().orElse(null);
46+
if (scopeRange == null)
47+
return;
48+
49+
Value scopeValue = new Value(nameExpr.getName(), scopeRange);
50+
try
51+
{
52+
ResolvedValueDeclaration vd = nameExpr.resolve();
53+
if (vd.isField())
54+
{
55+
container.putField(scopeValue.name, new ClassFieldLocation(getOwner(container), "reference",
56+
scopeValue.line, scopeValue.columnStart, scopeValue.columnEnd + 1));
57+
}
58+
else if (vd.isVariable())
59+
{
60+
container.putLocalVariable(scopeValue.name, new ClassLocalVariableLocation(getOwner(container),
61+
className, "reference", scopeValue.line, scopeValue.columnStart, scopeValue.columnEnd + 1));
62+
}
63+
else if (vd.isParameter())
64+
{
65+
container.putParameter(scopeValue.name, new ClassParameterLocation(getOwner(container), className,
66+
"reference", scopeValue.line, scopeValue.columnStart, scopeValue.columnEnd + 1));
67+
}
68+
69+
putFieldResolvedValues(container, expr, nameExpr, fieldValue);
70+
}
71+
catch (Exception e)
72+
{
73+
throw new RuntimeException(e);
74+
}
75+
}
76+
}
77+
2378
static void parse(ClassFileContainer container, FieldAccessExpr expr, CallableDeclaration<?> method)
2479
{
2580
Range fieldRange = Objects.requireNonNull(expr.getTokenRange().orElse(null)).getEnd().getRange().orElse(null);
@@ -107,7 +162,8 @@ else if (scope instanceof EnclosedExpr)
107162
fieldValue.name, "reference", -1, -1, -1));
108163
}
109164

110-
container.putField(fieldValue.name, new ClassFieldLocation(className, "reference", fieldValue.line, fieldValue.columnStart, fieldValue.columnEnd + 1));
165+
container.putField(fieldValue.name, new ClassFieldLocation(className, "reference", fieldValue.line,
166+
fieldValue.columnStart, fieldValue.columnEnd + 1));
111167
}
112168
catch (Exception e)
113169
{

src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/parser/visitors/MyVoidVisitor.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ public void visit(FieldAccessExpr n, Object arg)
560560
try
561561
{
562562
InitializerDeclaration initializer = findInitializerForExpression(n, this.compilationUnit);
563+
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = findClassOrInterfaceForExpression(n, this.compilationUnit);
563564
CallableDeclaration<?> method = findMethodForExpression(n, this.compilationUnit);
564565
if (method == null)
565566
method = findConstructorForExpression(n, this.compilationUnit);
@@ -568,6 +569,8 @@ public void visit(FieldAccessExpr n, Object arg)
568569
FieldAccessParser.parse(classFileContainer, n, method);
569570
else if (initializer != null)
570571
FieldAccessParser.parseStatic(classFileContainer, n);
572+
else if (classOrInterfaceDeclaration != null)
573+
FieldAccessParser.parse(classFileContainer, n, classOrInterfaceDeclaration.getNameAsString());
571574
}
572575
catch (Exception e)
573576
{
@@ -836,12 +839,17 @@ public void visit(MethodCallExpr n, Object arg)
836839
{
837840
CallableDeclaration<?> method = findMethodForExpression(n, this.compilationUnit);
838841
InitializerDeclaration staticInitializer = null;
842+
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = null;
839843
if (method == null)
840844
{
841845
method = findConstructorForExpression(n, this.compilationUnit);
842846
if (method == null)
843847
{
844848
staticInitializer = findInitializerForExpression(n, this.compilationUnit);
849+
if (staticInitializer == null)
850+
{
851+
classOrInterfaceDeclaration = findClassOrInterfaceForExpression(n, this.compilationUnit);
852+
}
845853
}
846854
}
847855

@@ -870,6 +878,10 @@ else if (staticInitializer != null)
870878
{
871879
MethodCallParser.parseStatic(classFileContainer, n);
872880
}
881+
else if (classOrInterfaceDeclaration != null)
882+
{
883+
MethodCallParser.parse(classFileContainer, n, null);
884+
}
873885
}
874886
catch (Exception e)
875887
{

src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/parser/visitors/ParameterParser.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import com.github.javaparser.ast.CompilationUnit;
44
import com.github.javaparser.ast.Node;
5+
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
56
import com.github.javaparser.ast.body.Parameter;
7+
import com.github.javaparser.ast.expr.Expression;
68
import com.github.javaparser.ast.expr.SimpleName;
79
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
810

@@ -23,14 +25,21 @@ public static void parse(CompilationUnit compilationUnit, Parameter p, ClassFile
2325

2426
String methodName = findMethodOwnerFor(compilationUnit, node);
2527
if (methodName == null) {
26-
System.err.println("Parameter - Method not found");
27-
return;
28+
ClassOrInterfaceDeclaration classOrInterfaceForExpression = findClassOrInterfaceForExpression((Expression) node, compilationUnit);
29+
if (classOrInterfaceForExpression == null)
30+
{
31+
System.err.println("Parameter - Method not found");
32+
return;
33+
}
34+
35+
methodName = classOrInterfaceForExpression.getNameAsString();
2836
}
2937

3038
SimpleName name = p.getName();
39+
String finalMethodName = methodName;
3140
name.getRange().ifPresent(range -> {
3241
Value parameter = new Value(name, range);
33-
putParameter(container, parameter, methodName, "declaration");
42+
putParameter(container, parameter, finalMethodName, "declaration");
3443
});
3544
}
3645
}

src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/parser/visitors/ParserUtil.java

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import com.github.javaparser.Range;
44
import com.github.javaparser.ast.CompilationUnit;
55
import com.github.javaparser.ast.Node;
6-
import com.github.javaparser.ast.body.CallableDeclaration;
7-
import com.github.javaparser.ast.body.ConstructorDeclaration;
8-
import com.github.javaparser.ast.body.InitializerDeclaration;
9-
import com.github.javaparser.ast.body.MethodDeclaration;
6+
import com.github.javaparser.ast.body.*;
107
import com.github.javaparser.ast.expr.Expression;
118
import com.github.javaparser.ast.expr.NameExpr;
129
import com.github.javaparser.ast.expr.SimpleName;
@@ -196,8 +193,16 @@ static void putFieldResolvedValues(ClassFileContainer container, Expression visi
196193
Expression resolveExpr, Value fieldValue)
197194
{
198195
ResolvedType resolvedType = visitedExpr.getSymbolResolver().calculateType(resolveExpr);
196+
if (resolvedType.isConstraint())
197+
{
198+
resolvedType = resolvedType.asConstraintType().getBound();
199+
}
200+
199201
if (!resolvedType.isReferenceType())
202+
{
200203
return;
204+
}
205+
201206

202207
String qualifiedName = resolvedType.asReferenceType().getQualifiedName();
203208
String className = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
@@ -523,4 +528,33 @@ public void visit(InitializerDeclaration n, Void arg)
523528

524529
return null;
525530
}
531+
532+
static ClassOrInterfaceDeclaration findClassOrInterfaceForExpression(Expression expression, CompilationUnit cu)
533+
{
534+
final boolean[] contains = {false};
535+
final ClassOrInterfaceDeclaration[] classOrInterfaceDeclaration = {null};
536+
cu.accept(new VoidVisitorAdapter<Void>()
537+
{
538+
@Override
539+
public void visit(ClassOrInterfaceDeclaration n, Void arg)
540+
{
541+
super.visit(n, arg);
542+
if (contains[0])
543+
return;
544+
545+
n.getMembers().forEach(member -> {
546+
if (member.containsWithinRange(expression))
547+
{
548+
contains[0] = true;
549+
classOrInterfaceDeclaration[0] = n;
550+
}
551+
});
552+
}
553+
}, null);
554+
555+
if (contains[0])
556+
return classOrInterfaceDeclaration[0];
557+
558+
return null;
559+
}
526560
}

0 commit comments

Comments
 (0)