Search in sources :

Example 11 with MemberDescriptor

use of meghanada.reflect.MemberDescriptor in project meghanada-server by mopemope.

the class DeclarationSearcher method searchMethodCall.

private static Optional<Declaration> searchMethodCall(final Source source, final Integer line, final Integer col, final String symbol) {
    final EntryMessage entryMessage = log.traceEntry("line={} col={} symbol={}", line, col, symbol);
    final Optional<MethodCall> methodCall = source.getMethodCall(line, col, true);
    final Optional<Declaration> result = methodCall.map(mc -> {
        final String methodName = mc.name;
        final List<String> arguments = mc.getArguments();
        final String declaringClass = mc.declaringClass;
        if (declaringClass == null) {
            return null;
        }
        final CachedASMReflector reflector = CachedASMReflector.getInstance();
        final MemberDescriptor method = searchMethod(declaringClass, methodName, arguments).orElseGet(() -> searchConstructor(declaringClass, arguments).orElse(null));
        String declaration;
        if (method != null) {
            declaration = method.getDeclaration();
        } else {
            final String args = Joiner.on(", ").join(arguments);
            declaration = mc.returnType + ' ' + methodName + '(' + args + ')';
        }
        String scope = mc.scope;
        if (scope != null && !scope.isEmpty()) {
            scope = scope + '.' + symbol;
        } else {
            scope = symbol;
        }
        return new Declaration(scope.trim(), declaration, Declaration.Type.METHOD, mc.argumentIndex);
    });
    log.traceExit(entryMessage);
    return result;
}
Also used : CachedASMReflector(meghanada.reflect.asm.CachedASMReflector) MemberDescriptor(meghanada.reflect.MemberDescriptor) EntryMessage(org.apache.logging.log4j.message.EntryMessage) MethodCall(meghanada.analyze.MethodCall)

Example 12 with MemberDescriptor

use of meghanada.reflect.MemberDescriptor in project meghanada-server by mopemope.

the class MemberCacheLoader method loadFromReflector.

private List<MemberDescriptor> loadFromReflector(String fqcn) {
    final String initName = ClassNameUtils.getSimpleName(fqcn);
    final ASMReflector asmReflector = ASMReflector.getInstance();
    Map<String, ClassIndex> index = CachedASMReflector.getInstance().getGlobalClassIndex();
    final InheritanceInfo info = asmReflector.getReflectInfo(index, fqcn);
    final List<MemberDescriptor> result = asmReflector.reflectAll(info);
    return result.stream().filter(md -> {
        if (md.matchType(CandidateUnit.MemberType.CONSTRUCTOR)) {
            final String name = ClassNameUtils.getSimpleName(md.getName());
            return name.equals(initName);
        }
        return true;
    }).collect(Collectors.toList());
}
Also used : ClassName(meghanada.utils.ClassName) Stopwatch(com.google.common.base.Stopwatch) FunctionUtils.wrapIOConsumer(meghanada.utils.FunctionUtils.wrapIOConsumer) InheritanceInfo(meghanada.reflect.asm.InheritanceInfo) Map(java.util.Map) CandidateUnit(meghanada.reflect.CandidateUnit) Objects.isNull(java.util.Objects.isNull) FunctionUtils.wrapIO(meghanada.utils.FunctionUtils.wrapIO) RemovalNotification(com.google.common.cache.RemovalNotification) ClassIndex(meghanada.reflect.ClassIndex) IOException(java.io.IOException) ProjectDatabaseHelper(meghanada.store.ProjectDatabaseHelper) CachedASMReflector(meghanada.reflect.asm.CachedASMReflector) Collectors(java.util.stream.Collectors) File(java.io.File) CacheLoader(com.google.common.cache.CacheLoader) MemberDescriptor(meghanada.reflect.MemberDescriptor) List(java.util.List) Logger(org.apache.logging.log4j.Logger) RemovalCause(com.google.common.cache.RemovalCause) ClassNameUtils(meghanada.utils.ClassNameUtils) Optional(java.util.Optional) RemovalListener(com.google.common.cache.RemovalListener) ASMReflector(meghanada.reflect.asm.ASMReflector) Objects.nonNull(java.util.Objects.nonNull) Collections(java.util.Collections) Config(meghanada.config.Config) LogManager(org.apache.logging.log4j.LogManager) ClassIndex(meghanada.reflect.ClassIndex) InheritanceInfo(meghanada.reflect.asm.InheritanceInfo) MemberDescriptor(meghanada.reflect.MemberDescriptor) CachedASMReflector(meghanada.reflect.asm.CachedASMReflector) ASMReflector(meghanada.reflect.asm.ASMReflector)

Example 13 with MemberDescriptor

use of meghanada.reflect.MemberDescriptor in project meghanada-server by mopemope.

the class JavaCompletion method completionSymbols.

