All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.tomassetti.symbolsolver.javaparsermodel.contexts.CompilationUnitContext Maven / Gradle / Ivy

The newest version!
package me.tomassetti.symbolsolver.javaparsermodel.contexts;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.expr.QualifiedNameExpr;
import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
import me.tomassetti.symbolsolver.model.resolution.SymbolReference;
import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
import me.tomassetti.symbolsolver.model.usages.typesystem.Type;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import me.tomassetti.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
import me.tomassetti.symbolsolver.resolution.MethodResolutionLogic;
import me.tomassetti.symbolsolver.resolution.SymbolSolver;

import java.util.List;


public class CompilationUnitContext extends AbstractJavaParserContext {

    public CompilationUnitContext(CompilationUnit wrappedNode, TypeSolver typeSolver) {
        super(wrappedNode, typeSolver);
    }

    private static boolean isQualifiedName(String name) {
        return name.contains(".");
    }

    @Override
    public SymbolReference solveSymbol(String name, TypeSolver typeSolver) {

        // solve absolute references
        String itName = name;
        while (itName.contains(".")) {
            String typeName = getType(itName);
            String memberName = getMember(itName);
            SymbolReference type = this.solveType(typeName, typeSolver);
            if (type.isSolved()) {
                return new SymbolSolver(typeSolver).solveSymbolInType(type.getCorrespondingDeclaration(), memberName);
            } else {
                itName = typeName;
            }
        }

        // Look among statically imported values
        if (wrappedNode.getImports() != null) {
            for (ImportDeclaration importDecl : wrappedNode.getImports()) {
                if (importDecl.isStatic()) {
                    if (importDecl.isAsterisk()) {
                        if (importDecl.getName() instanceof QualifiedNameExpr) {
                            String qName = importDecl.getName().toString();
                            me.tomassetti.symbolsolver.model.declarations.TypeDeclaration importedType = typeSolver.solveType(qName);
                            SymbolReference ref = new SymbolSolver(typeSolver).solveSymbolInType(importedType, name);
                            if (ref.isSolved()) {
                                return ref;
                            }
                        } else {
                            throw new UnsupportedOperationException("B");
                        }
                    } else {
                        if (importDecl.getName() instanceof QualifiedNameExpr) {
                            String qName = importDecl.getName().toString();
                            // split in field/method name and type name
                            String typeName = getType(qName);
                            String memberName = getMember(qName);

                            if (memberName.equals(name)) {
                                me.tomassetti.symbolsolver.model.declarations.TypeDeclaration importedType = typeSolver.solveType(typeName);
                                return new SymbolSolver(typeSolver).solveSymbolInType(importedType, memberName);
                            }
                        } else {
                            throw new UnsupportedOperationException("C");
                        }
                    }
                }
            }
        }

        return SymbolReference.unsolved(ValueDeclaration.class);
    }

    private String getType(String qName) {
        int index = qName.lastIndexOf('.');
        if (index == -1) {
            throw new UnsupportedOperationException();
        }
        String typeName = qName.substring(0, index);
        return typeName;
    }

    private String getMember(String qName) {
        int index = qName.lastIndexOf('.');
        if (index == -1) {
            throw new UnsupportedOperationException();
        }
        String memberName = qName.substring(index + 1);
        return memberName;
    }

    @Override
    public SymbolReference solveType(String name, TypeSolver typeSolver) {
        if (wrappedNode.getTypes() != null) {
            for (TypeDeclaration type : wrappedNode.getTypes()) {
                if (type.getName().equals(name)) {
                    if (type instanceof ClassOrInterfaceDeclaration) {
                        if (((ClassOrInterfaceDeclaration) type).isInterface()) {
                            return SymbolReference.solved(new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) type, typeSolver));
                        } else {
                            return SymbolReference.solved(new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) type, typeSolver));
                        }
                    } else {
                        throw new UnsupportedOperationException();
                    }
                }
            }
        }

        if (wrappedNode.getImports() != null) {
            for (ImportDeclaration importDecl : wrappedNode.getImports()) {
                if (!importDecl.isStatic()) {
                    if (!importDecl.isAsterisk()) {
                        if (importDecl.getName() instanceof QualifiedNameExpr) {
                            String qName = importDecl.getName().toString();
                            if (qName.equals(name) || qName.endsWith("." + name)) {
                                SymbolReference ref = typeSolver.tryToSolveType(qName);
                                if (ref.isSolved()) {
                                    return ref;
                                }
                            }
                        } else {
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        String qName = importDecl.getName().toString() + "." + name;
                        SymbolReference ref = typeSolver.tryToSolveType(qName);
                        if (ref.isSolved()) {
                            return ref;
                        }
                    }
                }
            }
        }

        // Look in current package
        if (this.wrappedNode.getPackage() != null) {
            String qName = this.wrappedNode.getPackage().getName().toString() + "." + name;
            SymbolReference ref = typeSolver.tryToSolveType(qName);
            if (ref.isSolved()) {
                return ref;
            }
        }

        // Look in the java.lang package
        SymbolReference ref = typeSolver.tryToSolveType("java.lang." + name);
        if (ref.isSolved()) {
            return ref;
        }

        // DO NOT look for absolute name if this name is not qualified: you cannot import classes from the default package
        if (isQualifiedName(name)) {
            return typeSolver.tryToSolveType(name);
        } else {
            return SymbolReference.unsolved(me.tomassetti.symbolsolver.model.declarations.TypeDeclaration.class);
        }
    }

    @Override
    public SymbolReference solveMethod(String name, List argumentsTypes, TypeSolver typeSolver) {
        if (wrappedNode.getImports() != null) {
            for (ImportDeclaration importDecl : wrappedNode.getImports()) {
                if (importDecl.isStatic()) {
                    if (importDecl.isAsterisk()) {
                        if (importDecl.getName() instanceof QualifiedNameExpr) {
                            String qName = importDecl.getName().toString();
                            me.tomassetti.symbolsolver.model.declarations.TypeDeclaration ref = typeSolver.solveType(qName);
                            SymbolReference method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, typeSolver);
                            if (method.isSolved()) {
                                return method;
                            }
                        } else {
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (importDecl.getName() instanceof QualifiedNameExpr) {
                            String qName = importDecl.getName().toString();
                            if (qName.equals(name) || qName.endsWith("." + name)) {
                                String typeName = getType(qName);
                                me.tomassetti.symbolsolver.model.declarations.TypeDeclaration ref = typeSolver.solveType(typeName);
                                SymbolReference method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, typeSolver);
                                if (method.isSolved()) {
                                    return method;
                                }
                            }
                        } else {
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            }
        }
        return SymbolReference.unsolved(MethodDeclaration.class);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy