Skip to content

Commit

Permalink
Add parsing for things that are not in a method or class declaration.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bl3nd committed Oct 17, 2024
1 parent 0c47d5c commit 5291651
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import com.github.javaparser.ast.body.CallableDeclaration;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.resolution.UnsolvedSymbolException;
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
import com.github.javaparser.resolution.types.ResolvedType;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassFieldLocation;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassLocalVariableLocation;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassParameterLocation;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassReferenceLocation;

import java.util.Objects;
Expand All @@ -20,6 +23,58 @@
class FieldAccessParser
{

/**
* Solve a field that is accessed through a lambda and not within a method or constructor
*
* @param container The {@link ClassFileContainer}
* @param expr The {@link FieldAccessExpr}
* @param className The class name of the class that is accessing the field
*/
static void parse(ClassFileContainer container, FieldAccessExpr expr, String className)
{
Range fieldRange = Objects.requireNonNull(expr.getTokenRange().orElse(null)).getEnd().getRange().orElse(null);
if (fieldRange == null)
return;

Value fieldValue = new Value(expr.getName(), fieldRange);

Expression scope = expr.getScope();
if (scope instanceof NameExpr)
{
NameExpr nameExpr = (NameExpr) scope;
Range scopeRange = nameExpr.getRange().orElse(null);
if (scopeRange == null)
return;

Value scopeValue = new Value(nameExpr.getName(), scopeRange);
try
{
ResolvedValueDeclaration vd = nameExpr.resolve();
if (vd.isField())
{
container.putField(scopeValue.name, new ClassFieldLocation(getOwner(container), "reference",
scopeValue.line, scopeValue.columnStart, scopeValue.columnEnd + 1));
}
else if (vd.isVariable())
{
container.putLocalVariable(scopeValue.name, new ClassLocalVariableLocation(getOwner(container),
className, "reference", scopeValue.line, scopeValue.columnStart, scopeValue.columnEnd + 1));
}
else if (vd.isParameter())
{
container.putParameter(scopeValue.name, new ClassParameterLocation(getOwner(container), className,
"reference", scopeValue.line, scopeValue.columnStart, scopeValue.columnEnd + 1));
}

putFieldResolvedValues(container, expr, nameExpr, fieldValue);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}

static void parse(ClassFileContainer container, FieldAccessExpr expr, CallableDeclaration<?> method)
{
Range fieldRange = Objects.requireNonNull(expr.getTokenRange().orElse(null)).getEnd().getRange().orElse(null);
Expand Down Expand Up @@ -107,7 +162,8 @@ else if (scope instanceof EnclosedExpr)
fieldValue.name, "reference", -1, -1, -1));
}

container.putField(fieldValue.name, new ClassFieldLocation(className, "reference", fieldValue.line, fieldValue.columnStart, fieldValue.columnEnd + 1));
container.putField(fieldValue.name, new ClassFieldLocation(className, "reference", fieldValue.line,
fieldValue.columnStart, fieldValue.columnEnd + 1));
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ public void visit(FieldAccessExpr n, Object arg)
try
{
InitializerDeclaration initializer = findInitializerForExpression(n, this.compilationUnit);
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = findClassOrInterfaceForExpression(n, this.compilationUnit);
CallableDeclaration<?> method = findMethodForExpression(n, this.compilationUnit);
if (method == null)
method = findConstructorForExpression(n, this.compilationUnit);
Expand All @@ -568,6 +569,8 @@ public void visit(FieldAccessExpr n, Object arg)
FieldAccessParser.parse(classFileContainer, n, method);
else if (initializer != null)
FieldAccessParser.parseStatic(classFileContainer, n);
else if (classOrInterfaceDeclaration != null)
FieldAccessParser.parse(classFileContainer, n, classOrInterfaceDeclaration.getNameAsString());
}
catch (Exception e)
{
Expand Down Expand Up @@ -836,12 +839,17 @@ public void visit(MethodCallExpr n, Object arg)
{
CallableDeclaration<?> method = findMethodForExpression(n, this.compilationUnit);
InitializerDeclaration staticInitializer = null;
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = null;
if (method == null)
{
method = findConstructorForExpression(n, this.compilationUnit);
if (method == null)
{
staticInitializer = findInitializerForExpression(n, this.compilationUnit);
if (staticInitializer == null)
{
classOrInterfaceDeclaration = findClassOrInterfaceForExpression(n, this.compilationUnit);
}
}
}

Expand Down Expand Up @@ -870,6 +878,10 @@ else if (staticInitializer != null)
{
MethodCallParser.parseStatic(classFileContainer, n);
}
else if (classOrInterfaceDeclaration != null)
{
MethodCallParser.parse(classFileContainer, n, null);
}
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.SimpleName;
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;

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

String methodName = findMethodOwnerFor(compilationUnit, node);
if (methodName == null) {
System.err.println("Parameter - Method not found");
return;
ClassOrInterfaceDeclaration classOrInterfaceForExpression = findClassOrInterfaceForExpression((Expression) node, compilationUnit);
if (classOrInterfaceForExpression == null)
{
System.err.println("Parameter - Method not found");
return;
}

methodName = classOrInterfaceForExpression.getNameAsString();
}

SimpleName name = p.getName();
String finalMethodName = methodName;
name.getRange().ifPresent(range -> {
Value parameter = new Value(name, range);
putParameter(container, parameter, methodName, "declaration");
putParameter(container, parameter, finalMethodName, "declaration");
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import com.github.javaparser.Range;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.CallableDeclaration;
import com.github.javaparser.ast.body.ConstructorDeclaration;
import com.github.javaparser.ast.body.InitializerDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.SimpleName;
Expand Down Expand Up @@ -196,8 +193,16 @@ static void putFieldResolvedValues(ClassFileContainer container, Expression visi
Expression resolveExpr, Value fieldValue)
{
ResolvedType resolvedType = visitedExpr.getSymbolResolver().calculateType(resolveExpr);
if (resolvedType.isConstraint())
{
resolvedType = resolvedType.asConstraintType().getBound();
}

if (!resolvedType.isReferenceType())
{
return;
}


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

return null;
}

static ClassOrInterfaceDeclaration findClassOrInterfaceForExpression(Expression expression, CompilationUnit cu)
{
final boolean[] contains = {false};
final ClassOrInterfaceDeclaration[] classOrInterfaceDeclaration = {null};
cu.accept(new VoidVisitorAdapter<Void>()
{
@Override
public void visit(ClassOrInterfaceDeclaration n, Void arg)
{
super.visit(n, arg);
if (contains[0])
return;

n.getMembers().forEach(member -> {
if (member.containsWithinRange(expression))
{
contains[0] = true;
classOrInterfaceDeclaration[0] = n;
}
});
}
}, null);

if (contains[0])
return classOrInterfaceDeclaration[0];

return null;
}
}

0 comments on commit 5291651

Please sign in to comment.