Attempt at making the code more understandable and a few other things.
- Added examples on what visitor visits - Moved away from the line, columnStart and columnEnd variables for each visitor, instead we use the Value class. - Added a few more values we parse.
This commit is contained in:
parent
82789aa38e
commit
340bec4fe8
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,122 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.body.CallableDeclaration;
|
||||
import com.github.javaparser.ast.expr.*;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.Value;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.*;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 10/1/2024
|
||||
*/
|
||||
class ArrayParser
|
||||
{
|
||||
|
||||
static void parseAccess(CompilationUnit compilationUnit, ArrayAccessExpr expr, ClassFileContainer container)
|
||||
{
|
||||
Expression valueExp = expr.getName();
|
||||
if (valueExp instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) valueExp;
|
||||
CallableDeclaration<?> method = findMethodForExpression(expr, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
method = findConstructorForExpression(expr, compilationUnit);
|
||||
}
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
System.err.println("ArrayAccess1 - Method not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value nameValue = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, nameValue);
|
||||
}
|
||||
|
||||
Expression indexExp = expr.getIndex();
|
||||
if (indexExp instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) indexExp;
|
||||
CallableDeclaration<?> method = findMethodForExpression(expr, compilationUnit);
|
||||
if (method == null)
|
||||
method = findConstructorForExpression(expr, compilationUnit);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
System.err.println("ArrayAccess2 - Method not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value indexValue = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, indexValue);
|
||||
}
|
||||
}
|
||||
|
||||
static void parseCreation(CompilationUnit compilationUnit, ArrayCreationExpr expr,
|
||||
ClassFileContainer container)
|
||||
{
|
||||
expr.getLevels().forEach(level -> {
|
||||
Expression dimensionExpr = level.getDimension().orElse(null);
|
||||
if (dimensionExpr instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) dimensionExpr;
|
||||
CallableDeclaration<?> method = findMethodForExpression(expr, compilationUnit);
|
||||
if (method == null)
|
||||
method = findConstructorForExpression(expr, compilationUnit);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
System.err.println("ArrayCreation - Method not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value dimensionValue = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, dimensionValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void parseInitializer(CompilationUnit compilationUnit, ArrayInitializerExpr expr,
|
||||
ClassFileContainer container)
|
||||
{
|
||||
expr.getValues().forEach(value -> {
|
||||
if (value instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) value;
|
||||
CallableDeclaration<?> method = findMethodForExpression(expr, compilationUnit);
|
||||
if (method == null)
|
||||
method = findConstructorForExpression(expr, compilationUnit);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
System.err.println("ArrayInitializer - Method not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value valueValue = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, valueValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.body.CallableDeclaration;
|
||||
import com.github.javaparser.ast.expr.AssignExpr;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import com.github.javaparser.ast.expr.SimpleName;
|
||||
import com.github.javaparser.resolution.UnsolvedSymbolException;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.Value;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.printException;
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.putResolvedValues;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 9/29/2024
|
||||
*/
|
||||
class AssignParser
|
||||
{
|
||||
|
||||
static void parse(ClassFileContainer container, AssignExpr expr, CallableDeclaration<?> method)
|
||||
{
|
||||
if (expr.getValue() instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) expr.getValue();
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value value = new Value(nameExpr.getName(), range);
|
||||
try
|
||||
{
|
||||
putResolvedValues(container, "reference", method, nameExpr, value);
|
||||
}
|
||||
catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.getTarget() instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) expr.getTarget();
|
||||
try
|
||||
{
|
||||
SimpleName simpleName = nameExpr.getName();
|
||||
Range range = simpleName.getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value target = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, target);
|
||||
}
|
||||
catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parseStatic(ClassFileContainer container, AssignExpr expr)
|
||||
{
|
||||
if (expr.getValue() instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) expr.getValue();
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value value = new Value(nameExpr.getName(), range);
|
||||
try
|
||||
{
|
||||
putResolvedValues(container, "reference", nameExpr, value);
|
||||
}
|
||||
catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.getTarget() instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) expr.getTarget();
|
||||
try
|
||||
{
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value target = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", nameExpr, target);
|
||||
}
|
||||
catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.body.CallableDeclaration;
|
||||
import com.github.javaparser.ast.expr.ConditionalExpr;
|
||||
import com.github.javaparser.ast.expr.Expression;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.Value;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.*;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 10/1/2024
|
||||
*/
|
||||
class ConditionalParser
|
||||
{
|
||||
|
||||
static void parse(CompilationUnit compilationUnit, ConditionalExpr expr, ClassFileContainer container)
|
||||
{
|
||||
CallableDeclaration<?> method = findMethodForExpression(expr, compilationUnit);
|
||||
if (method == null)
|
||||
method = findConstructorForExpression(expr, compilationUnit);
|
||||
|
||||
if (method == null)
|
||||
return;
|
||||
|
||||
Expression elseExpr = expr.getElseExpr();
|
||||
if (elseExpr instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) elseExpr;
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value elseValue = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, elseValue);
|
||||
}
|
||||
|
||||
Expression thenExpr = expr.getThenExpr();
|
||||
if (thenExpr instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) thenExpr;
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value thenValue = new Value(nameExpr.getName(), range);
|
||||
putResolvedValues(container, "reference", method, nameExpr, thenValue);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.expr.*;
|
||||
import com.github.javaparser.resolution.UnsolvedSymbolException;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.*;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 9/28/2024
|
||||
*/
|
||||
class FieldAccessParser
|
||||
{
|
||||
|
||||
static void parse(ClassFileContainer container, FieldAccessExpr expr)
|
||||
{
|
||||
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();
|
||||
|
||||
// Ex. Clazz.field -> Clazz
|
||||
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
|
||||
{
|
||||
putClassResolvedValues(container, expr, nameExpr, scopeValue, fieldValue);
|
||||
}
|
||||
catch (UnsolvedSymbolException ignore)
|
||||
{
|
||||
try
|
||||
{
|
||||
putClassResolvedValues(container, expr, nameExpr, scopeValue, fieldValue);
|
||||
}
|
||||
catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
} // Ex. this.field
|
||||
else if (scope instanceof ThisExpr)
|
||||
{
|
||||
ThisExpr thisExpr = (ThisExpr) scope;
|
||||
try
|
||||
{
|
||||
putFieldResolvedValues(container, expr, thisExpr, fieldValue);
|
||||
} catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
else if (scope instanceof EnclosedExpr)
|
||||
{
|
||||
EnclosedExpr enclosedExpr = (EnclosedExpr) scope;
|
||||
try
|
||||
{
|
||||
putFieldResolvedValues(container, expr, enclosedExpr, fieldValue);
|
||||
} catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parseStatic(ClassFileContainer container, FieldAccessExpr expr)
|
||||
{
|
||||
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
|
||||
{
|
||||
putClassResolvedValues(container, expr, nameExpr, scopeValue, fieldValue);
|
||||
}
|
||||
catch (UnsolvedSymbolException ignore)
|
||||
{
|
||||
try
|
||||
{
|
||||
putClassResolvedValues(container, expr, nameExpr, scopeValue, fieldValue);
|
||||
} catch (UnsolvedSymbolException e) {
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (scope instanceof ThisExpr)
|
||||
{
|
||||
ThisExpr thisExpr = (ThisExpr) scope;
|
||||
try {
|
||||
putFieldResolvedValues(container, expr, thisExpr, fieldValue);
|
||||
} catch (UnsolvedSymbolException e) {
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
import com.github.javaparser.Range;
|
||||
import com.github.javaparser.ast.body.CallableDeclaration;
|
||||
import com.github.javaparser.ast.expr.Expression;
|
||||
import com.github.javaparser.ast.expr.MethodCallExpr;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import com.github.javaparser.resolution.UnsolvedSymbolException;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.Value;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.*;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 9/28/2024
|
||||
*/
|
||||
class MethodCallParser
|
||||
{
|
||||
|
||||
static void parse(ClassFileContainer container, MethodCallExpr expr, CallableDeclaration<?> method)
|
||||
{
|
||||
if (expr.hasScope())
|
||||
{
|
||||
Expression scope = expr.getScope().orElse(null);
|
||||
|
||||
/*
|
||||
Ex.
|
||||
field.method -> field
|
||||
variable.method -> variable
|
||||
parameter.method -> parameter
|
||||
*/
|
||||
if (scope instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) scope;
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value scopeValue = new Value(nameExpr.getName(), range);
|
||||
|
||||
try
|
||||
{
|
||||
putResolvedValues(container, "reference", method, nameExpr, scopeValue);
|
||||
}
|
||||
catch (UnsolvedSymbolException ignored)
|
||||
{
|
||||
try
|
||||
{
|
||||
putClassResolvedValues(container, expr, nameExpr, scopeValue);
|
||||
} catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ex. method(arg, arg, ...)
|
||||
expr.getArguments().forEach(argument ->
|
||||
{
|
||||
if (argument instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) argument;
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
return;
|
||||
|
||||
Value argName = new Value(nameExpr.getName(), range);
|
||||
try {
|
||||
putResolvedValues(container, "reference", method, nameExpr, argName);
|
||||
} catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void parseStatic(ClassFileContainer container, MethodCallExpr expr)
|
||||
{
|
||||
if (expr.hasScope())
|
||||
{
|
||||
/*
|
||||
Ex.
|
||||
field.method -> field
|
||||
variable.method -> variable
|
||||
parameter.method -> parameter
|
||||
*/
|
||||
Expression scope = expr.getScope().orElse(null);
|
||||
if (scope instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) scope;
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Value scopeValue = new Value(nameExpr.getName(), range);
|
||||
|
||||
try {
|
||||
putResolvedValues(container, "reference", nameExpr, scopeValue);
|
||||
} catch (UnsolvedSymbolException ignored)
|
||||
{
|
||||
try
|
||||
{
|
||||
putClassResolvedValues(container, expr, nameExpr, scopeValue);
|
||||
} catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expr.getArguments().forEach(argument ->
|
||||
{
|
||||
if (argument instanceof NameExpr)
|
||||
{
|
||||
NameExpr nameExpr = (NameExpr) argument;
|
||||
Range range = nameExpr.getName().getRange().orElse(null);
|
||||
if (range == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Value argValue = new Value(nameExpr.getName(), range);
|
||||
|
||||
try
|
||||
{
|
||||
putResolvedValues(container, "reference", nameExpr, argValue);
|
||||
} catch (UnsolvedSymbolException e)
|
||||
{
|
||||
printException(expr, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,36 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.ast.body.Parameter;
|
||||
import com.github.javaparser.ast.expr.SimpleName;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors.ParserUtil.*;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 10/1/2024
|
||||
*/
|
||||
public class ParameterParser
|
||||
{
|
||||
|
||||
public static void parse(CompilationUnit compilationUnit, Parameter p, ClassFileContainer container)
|
||||
{
|
||||
Node node = p.getParentNode().orElse(null);
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
String methodName = findMethodOwnerFor(compilationUnit, node);
|
||||
if (methodName == null) {
|
||||
System.err.println("Parameter - Method not found");
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleName name = p.getName();
|
||||
name.getRange().ifPresent(range -> {
|
||||
Value parameter = new Value(name, range);
|
||||
putParameter(container, parameter, methodName, "declaration");
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,514 @@
|
|||
package the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.visitors;
|
||||
|
||||
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.expr.Expression;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import com.github.javaparser.ast.expr.SimpleName;
|
||||
import com.github.javaparser.ast.stmt.CatchClause;
|
||||
import com.github.javaparser.ast.stmt.Statement;
|
||||
import com.github.javaparser.ast.stmt.TryStmt;
|
||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||||
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
|
||||
import com.github.javaparser.resolution.types.ResolvedReferenceType;
|
||||
import com.github.javaparser.resolution.types.ResolvedType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
* Date: 9/28/2024
|
||||
*/
|
||||
class ParserUtil
|
||||
{
|
||||
|
||||
static class Value
|
||||
{
|
||||
|
||||
final String name;
|
||||
final int line;
|
||||
final int columnStart;
|
||||
final int columnEnd;
|
||||
|
||||
public Value(SimpleName simpleName, Range range)
|
||||
{
|
||||
this.name = simpleName.getIdentifier();
|
||||
this.line = range.begin.line;
|
||||
this.columnStart = range.begin.column;
|
||||
this.columnEnd = range.end.column;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put resolved value types (field, variable and parameter) that have a method as an owner.
|
||||
*
|
||||
* @param container The class container
|
||||
* @param method The owner method of the type
|
||||
* @param resolveExpr The {@code NameExpr}
|
||||
* @param value The value
|
||||
*/
|
||||
static void putResolvedValues(ClassFileContainer container, String decRef, CallableDeclaration<?> method,
|
||||
NameExpr resolveExpr, Value value)
|
||||
{
|
||||
ResolvedValueDeclaration vd = resolveExpr.resolve();
|
||||
if (vd.isField())
|
||||
{
|
||||
container.putField(value.name, new ClassFieldLocation(getOwner(container), decRef,
|
||||
value.line, value.columnStart, value.columnEnd + 1));
|
||||
}
|
||||
else if (vd.isVariable())
|
||||
{
|
||||
container.putLocalVariable(value.name, new ClassLocalVariableLocation(getOwner(container)
|
||||
, getMethod(method), decRef, value.line, value.columnStart,
|
||||
value.columnEnd + 1));
|
||||
}
|
||||
else if (vd.isParameter())
|
||||
{
|
||||
container.putParameter(value.name, new ClassParameterLocation(getOwner(container),
|
||||
getMethod(method), decRef, value.line, value.columnStart,
|
||||
value.columnEnd + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put resolved value types (field, variable and parameter) that are in a static block.
|
||||
*
|
||||
* @param container The class container
|
||||
* @param resolveExpr The {@code NameExpr}
|
||||
* @param value The value
|
||||
*/
|
||||
static void putResolvedValues(ClassFileContainer container, String decRef, NameExpr resolveExpr, Value value)
|
||||
{
|
||||
ResolvedValueDeclaration vd = resolveExpr.resolve();
|
||||
if (vd.isField())
|
||||
{
|
||||
container.putField(value.name, new ClassFieldLocation(getOwner(container), decRef,
|
||||
value.line, value.columnStart, value.columnEnd + 1));
|
||||
}
|
||||
else if (vd.isVariable())
|
||||
{
|
||||
container.putLocalVariable(value.name, new ClassLocalVariableLocation(getOwner(container)
|
||||
, "static", decRef, value.line, value.columnStart, value.columnEnd + 1));
|
||||
}
|
||||
else if (vd.isParameter())
|
||||
{
|
||||
container.putParameter(value.name, new ClassParameterLocation(getOwner(container),
|
||||
"static", decRef, value.line, value.columnStart, value.columnEnd + 1));
|
||||
}
|
||||
}
|
||||
|
||||
static void putParameter(ClassFileContainer container, Value parameter, String method, String decRef)
|
||||
{
|
||||
container.putParameter(parameter.name, new ClassParameterLocation(getOwner(container), method, decRef,
|
||||
parameter.line, parameter.columnStart, parameter.columnEnd + 1));
|
||||
}
|
||||
|
||||
static void putLocalVariable(ClassFileContainer container, Value variable, String method, String decRef)
|
||||
{
|
||||
container.putLocalVariable(variable.name, new ClassLocalVariableLocation(getOwner(container), method, decRef,
|
||||
variable.line, variable.columnStart, variable.columnEnd + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Put both the class and field reference.
|
||||
*
|
||||
* @param container The class container
|
||||
* @param visitedExpr The main expression
|
||||
* @param resolveExpr The expression to resolve
|
||||
* @param scopeValue The scope value
|
||||
* @param fieldValue The field value
|
||||
*/
|
||||
static void putClassResolvedValues(ClassFileContainer container, Expression visitedExpr,
|
||||
Expression resolveExpr,
|
||||
Value scopeValue, Value fieldValue)
|
||||
{
|
||||
ResolvedType resolvedType = visitedExpr.getSymbolResolver().calculateType(resolveExpr);
|
||||
if (!resolvedType.isReferenceType())
|
||||
return;
|
||||
|
||||
String qualifiedName = resolvedType.asReferenceType().getQualifiedName();
|
||||
String className = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
|
||||
String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf('.'));
|
||||
container.putClassReference(className, new ClassReferenceLocation(ParserUtil.getOwner(container),
|
||||
packageName.replace('.', '/'), fieldValue.name, "reference", scopeValue.line, scopeValue.columnStart,
|
||||
scopeValue.columnEnd + 1));
|
||||
container.putField(fieldValue.name, new ClassFieldLocation(scopeValue.name, "reference", fieldValue.line,
|
||||
fieldValue.columnStart, fieldValue.columnEnd + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Put only the class reference.
|
||||
*
|
||||
* @param container The class container
|
||||
* @param visitedExpr The main expression
|
||||
* @param resolveExpr The expression to resolve
|
||||
* @param scopeValue The scope value
|
||||
*/
|
||||
static void putClassResolvedValues(ClassFileContainer container, Expression visitedExpr,
|
||||
Expression resolveExpr, Value scopeValue)
|
||||
{
|
||||
ResolvedType resolvedType = visitedExpr.getSymbolResolver().calculateType(resolveExpr);
|
||||
if (!resolvedType.isReferenceType())
|
||||
return;
|
||||
|
||||
ResolvedReferenceType referenceType = resolvedType.asReferenceType();
|
||||
if (!referenceType.hasName())
|
||||
return;
|
||||
|
||||
String qualifiedName = referenceType.getQualifiedName();
|
||||
String className = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
|
||||
String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf('.'));
|
||||
container.putClassReference(className, new ClassReferenceLocation(ParserUtil.getOwner(container),
|
||||
packageName.replace('.', '/'), "", "reference", scopeValue.line, scopeValue.columnStart,
|
||||
scopeValue.columnEnd + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Put only a class field reference.
|
||||
*
|
||||
* @param container The class container
|
||||
* @param visitedExpr The main expression
|
||||
* @param resolveExpr The expression to resolve
|
||||
* @param fieldValue The field value
|
||||
*/
|
||||
static void putFieldResolvedValues(ClassFileContainer container, Expression visitedExpr,
|
||||
Expression resolveExpr, Value fieldValue)
|
||||
{
|
||||
ResolvedType resolvedType = visitedExpr.getSymbolResolver().calculateType(resolveExpr);
|
||||
if (!resolvedType.isReferenceType())
|
||||
return;
|
||||
|
||||
String qualifiedName = resolvedType.asReferenceType().getQualifiedName();
|
||||
String className = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
|
||||
container.putField(fieldValue.name, new ClassFieldLocation(className, "reference", fieldValue.line,
|
||||
fieldValue.columnStart, fieldValue.columnEnd + 1));
|
||||
}
|
||||
|
||||
static void printException(Object o, Exception e)
|
||||
{
|
||||
System.err.println(o.getClass().getSimpleName() + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
static String getOwner(ClassFileContainer container)
|
||||
{
|
||||
return container.getName();
|
||||
}
|
||||
|
||||
static String getMethod(CallableDeclaration<?> method)
|
||||
{
|
||||
return method.getDeclarationAsString(false, false);
|
||||
}
|
||||
|
||||
static @Nullable String findMethodOwnerFor(CompilationUnit compilationUnit, Node node)
|
||||
{
|
||||
if (node instanceof CallableDeclaration<?>)
|
||||
{
|
||||
return ((CallableDeclaration<?>) node).getDeclarationAsString(false, false);
|
||||
}
|
||||
else if (node instanceof CatchClause)
|
||||
{
|
||||
TryStmt statement = (TryStmt) node.getParentNode().orElse(null);
|
||||
if (statement == null)
|
||||
return null;
|
||||
|
||||
CallableDeclaration<?> method = findMethodForStatement(statement, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
method = findConstructorForStatement(statement, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
if (findInitializerForStatement(statement, compilationUnit) != null)
|
||||
return "static";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return method.getDeclarationAsString(false, false);
|
||||
}
|
||||
else if (node instanceof Statement)
|
||||
{
|
||||
CallableDeclaration<?> method = findMethodForStatement((Statement) node, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
method = findConstructorForStatement((Statement) node, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
if (findInitializerForStatement((Statement) node, compilationUnit) != null)
|
||||
return "static";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return method.getDeclarationAsString(false, false);
|
||||
}
|
||||
else if (node instanceof Expression)
|
||||
{
|
||||
CallableDeclaration<?> method = findMethodForExpression((Expression) node, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
method = findConstructorForExpression((Expression) node, compilationUnit);
|
||||
if (method == null)
|
||||
{
|
||||
if (findInitializerForExpression((Expression) node, compilationUnit) != null)
|
||||
return "static";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return method.getDeclarationAsString(false, false);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
* @param statement The {@code statement} we are looking for
|
||||
* @param cu The {@code CompilationUnit}
|
||||
* @return the method that contains the {@code statement}.
|
||||
*/
|
||||
static MethodDeclaration findMethodForStatement(Statement statement, CompilationUnit cu)
|
||||
{
|
||||
final boolean[] contains = {false};
|
||||
final MethodDeclaration[] methodDeclaration = {null};
|
||||
cu.accept(new VoidVisitorAdapter<Void>()
|
||||
{
|
||||
@Override
|
||||
public void visit(MethodDeclaration n, Void arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
if (!n.isAbstract()/* && !contains[0]*/)
|
||||
{
|
||||
for (Statement statement1 : n.getBody().get().getStatements())
|
||||
{
|
||||
if (statement1.containsWithinRange(statement))
|
||||
{
|
||||
contains[0] = true;
|
||||
methodDeclaration[0] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
if (contains[0])
|
||||
{
|
||||
return methodDeclaration[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
* @param expression The {@code expression} we are looking for
|
||||
* @param cu The {@code CompilationUnit}
|
||||
* @return the method that contains the {@code expression}.
|
||||
*/
|
||||
static MethodDeclaration findMethodForExpression(Expression expression, CompilationUnit cu)
|
||||
{
|
||||
final boolean[] contains = {false};
|
||||
final MethodDeclaration[] methodDeclaration = {null};
|
||||
cu.accept(new VoidVisitorAdapter<Void>()
|
||||
{
|
||||
@Override
|
||||
public void visit(MethodDeclaration n, Void arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
if (!n.isAbstract()/* && !contains[0]*/)
|
||||
{
|
||||
for (Statement statement : n.getBody().get().getStatements())
|
||||
{
|
||||
if (statement.containsWithinRange(expression))
|
||||
{
|
||||
contains[0] = true;
|
||||
methodDeclaration[0] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
if (contains[0])
|
||||
{
|
||||
return methodDeclaration[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
* @param statement The {@code statement} we are looking for
|
||||
* @param cu The {@code CompilationUnit}
|
||||
* @return the constructor that contains the {@code statement}.
|
||||
*/
|
||||
static ConstructorDeclaration findConstructorForStatement(Statement statement, CompilationUnit cu)
|
||||
{
|
||||
final boolean[] contains = {false};
|
||||
final ConstructorDeclaration[] constructorDeclaration = {null};
|
||||
cu.accept(new VoidVisitorAdapter<Void>()
|
||||
{
|
||||
@Override
|
||||
public void visit(ConstructorDeclaration n, Void arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
if (contains[0])
|
||||
return;
|
||||
|
||||
for (Statement statement1 : n.getBody().getStatements())
|
||||
{
|
||||
if (statement1.containsWithinRange(statement))
|
||||
{
|
||||
contains[0] = true;
|
||||
constructorDeclaration[0] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
if (contains[0])
|
||||
{
|
||||
return constructorDeclaration[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
* @param expression The {@code expression} we are looking for
|
||||
* @param cu The {@code CompilationUnit}
|
||||
* @return the constructor that contains the {@code expression}.
|
||||
*/
|
||||
static ConstructorDeclaration findConstructorForExpression(Expression expression, CompilationUnit cu)
|
||||
{
|
||||
final boolean[] contains = {false};
|
||||
final ConstructorDeclaration[] constructorDeclaration = {null};
|
||||
cu.accept(new VoidVisitorAdapter<Void>()
|
||||
{
|
||||
@Override
|
||||
public void visit(ConstructorDeclaration n, Void arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
if (contains[0])
|
||||
return;
|
||||
|
||||
for (Statement statement1 : n.getBody().getStatements())
|
||||
{
|
||||
if (statement1.containsWithinRange(expression))
|
||||
{
|
||||
contains[0] = true;
|
||||
constructorDeclaration[0] = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
if (contains[0])
|
||||
{
|
||||
return constructorDeclaration[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
* @param statement The {@code statement} we are looking for
|
||||
* @param cu The {@code CompilationUnit}
|
||||
* @return the initializer that contains the {@code statement}.
|
||||
*/
|
||||
static InitializerDeclaration findInitializerForStatement(Statement statement, CompilationUnit cu)
|
||||
{
|
||||
final boolean[] contains = {false};
|
||||
final InitializerDeclaration[] initializerDeclaration = {null};
|
||||
cu.accept(new VoidVisitorAdapter<Void>()
|
||||
{
|
||||
@Override
|
||||
public void visit(InitializerDeclaration n, Void arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
if (contains[0])
|
||||
return;
|
||||
|
||||
for (Statement statement : n.getBody().getStatements())
|
||||
{
|
||||
if (statement.containsWithinRange(statement))
|
||||
{
|
||||
contains[0] = true;
|
||||
initializerDeclaration[0] = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
if (contains[0])
|
||||
{
|
||||
return initializerDeclaration[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
* @param expression The {@code expression} we are looking for
|
||||
* @param cu The {@code CompilationUnit}
|
||||
* @return the initializer that contains the {@code expression}.
|
||||
*/
|
||||
static InitializerDeclaration findInitializerForExpression(Expression expression, CompilationUnit cu)
|
||||
{
|
||||
final boolean[] contains = {false};
|
||||
final InitializerDeclaration[] initializerDeclaration = {null};
|
||||
cu.accept(new VoidVisitorAdapter<Void>()
|
||||
{
|
||||
@Override
|
||||
public void visit(InitializerDeclaration n, Void arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
if (contains[0])
|
||||
return;
|
||||
|
||||
for (Statement statement : n.getBody().getStatements())
|
||||
{
|
||||
if (statement.containsWithinRange(expression))
|
||||
{
|
||||
contains[0] = true;
|
||||
initializerDeclaration[0] = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
if (contains[0])
|
||||
{
|
||||
return initializerDeclaration[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user