private static Collection<? extends CandidateUnit> completionSymbols(Source source, int line, String prefix) {
    Set<CandidateUnit> result = new HashSet<>(32);
    // prefix search
    log.debug("Search variables prefix:{} line:{}", prefix, line);
    Optional<TypeScope> typeScope = source.getTypeScope(line);
    if (!typeScope.isPresent()) {
        return result;
    }
    String fqcn = typeScope.get().getFQCN();
    // add this member
    for (MemberDescriptor c : JavaCompletion.reflectSelf(fqcn, true, prefix)) {
        if (c.getName().startsWith(prefix)) {
            result.add(c);
        }
    }
    if (fqcn.contains(ClassNameUtils.INNER_MARK)) {
        // add parent
        String parentClass = fqcn;
        while (true) {
            int i = parentClass.lastIndexOf('$');
            if (i < 0) {
                break;
            }
            parentClass = parentClass.substring(0, i);
            for (MemberDescriptor c : JavaCompletion.reflectSelf(parentClass, true, prefix)) {
                if (c.getName().startsWith(prefix)) {
                    result.add(c);
                }
            }
        }
    }
    log.debug("self fqcn:{}", fqcn);
    Map<String, Variable> symbols = source.getDeclaratorMap(line);
    log.debug("search variables size:{} result:{}", symbols.size(), symbols);
    for (Map.Entry<String, Variable> e : symbols.entrySet()) {
        String k = e.getKey();
        Variable v = e.getValue();
        log.debug("check variable name:{}", k);
        if (k.startsWith(prefix)) {
            log.debug("match variable name:{}", k);
            if (!v.isField) {
                result.add(v.toCandidateUnit());
            }
        }
    }
    // import
    for (Map.Entry<String, String> e : source.getImportedClassMap().entrySet()) {
        String k = e.getKey();
        String v = e.getValue();
        if (k.startsWith(prefix)) {
            result.add(ClassIndex.createClass(v));
        }
    }
    // static import
    for (Map.Entry<String, String> e : source.staticImportClass.entrySet()) {
        String methodName = e.getKey();
        String clazz = e.getValue();
        for (MemberDescriptor md : JavaCompletion.reflectWithFQCN(clazz, methodName)) {
            if (md.getName().equals(methodName)) {
                result.add(md);
            }
        }
    }
    // Add class
    if (Character.isUpperCase(prefix.charAt(0))) {
        // completion
        CachedASMReflector reflector = CachedASMReflector.getInstance();
        boolean fuzzySearch = Config.load().useClassFuzzySearch();
        if (fuzzySearch) {
            result.addAll(reflector.fuzzySearchClasses(prefix.toLowerCase()));
        } else {
            result.addAll(reflector.searchClasses(prefix.toLowerCase()));
        }
    }
    List<CandidateUnit> list = new ArrayList<>(result);
    list.sort(comparing(source, prefix));
    return list;
}
Also used : CachedASMReflector(meghanada.reflect.asm.CachedASMReflector) Variable(meghanada.analyze.Variable) MemberDescriptor(meghanada.reflect.MemberDescriptor) ArrayList(java.util.ArrayList) TypeScope(meghanada.analyze.TypeScope) CandidateUnit(meghanada.reflect.CandidateUnit) Map(java.util.Map) HashSet(java.util.HashSet)

Example 14 with MemberDescriptor

use of meghanada.reflect.MemberDescriptor in project meghanada-server by mopemope.

the class JavaCompletion method completionFieldsOrMethods.

private static Collection<? extends CandidateUnit> completionFieldsOrMethods(final Source source, final int line, final String var, final String target) {
    // completionAt methods or fields
    if (var.equals("this")) {
        return JavaCompletion.completionThis(source, line, target);
    }
    if (var.equals("super")) {
        return JavaCompletion.completionSuper(source, line, target);
    }
    log.debug("search '{}' field or method", var);
    String ownPackage = source.getPackageName();
    final Set<CandidateUnit> res = new HashSet<>(32);
    {
        // completion static method
        String fqcn = source.getImportedClassFQCN(var, null);
        if (nonNull(fqcn)) {
            if (!fqcn.contains(".") && !ownPackage.isEmpty()) {
                fqcn = ownPackage + '.' + fqcn;
            }
            final Collection<? extends CandidateUnit> result = JavaCompletion.reflect(ownPackage, fqcn, true, false, target);
            res.addAll(result);
            // add inner class
            final Collection<? extends CandidateUnit> inners = CachedASMReflector.getInstance().searchInnerClasses(fqcn);
            res.addAll(inners);
            if (!res.isEmpty()) {
                return res;
            }
        }
    }
    {
        final Map<String, Variable> symbols = source.getDeclaratorMap(line);
        final Variable variable = symbols.get(var);
        if (nonNull(variable)) {
            // get data from reflector
            String fqcn = variable.fqcn;
            if (!fqcn.contains(".")) {
                fqcn = ownPackage + '.' + fqcn;
            }
            final Collection<? extends CandidateUnit> reflect = JavaCompletion.reflect(ownPackage, fqcn, target);
            res.addAll(reflect);
        }
    }
    {
        for (final ClassScope cs : source.getClassScopes()) {
            final String fqcn = cs.getFQCN();
            final Optional<MemberDescriptor> fieldResult = JavaCompletion.reflectSelf(fqcn, true, target).stream().filter(c -> c instanceof FieldDescriptor && c.getName().equals(var)).findFirst();
            if (fieldResult.isPresent()) {
                final MemberDescriptor memberDescriptor = fieldResult.orElse(null);
                final String returnType = memberDescriptor.getRawReturnType();
                final Collection<? extends CandidateUnit> reflect = reflect(ownPackage, returnType, target);
                res.addAll(reflect);
            }
        }
    }
    {
        // java.lang
        final String fqcn = "java.lang." + var;
        final Collection<? extends CandidateUnit> result = JavaCompletion.reflect(ownPackage, fqcn, true, false, target);
        res.addAll(result);
    }
    {
        String fqcn = var;
        if (!ownPackage.isEmpty()) {
            fqcn = ownPackage + '.' + var;
        }
        final Collection<? extends CandidateUnit> reflectResults = JavaCompletion.reflect(ownPackage, fqcn, true, false, target);
        res.addAll(reflectResults);
        final CachedASMReflector reflector = CachedASMReflector.getInstance();
        if (reflector.containsFQCN(fqcn)) {
            final Collection<? extends CandidateUnit> inners = reflector.searchInnerClasses(fqcn);
            res.addAll(inners);
        }
    }
    if (line > 0 && res.isEmpty()) {
        List<MethodCall> calls = source.getMethodCall(line - 1);
        long lastCol = 0;
        String lastFQCN = null;
        for (MethodCall call : calls) {
            long col = call.nameRange.begin.column;
            String name = ClassNameUtils.getSimpleName(call.name);
            if (name.equals(var) && col > lastCol) {
                lastFQCN = call.returnType;
                lastCol = col;
            }
        }
        if (nonNull(lastFQCN)) {
            res.addAll(reflectWithFQCN(lastFQCN, ""));
        }
    }
    return res;
}
Also used : CachedASMReflector(meghanada.reflect.asm.CachedASMReflector) Variable(meghanada.analyze.Variable) Optional(java.util.Optional) MemberDescriptor(meghanada.reflect.MemberDescriptor) MethodCall(meghanada.analyze.MethodCall) ClassScope(meghanada.analyze.ClassScope) FieldDescriptor(meghanada.reflect.FieldDescriptor) Collection(java.util.Collection) CandidateUnit(meghanada.reflect.CandidateUnit) Map(java.util.Map) HashSet(java.util.HashSet)

Example 15 with MemberDescriptor

use of meghanada.reflect.MemberDescriptor in project meghanada-server by mopemope.

the class ASMReflector method getMembersFromClassFile.

private List<MemberDescriptor> getMembersFromClassFile(final File parent, final File file, String fqcn, boolean includeSuper) throws IOException {
    try (final InputStream in = new FileInputStream(file)) {
        final ClassReader classReader = new ClassReader(in);
        final String className = ClassNameUtils.replaceSlash(classReader.getClassName());
        if (className.equals(fqcn)) {
            final ClassAnalyzeVisitor cv = new ClassAnalyzeVisitor(className, className, false, true);
            classReader.accept(cv, 0);
            final List<MemberDescriptor> members = cv.getMembers();
            if (includeSuper) {
                readSuperMembers(parent, cv, members);
            }
            return members;
        }
    }
    return null;
}
Also used : MemberDescriptor(meghanada.reflect.MemberDescriptor) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ClassReader(org.objectweb.asm.ClassReader) FileInputStream(java.io.FileInputStream)

Aggregations

MemberDescriptor (meghanada.reflect.MemberDescriptor)26 File (java.io.File)17 Map (java.util.Map)17 ClassIndex (meghanada.reflect.ClassIndex)16 Stopwatch (com.google.common.base.Stopwatch)15 List (java.util.List)15 Config (meghanada.config.Config)15 MethodDescriptor (meghanada.reflect.MethodDescriptor)13 Test (org.junit.Test)13 GradleTestBase (meghanada.GradleTestBase)12 Config.debugIt (meghanada.config.Config.debugIt)12 Config.timeIt (meghanada.config.Config.timeIt)12 AfterClass (org.junit.AfterClass)12 Assert.assertEquals (org.junit.Assert.assertEquals)12 Assert.assertNotNull (org.junit.Assert.assertNotNull)12 BeforeClass (org.junit.BeforeClass)12 CandidateUnit (meghanada.reflect.CandidateUnit)6 CachedASMReflector (meghanada.reflect.asm.CachedASMReflector)5 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4