use of com.sun.tools.javac.tree.EndPosTable in project meghanada-server by mopemope.
the class TreeAnalyzer method analyzeMethodInvocation.
private static void analyzeMethodInvocation(SourceContext context, JCTree.JCMethodInvocation methodInvocation, int preferredPos, int endPos) throws IOException {
Source src = context.getSource();
EndPosTable endPosTable = context.getEndPosTable();
Type returnType = methodInvocation.type;
boolean isParameter = context.isParameter();
int argumentIndex = context.getArgumentIndex();
List<JCTree.JCExpression> argumentExpressions = methodInvocation.getArguments();
java.util.List<String> arguments = getArgumentsType(context, argumentExpressions);
context.setParameter(isParameter);
context.setArgumentIndex(argumentIndex);
JCTree.JCExpression methodSelect = methodInvocation.getMethodSelect();
if (methodSelect instanceof JCTree.JCIdent) {
// super
JCTree.JCIdent ident = (JCTree.JCIdent) methodSelect;
String s = ident.getName().toString();
Symbol sym = ident.sym;
if (nonNull(sym)) {
Symbol owner = sym.owner;
int nameBegin = ident.getStartPosition();
int nameEnd = ident.getEndPosition(endPosTable);
Range nameRange = Range.create(src, nameBegin, nameEnd);
Range range = Range.create(src, nameBegin, endPos);
if (s.equals("super")) {
// call super constructor
if (nonNull(owner) && nonNull(owner.type)) {
String constructor = owner.flatName().toString();
MethodCall mc = new MethodCall(s, constructor, nameBegin, nameRange, range);
getTypeString(src, owner.type).ifPresent(fqcn -> mc.declaringClass = TreeAnalyzer.markFQCN(src, fqcn));
setReturnTypeAndArgType(context, src, owner.type, mc);
src.getCurrentScope().ifPresent(scope -> {
mc.setArguments(arguments);
scope.addMethodCall(mc);
});
}
} else {
MethodCall mc = new MethodCall(s, preferredPos + 1, nameRange, range);
if (nonNull(owner) && nonNull(owner.type)) {
getTypeString(src, owner.type).ifPresent(fqcn -> {
String className = src.staticImportClass.get(s);
if (fqcn.equals(className)) {
// static imported
mc.declaringClass = TreeAnalyzer.markFQCN(src, fqcn, false);
} else {
mc.declaringClass = TreeAnalyzer.markFQCN(src, fqcn);
}
});
setReturnTypeAndArgType(context, src, returnType, mc);
}
src.getCurrentScope().ifPresent(scope -> {
mc.setArguments(arguments);
scope.addMethodCall(mc);
});
}
}
} else if (methodSelect instanceof JCTree.JCFieldAccess) {
JCTree.JCFieldAccess fa = (JCTree.JCFieldAccess) methodSelect;
JCTree.JCExpression expression = fa.getExpression();
String selectScope = expression.toString();
analyzeParsedTree(context, expression);
Type owner = expression.type;
String name = fa.getIdentifier().toString();
int start = preferredPos - name.length();
Range nameRange = Range.create(src, start, preferredPos);
Range range = Range.create(src, start, endPos);
MethodCall methodCall = new MethodCall(selectScope, name, start + 1, nameRange, range);
if (isNull(owner)) {
// call static
if (expression instanceof JCTree.JCIdent) {
JCTree.JCIdent ident = (JCTree.JCIdent) expression;
String nm = ident.getName().toString();
String clazz = src.getImportedClassFQCN(nm, null);
if (nonNull(clazz)) {
methodCall.declaringClass = TreeAnalyzer.markFQCN(src, clazz);
} else {
if (src.isReportUnknown()) {
log.warn("unknown ident class expression={} {} {}", expression, expression.getClass(), src.filePath);
}
}
} else {
if (src.isReportUnknown()) {
log.warn("unknown expression expression={} {}", expression, expression.getClass(), src.filePath);
}
}
} else {
getTypeString(src, owner).ifPresent(fqcn -> {
methodCall.declaringClass = TreeAnalyzer.markFQCN(src, fqcn);
if (expression instanceof JCTree.JCIdent) {
JCTree.JCIdent ident = (JCTree.JCIdent) expression;
int vStart = ident.getStartPosition();
int vEndPos = ident.getEndPosition(context.getEndPosTable());
Range vRange = Range.create(src, vStart, vEndPos);
Variable variable = new Variable(selectScope, ident.pos, vRange);
variable.fqcn = fqcn;
src.getCurrentScope().ifPresent(s -> s.addVariable(variable));
}
});
}
if (isNull(returnType)) {
if (expression instanceof JCTree.JCIdent) {
JCTree.JCIdent ident = (JCTree.JCIdent) expression;
String nm = ident.getName().toString();
String clazz = src.getImportedClassFQCN(nm, null);
if (nonNull(clazz)) {
methodCall.returnType = TreeAnalyzer.markFQCN(src, clazz);
methodCall.argumentIndex = context.getArgumentIndex();
context.setArgumentFQCN(methodCall.returnType);
} else {
if (src.isReportUnknown()) {
log.warn("unknown ident class expression={} {} {}", expression, expression.getClass(), src.filePath);
}
}
} else {
if (src.isReportUnknown()) {
log.warn("unknown expression expression={} {}", expression, expression.getClass(), src.filePath);
}
}
} else {
getTypeString(src, returnType).ifPresent(fqcn -> {
methodCall.returnType = TreeAnalyzer.markFQCN(src, fqcn);
methodCall.argumentIndex = context.getArgumentIndex();
context.setArgumentFQCN(methodCall.returnType);
});
}
src.getCurrentScope().ifPresent(scope -> {
methodCall.setArguments(arguments);
scope.addMethodCall(methodCall);
});
} else {
log.warn("unknown method select:{}", methodSelect);
analyzeParsedTree(context, methodSelect);
}
}
use of com.sun.tools.javac.tree.EndPosTable in project meghanada-server by mopemope.
the class TreeAnalyzer method analyzeCompilationUnitTree.
private static void analyzeCompilationUnitTree(SourceContext context, CompilationUnitTree cut) {
Source src = context.getSource();
log.trace("file={}", src.getFile());
EndPosTable endPosTable = ((JCTree.JCCompilationUnit) cut).endPositions;
context.setEndPosTable(endPosTable);
analyzePackageName(cut, src, endPosTable);
analyzeImports(cut, src, endPosTable);
try {
for (Tree td : cut.getTypeDecls()) {
// start class
if (td instanceof JCTree.JCClassDecl) {
analyzeTopLevelClass(context, (JCTree.JCClassDecl) td);
} else if (td instanceof JCTree.JCSkip) {
// skip
} else if (td instanceof JCTree.JCErroneous) {
// skip erroneous
} else {
log.warn("unknown td={} {}", td, td.getClass());
}
}
} catch (IOException e) {
log.catching(e);
throw new UncheckedIOException(e);
}
}
use of com.sun.tools.javac.tree.EndPosTable in project meghanada-server by mopemope.
the class TreeAnalyzer method analyzeNewClass.
private static void analyzeNewClass(SourceContext context, JCTree.JCNewClass newClass, int preferredPos, int endPos) throws IOException {
Source src = context.getSource();
EndPosTable endPosTable = context.getEndPosTable();
boolean isParameter = context.isParameter();
boolean isArgument = context.isArgument();
int argumentIndex = context.getArgumentIndex();
List<JCTree.JCExpression> argumentExpressions = newClass.getArguments();
java.util.List<String> arguments = getArgumentsType(context, argumentExpressions);
context.setParameter(isParameter);
context.setArgument(isArgument);
context.setArgumentIndex(argumentIndex);
JCTree.JCExpression identifier = newClass.getIdentifier();
String name = identifier.toString();
int start = identifier.getStartPosition();
int end = identifier.getEndPosition(endPosTable);
Range nameRange = Range.create(src, start, end);
Range range = Range.create(src, preferredPos + 4, endPos);
MethodCall methodCall = new MethodCall(name, preferredPos, nameRange, range, true);
Type type = identifier.type;
getTypeString(src, type).ifPresent(fqcn -> {
methodCall.declaringClass = TreeAnalyzer.markFQCN(src, fqcn);
methodCall.returnType = fqcn;
methodCall.argumentIndex = argumentIndex;
context.setArgumentFQCN(fqcn);
});
if (isNull(type) || type instanceof Type.ErrorType) {
// add className to unknown
ClassName className = new ClassName(name);
String simpleName = className.getName();
if (!src.getImportedClassMap().containsKey(simpleName) && !CachedASMReflector.getInstance().getGlobalClassIndex().containsKey(simpleName)) {
src.addUnknown(simpleName);
}
}
JCTree.JCClassDecl classBody = newClass.getClassBody();
analyzeParsedTree(context, classBody);
src.getCurrentScope().ifPresent(scope -> {
if (nonNull(arguments)) {
methodCall.setArguments(arguments);
}
scope.addMethodCall(methodCall);
});
}
use of com.sun.tools.javac.tree.EndPosTable in project error-prone by google.
the class Template method pretty.
protected static Pretty pretty(Context context, final Writer writer) {
final JCCompilationUnit unit = context.get(JCCompilationUnit.class);
try {
final String unitContents = unit.getSourceFile().getCharContent(false).toString();
return new Pretty(writer, true) {
{
// Work-around for b/22196513
width = 0;
}
@Override
public void visitAnnotation(JCAnnotation anno) {
if (anno.getArguments().isEmpty()) {
try {
print("@");
printExpr(anno.annotationType);
} catch (IOException e) {
// the supertype swallows exceptions too
throw new RuntimeException(e);
}
} else {
super.visitAnnotation(anno);
}
}
@Override
public void printExpr(JCTree tree, int prec) throws IOException {
EndPosTable endPositions = unit.endPositions;
/*
* Modifiers, and specifically flags like final, appear to just need weird special
* handling.
*
* Note: we can't use {@code TreeInfo.getEndPos()} or {@code JCTree.getEndPosition()}
* here, because they will return the end position of an enclosing AST node for trees
* whose real end positions aren't stored.
*/
int endPos = endPositions.getEndPos(tree);
boolean hasRealEndPosition = endPos != Position.NOPOS;
if (tree.getKind() != Kind.MODIFIERS && hasRealEndPosition) {
writer.append(unitContents.substring(tree.getStartPosition(), endPos));
} else {
super.printExpr(tree, prec);
}
}
@Override
public void visitApply(JCMethodInvocation tree) {
JCExpression select = tree.getMethodSelect();
if (select != null && select.toString().equals("Refaster.emitCommentBefore")) {
String commentLiteral = (String) ((JCLiteral) tree.getArguments().get(0)).getValue();
JCExpression expr = tree.getArguments().get(1);
try {
print("/* " + commentLiteral + " */ ");
} catch (IOException e) {
throw new RuntimeException(e);
}
expr.accept(this);
} else {
super.visitApply(tree);
}
}
@Override
public void printStat(JCTree tree) throws IOException {
if (tree instanceof JCExpressionStatement && ((JCExpressionStatement) tree).getExpression() instanceof JCMethodInvocation) {
JCMethodInvocation invocation = (JCMethodInvocation) ((JCExpressionStatement) tree).getExpression();
JCExpression select = invocation.getMethodSelect();
if (select != null && select.toString().equals("Refaster.emitComment")) {
String commentLiteral = (String) ((JCLiteral) invocation.getArguments().get(0)).getValue();
print("// " + commentLiteral);
return;
}
}
super.printStat(tree);
}
@Override
public void visitTry(JCTry tree) {
if (tree.getResources().isEmpty()) {
super.visitTry(tree);
return;
}
try {
print("try (");
boolean first = true;
for (JCTree resource : tree.getResources()) {
if (!first) {
print(";");
println();
}
printExpr(resource);
first = false;
}
print(")");
printStat(tree.body);
for (JCCatch catchStmt : tree.getCatches()) {
printStat(catchStmt);
}
if (tree.getFinallyBlock() != null) {
print(" finally ");
printStat(tree.getFinallyBlock());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of com.sun.tools.javac.tree.EndPosTable in project meghanada-server by mopemope.
the class TreeAnalyzer method analyzeParsedTree.
private static void analyzeParsedTree(SourceContext context, @Nullable JCTree tree) throws IOException {
if (isNull(tree)) {
return;
}
JCDiagnostic.DiagnosticPosition pos = tree.pos();
EndPosTable endPosTable = context.getEndPosTable();
int startPos = pos.getStartPosition();
int preferredPos = pos.getPreferredPosition();
int endPos = pos.getEndPosition(endPosTable);
EntryMessage em = log.traceEntry("# class={} preferredPos={} endPos={} expr='{}'", tree.getClass().getSimpleName(), preferredPos, endPos, tree);
if (endPos == -1 && !(tree instanceof JCTree.JCAssign) && !(tree instanceof JCTree.JCIdent)) {
// skip
log.trace("skip expr={}", tree);
log.traceExit(em);
return;
}
if (tree instanceof JCTree.JCVariableDecl) {
analyzeVariableDecl(context, (JCTree.JCVariableDecl) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCTypeCast) {
JCTree.JCTypeCast cast = (JCTree.JCTypeCast) tree;
JCTree.JCExpression expression = cast.getExpression();
analyzeParsedTree(context, expression);
if (context.isArgument()) {
getExpressionType(context.getSource(), cast).ifPresent(context::setArgumentFQCN);
}
} else if (tree instanceof JCTree.JCMethodDecl) {
analyzeMethodDecl(context, (JCTree.JCMethodDecl) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCClassDecl) {
analyzeInnerClassDecl(context, (JCTree.JCClassDecl) tree, startPos, endPos);
} else if (tree instanceof JCTree.JCBlock) {
JCTree.JCBlock block = (JCTree.JCBlock) tree;
int argumentIndex = context.getArgumentIndex();
context.setArgumentIndex(-1);
analyzeSimpleStatements(context, block.getStatements());
context.setArgumentIndex(argumentIndex);
} else if (tree instanceof JCTree.JCFieldAccess) {
analyzeFieldAccess(context, (JCTree.JCFieldAccess) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCArrayAccess) {
JCTree.JCArrayAccess arrayAccess = (JCTree.JCArrayAccess) tree;
analyzeParsedTree(context, arrayAccess.getExpression());
analyzeParsedTree(context, arrayAccess.getIndex());
} else if (tree instanceof JCTree.JCExpressionStatement) {
analyzeExpressionStatement(context, (JCTree.JCExpressionStatement) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCLiteral) {
analyzeLiteral(context, (JCTree.JCLiteral) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCIdent) {
analyzeIdent(context, (JCTree.JCIdent) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCContinue) {
// skip
} else if (tree instanceof JCTree.JCBreak) {
// skip
} else if (tree instanceof JCTree.JCUnary) {
JCTree.JCUnary unary = (JCTree.JCUnary) tree;
JCTree.JCExpression expression = unary.getExpression();
analyzeParsedTree(context, expression);
} else if (tree instanceof JCTree.JCSwitch) {
analyzeSwitch(context, (JCTree.JCSwitch) tree);
} else if (tree instanceof JCTree.JCReturn) {
JCTree.JCReturn ret = (JCTree.JCReturn) tree;
JCTree.JCExpression expression = ret.getExpression();
analyzeParsedTree(context, ret.getExpression());
} else if (tree instanceof JCTree.JCForLoop) {
analyzeForLoop(context, (JCTree.JCForLoop) tree);
} else if (tree instanceof JCTree.JCEnhancedForLoop) {
analyzeEnhancedForLoop(context, (JCTree.JCEnhancedForLoop) tree);
} else if (tree instanceof JCTree.JCTry) {
analyzeTry(context, (JCTree.JCTry) tree);
} else if (tree instanceof JCTree.JCIf) {
JCTree.JCIf ifExpr = (JCTree.JCIf) tree;
JCTree.JCExpression condition = ifExpr.getCondition();
JCTree.JCStatement thenStatement = ifExpr.getThenStatement();
JCTree.JCStatement elseStatement = ifExpr.getElseStatement();
analyzeParsedTree(context, condition);
analyzeParsedTree(context, thenStatement);
analyzeParsedTree(context, elseStatement);
} else if (tree instanceof JCTree.JCParens) {
JCTree.JCParens parens = (JCTree.JCParens) tree;
JCTree.JCExpression expression = parens.getExpression();
analyzeParsedTree(context, expression);
} else if (tree instanceof JCTree.JCNewClass) {
analyzeNewClass(context, (JCTree.JCNewClass) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCBinary) {
JCTree.JCBinary binary = (JCTree.JCBinary) tree;
JCTree.JCExpression leftOperand = binary.getLeftOperand();
JCTree.JCExpression rightOperand = binary.getRightOperand();
analyzeParsedTree(context, leftOperand);
analyzeParsedTree(context, rightOperand);
} else if (tree instanceof JCTree.JCMethodInvocation) {
analyzeMethodInvocation(context, (JCTree.JCMethodInvocation) tree, preferredPos, endPos);
} else if (tree instanceof JCTree.JCAssign) {
JCTree.JCAssign assign = (JCTree.JCAssign) tree;
JCTree.JCExpression expression = assign.getExpression();
JCTree.JCExpression variable = assign.getVariable();
analyzeParsedTree(context, variable);
analyzeParsedTree(context, expression);
} else if (tree instanceof JCTree.JCNewArray) {
JCTree.JCNewArray newArray = (JCTree.JCNewArray) tree;
JCTree.JCExpression type = newArray.getType();
analyzeParsedTree(context, type);
List<JCTree.JCExpression> initializes = newArray.getInitializers();
analyzeSimpleExpressions(context, initializes);
List<JCTree.JCExpression> dimensions = newArray.getDimensions();
analyzeSimpleExpressions(context, dimensions);
if (nonNull(newArray.type)) {
getTypeString(context.getSource(), newArray.type).ifPresent(context::setArgumentFQCN);
}
} else if (tree instanceof JCTree.JCPrimitiveTypeTree) {
// skip
} else if (tree instanceof JCTree.JCConditional) {
JCTree.JCConditional conditional = (JCTree.JCConditional) tree;
JCTree.JCExpression condition = conditional.getCondition();
analyzeParsedTree(context, condition);
JCTree.JCExpression trueExpression = conditional.getTrueExpression();
analyzeParsedTree(context, trueExpression);
JCTree.JCExpression falseExpression = conditional.getFalseExpression();
analyzeParsedTree(context, falseExpression);
} else if (tree instanceof JCTree.JCLambda) {
analyzeLambda(context, (JCTree.JCLambda) tree);
} else if (tree instanceof JCTree.JCThrow) {
JCTree.JCThrow jcThrow = (JCTree.JCThrow) tree;
JCTree.JCExpression expression = jcThrow.getExpression();
analyzeParsedTree(context, expression);
} else if (tree instanceof JCTree.JCInstanceOf) {
JCTree.JCInstanceOf jcInstanceOf = (JCTree.JCInstanceOf) tree;
JCTree.JCExpression expression = jcInstanceOf.getExpression();
analyzeParsedTree(context, expression);
JCTree typeTree = jcInstanceOf.getType();
analyzeParsedTree(context, typeTree);
} else if (tree instanceof JCTree.JCMemberReference) {
Source src = context.getSource();
JCTree.JCMemberReference memberReference = (JCTree.JCMemberReference) tree;
JCTree.JCExpression expression = memberReference.getQualifierExpression();
com.sun.tools.javac.util.Name name = memberReference.getName();
String methodName = name.toString();
if (nonNull(expression)) {
analyzeParsedTree(context, expression);
Symbol sym = memberReference.sym;
if (nonNull(sym)) {
// method invoke
int start = expression.getEndPosition(endPosTable) + 2;
Range range = Range.create(src, start, start + methodName.length());
String s = memberReference.toString();
MethodCall methodCall = new MethodCall(s, methodName, preferredPos + 1, range, range);
if (sym instanceof Symbol.MethodSymbol) {
Symbol.MethodSymbol methodSymbol = (Symbol.MethodSymbol) sym;
java.util.List<String> arguments = new ArrayList<>(methodSymbol.getParameters().size());
for (VarSymbol varSymbol : methodSymbol.getParameters()) {
arguments.add(varSymbol.asType().toString());
}
methodCall.setArguments(arguments);
}
Symbol owner = sym.owner;
if (nonNull(owner) && nonNull(owner.type)) {
getTypeString(src, owner.type).ifPresent(fqcn -> methodCall.declaringClass = TreeAnalyzer.markFQCN(src, fqcn));
}
if (nonNull(sym.type)) {
getTypeString(src, sym.type).ifPresent(fqcn -> {
methodCall.returnType = TreeAnalyzer.markFQCN(src, fqcn);
// TODO add args
});
}
src.getCurrentScope().ifPresent(scope -> scope.addMethodCall(methodCall));
}
}
} else if (tree instanceof JCTree.JCWhileLoop) {
JCTree.JCWhileLoop whileLoop = (JCTree.JCWhileLoop) tree;
JCTree.JCExpression condition = whileLoop.getCondition();
analyzeParsedTree(context, condition);
JCTree.JCStatement statement = whileLoop.getStatement();
analyzeParsedTree(context, statement);
} else if (tree instanceof JCTree.JCSynchronized) {
JCTree.JCSynchronized jcSynchronized = (JCTree.JCSynchronized) tree;
JCTree.JCExpression expression = jcSynchronized.getExpression();
analyzeParsedTree(context, expression);
JCTree.JCBlock block = jcSynchronized.getBlock();
analyzeParsedTree(context, block);
} else if (tree instanceof JCTree.JCAssert) {
JCTree.JCAssert jcAssert = (JCTree.JCAssert) tree;
JCTree.JCExpression condition = jcAssert.getCondition();
analyzeParsedTree(context, condition);
JCTree.JCExpression detail = jcAssert.getDetail();
analyzeParsedTree(context, detail);
} else if (tree instanceof JCTree.JCArrayTypeTree) {
JCTree.JCArrayTypeTree arrayTypeTree = (JCTree.JCArrayTypeTree) tree;
JCTree type = arrayTypeTree.getType();
analyzeParsedTree(context, type);
} else if (tree instanceof JCTree.JCDoWhileLoop) {
JCTree.JCDoWhileLoop doWhileLoop = (JCTree.JCDoWhileLoop) tree;
JCTree.JCExpression condition = doWhileLoop.getCondition();
analyzeParsedTree(context, condition);
JCTree.JCStatement statement = doWhileLoop.getStatement();
analyzeParsedTree(context, statement);
} else if (tree instanceof JCTree.JCLabeledStatement) {
JCTree.JCLabeledStatement labeledStatement = (JCTree.JCLabeledStatement) tree;
JCTree.JCStatement statement = labeledStatement.getStatement();
analyzeParsedTree(context, statement);
} else if (tree instanceof JCTree.JCTypeApply) {
JCTree.JCTypeApply typeApply = (JCTree.JCTypeApply) tree;
JCTree type = typeApply.getType();
analyzeParsedTree(context, type);
} else if (tree instanceof JCTree.JCAssignOp) {
JCTree.JCAssignOp assignOp = (JCTree.JCAssignOp) tree;
JCTree.JCExpression expression = assignOp.getExpression();
analyzeParsedTree(context, expression);
} else if (tree instanceof JCTree.JCAnnotation) {
JCTree.JCAnnotation annotation = (JCTree.JCAnnotation) tree;
analyzeSimpleExpressions(context, annotation.getArguments());
JCTree annotationType = annotation.getAnnotationType();
analyzeParsedTree(context, annotationType);
} else if (tree instanceof JCTree.JCSkip) {
// skip
} else if (tree instanceof JCTree.JCErroneous) {
// skip error
} else {
Source src = context.getSource();
log.warn("@@ unknown or broken tree class={} expr={} filePath={}", tree.getClass(), tree, src.filePath);
}
log.traceExit(em);
}
Aggregations