Search in sources :

Example 1 with ClassName

use of meghanada.utils.ClassName 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);
    }
}
Also used : ClassName(meghanada.utils.ClassName) VariableTree(com.sun.source.tree.VariableTree) LineMap(com.sun.source.tree.LineMap) ArrayList(java.util.ArrayList) Map(java.util.Map) Objects.isNull(java.util.Objects.isNull) StreamSupport(java.util.stream.StreamSupport) URI(java.net.URI) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Name(javax.lang.model.element.Name) ElementKind(javax.lang.model.element.ElementKind) ExpressionTree(com.sun.source.tree.ExpressionTree) ClassIndex(meghanada.reflect.ClassIndex) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Symbol(com.sun.tools.javac.code.Symbol) JCDiagnostic(com.sun.tools.javac.util.JCDiagnostic) Set(java.util.Set) IOException(java.io.IOException) CachedASMReflector(meghanada.reflect.asm.CachedASMReflector) JCTree(com.sun.tools.javac.tree.JCTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) EntryMessage(org.apache.logging.log4j.message.EntryMessage) List(com.sun.tools.javac.util.List) File(java.io.File) UncheckedIOException(java.io.UncheckedIOException) Stream(java.util.stream.Stream) Logger(org.apache.logging.log4j.Logger) ClassNameUtils(meghanada.utils.ClassNameUtils) EndPosTable(com.sun.tools.javac.tree.EndPosTable) Optional(java.util.Optional) Objects.nonNull(java.util.Objects.nonNull) LogManager(org.apache.logging.log4j.LogManager) Type(com.sun.tools.javac.code.Type) Joiner(com.google.common.base.Joiner) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Symbol(com.sun.tools.javac.code.Symbol) JCTree(com.sun.tools.javac.tree.JCTree) Type(com.sun.tools.javac.code.Type) EndPosTable(com.sun.tools.javac.tree.EndPosTable)

Example 2 with ClassName

use of meghanada.utils.ClassName 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);
    });
}
Also used : JCTree(com.sun.tools.javac.tree.JCTree) Type(com.sun.tools.javac.code.Type) ClassName(meghanada.utils.ClassName) EndPosTable(com.sun.tools.javac.tree.EndPosTable)

Example 3 with ClassName

use of meghanada.utils.ClassName in project meghanada-server by mopemope.

the class CachedASMReflector method reflect.

public List<MemberDescriptor> reflect(final String className) {
    final ClassName cn = new ClassName(className);
    // check type parameter
    final String classWithoutTP = cn.getName();
    final GlobalCache globalCache = GlobalCache.getInstance();
    try {
        final List<MemberDescriptor> members = new ArrayList<>(16);
        List<MemberDescriptor> list = globalCache.getMemberDescriptors(classWithoutTP);
        for (final MemberDescriptor md : list) {
            members.add(md.clone());
        }
        if (cn.hasTypeParameter()) {
            return this.replaceMembers(classWithoutTP, className, members);
        }
        return members;
    } catch (ExecutionException e) {
        throw new UncheckedExecutionException(e);
    }
}
Also used : GlobalCache(meghanada.cache.GlobalCache) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) MemberDescriptor(meghanada.reflect.MemberDescriptor) ClassName(meghanada.utils.ClassName) ArrayList(java.util.ArrayList) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) ExecutionException(java.util.concurrent.ExecutionException)

Example 4 with ClassName

use of meghanada.utils.ClassName in project meghanada-server by mopemope.

the class MemberCacheLoader method load.

@Override
public List<MemberDescriptor> load(final String className) throws IOException {
    final ClassName cn = new ClassName(className);
    final String fqcn = cn.getName();
    final String projectRoot = Config.getProjectRoot();
    File classFile = MemberCacheLoader.getClassFile(fqcn);
    if (isNull(classFile)) {
        // try inner class
        classFile = MemberCacheLoader.getClassFile(ClassNameUtils.replaceInnerMark(fqcn));
        if (isNull(classFile)) {
            log.debug("Missing FQCN:{}'s file is null", fqcn);
            return Collections.emptyList();
        }
    }
    String classFilePath = classFile.getPath();
    boolean isMyProject = classFilePath.startsWith(projectRoot);
    if (!isMyProject) {
        final Stopwatch stopwatch = Stopwatch.createStarted();
        final List<MemberDescriptor> members = loadFromReflector(fqcn);
        log.trace("load fqcn:{} elapsed:{}", fqcn, stopwatch.stop());
        if (!members.isEmpty()) {
            storeMembers(fqcn, members);
            return members;
        }
    }
    @SuppressWarnings("unchecked") final List<MemberDescriptor> cachedResult = MemberCacheLoader.getCachedMemberDescriptors(fqcn);
    if (nonNull(cachedResult)) {
        return cachedResult;
    }
    final Stopwatch stopwatch = Stopwatch.createStarted();
    final List<MemberDescriptor> members = loadFromReflector(fqcn);
    log.trace("load fqcn:{} elapsed:{}", fqcn, stopwatch.stop());
    storeMembers(fqcn, members);
    return members;
}
Also used : MemberDescriptor(meghanada.reflect.MemberDescriptor) ClassName(meghanada.utils.ClassName) Stopwatch(com.google.common.base.Stopwatch) File(java.io.File)

Aggregations

ClassName (meghanada.utils.ClassName)4 Type (com.sun.tools.javac.code.Type)2 EndPosTable (com.sun.tools.javac.tree.EndPosTable)2 JCTree (com.sun.tools.javac.tree.JCTree)2 File (java.io.File)2 ArrayList (java.util.ArrayList)2 MemberDescriptor (meghanada.reflect.MemberDescriptor)2 Joiner (com.google.common.base.Joiner)1 Stopwatch (com.google.common.base.Stopwatch)1 UncheckedExecutionException (com.google.common.util.concurrent.UncheckedExecutionException)1 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)1 ExpressionTree (com.sun.source.tree.ExpressionTree)1 ImportTree (com.sun.source.tree.ImportTree)1 LineMap (com.sun.source.tree.LineMap)1 Tree (com.sun.source.tree.Tree)1 VariableTree (com.sun.source.tree.VariableTree)1 Symbol (com.sun.tools.javac.code.Symbol)1 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)1 JCDiagnostic (com.sun.tools.javac.util.JCDiagnostic)1 List (com.sun.tools.javac.util.List)1