Search in sources :

Example 1 with Project

use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.

the class LintClient method getProject.

/**
     * Returns a project for the given directory. This should return the same
     * project for the same directory if called repeatedly.
     *
     * @param dir the directory containing the project
     * @param referenceDir See {@link Project#getReferenceDir()}.
     * @return a project, never null
     */
@NonNull
public Project getProject(@NonNull File dir, @NonNull File referenceDir) {
    if (mDirToProject == null) {
        mDirToProject = new HashMap<File, Project>();
    }
    File canonicalDir = dir;
    try {
        // Attempt to use the canonical handle for the file, in case there
        // are symlinks etc present (since when handling library projects,
        // we also call getCanonicalFile to compute the result of appending
        // relative paths, which can then resolve symlinks and end up with
        // a different prefix)
        canonicalDir = dir.getCanonicalFile();
    } catch (IOException ioe) {
    // pass
    }
    Project project = mDirToProject.get(canonicalDir);
    if (project != null) {
        return project;
    }
    project = createProject(dir, referenceDir);
    mDirToProject.put(canonicalDir, project);
    return project;
}
Also used : Project(com.android.tools.klint.detector.api.Project) IOException(java.io.IOException) File(java.io.File) NonNull(com.android.annotations.NonNull)

Example 2 with Project

use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.

the class LintClient method registerProject.

/**
     * Registers the given project for the given directory. This can
     * be used when projects are initialized outside of the client itself.
     *
     * @param dir the directory of the project, which must be unique
     * @param project the project
     */
public void registerProject(@NonNull File dir, @NonNull Project project) {
    File canonicalDir = dir;
    try {
        // Attempt to use the canonical handle for the file, in case there
        // are symlinks etc present (since when handling library projects,
        // we also call getCanonicalFile to compute the result of appending
        // relative paths, which can then resolve symlinks and end up with
        // a different prefix)
        canonicalDir = dir.getCanonicalFile();
    } catch (IOException ioe) {
    // pass
    }
    if (mDirToProject == null) {
        mDirToProject = new HashMap<File, Project>();
    } else {
        assert !mDirToProject.containsKey(dir) : dir;
    }
    mDirToProject.put(canonicalDir, project);
}
Also used : Project(com.android.tools.klint.detector.api.Project) IOException(java.io.IOException) File(java.io.File)

Example 3 with Project

use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.

the class LintDriver method analyze.

/** Runs the driver to analyze the requested files */
private void analyze() {
    mCanceled = false;
    mScope = mRequest.getScope();
    assert mScope == null || !mScope.contains(Scope.ALL_RESOURCE_FILES) || mScope.contains(Scope.RESOURCE_FILE);
    Collection<Project> projects;
    try {
        projects = mRequest.getProjects();
        if (projects == null) {
            projects = computeProjects(mRequest.getFiles());
        }
    } catch (CircularDependencyException e) {
        mCurrentProject = e.getProject();
        if (mCurrentProject != null) {
            Location location = e.getLocation();
            File file = location != null ? location.getFile() : mCurrentProject.getDir();
            Context context = new Context(this, mCurrentProject, null, file);
            context.report(IssueRegistry.LINT_ERROR, e.getLocation(), e.getMessage());
            mCurrentProject = null;
        }
        return;
    }
    if (projects.isEmpty()) {
        mClient.log(null, "No projects found for %1$s", mRequest.getFiles().toString());
        return;
    }
    if (mCanceled) {
        return;
    }
    registerCustomDetectors(projects);
    if (mScope == null) {
        mScope = Scope.infer(projects);
    }
    fireEvent(EventType.STARTING, null);
    for (Project project : projects) {
        mPhase = 1;
        Project main = mRequest.getMainProject(project);
        // The set of available detectors varies between projects
        computeDetectors(project);
        if (mApplicableDetectors.isEmpty()) {
            // No detectors enabled in this project: skip it
            continue;
        }
        checkProject(project, main);
        if (mCanceled) {
            break;
        }
        runExtraPhases(project, main);
    }
    fireEvent(mCanceled ? EventType.CANCELED : EventType.COMPLETED, null);
}
Also used : ClassContext(com.android.tools.klint.detector.api.ClassContext) XmlContext(com.android.tools.klint.detector.api.XmlContext) JavaContext(com.android.tools.klint.detector.api.JavaContext) ResourceContext(com.android.tools.klint.detector.api.ResourceContext) Context(com.android.tools.klint.detector.api.Context) Project(com.android.tools.klint.detector.api.Project) File(java.io.File) PsiFile(com.intellij.psi.PsiFile) Location(com.android.tools.klint.detector.api.Location)

Example 4 with Project

use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.

the class LintDriver method computeProjects.

private Collection<Project> computeProjects(@NonNull List<File> files) {
    // Compute list of projects
    Map<File, Project> fileToProject = new LinkedHashMap<File, Project>();
    File sharedRoot = null;
    // Ensure that we have absolute paths such that if you lint
    //  "foo bar" in "baz" we can show baz/ as the root
    List<File> absolute = new ArrayList<File>(files.size());
    for (File file : files) {
        absolute.add(file.getAbsoluteFile());
    }
    // Always use absoluteFiles so that we can check the file's getParentFile()
    // which is null if the file is not absolute.
    files = absolute;
    if (files.size() > 1) {
        sharedRoot = LintUtils.getCommonParent(files);
        if (sharedRoot != null && sharedRoot.getParentFile() == null) {
            // "/" ?
            sharedRoot = null;
        }
    }
    for (File file : files) {
        if (file.isDirectory()) {
            File rootDir = sharedRoot;
            if (rootDir == null) {
                rootDir = file;
                if (files.size() > 1) {
                    rootDir = file.getParentFile();
                    if (rootDir == null) {
                        rootDir = file;
                    }
                }
            }
            // hopefully pointing at a project tree that you want to scan recursively.
            if (mClient.isProjectDirectory(file)) {
                registerProjectFile(fileToProject, file, file, rootDir);
                continue;
            } else {
                File parent = file.getParentFile();
                if (parent != null) {
                    if (mClient.isProjectDirectory(parent)) {
                        registerProjectFile(fileToProject, file, parent, parent);
                        continue;
                    } else {
                        parent = parent.getParentFile();
                        if (parent != null && mClient.isProjectDirectory(parent)) {
                            registerProjectFile(fileToProject, file, parent, parent);
                            continue;
                        }
                    }
                }
                // Search downwards for nested projects
                addProjects(file, fileToProject, rootDir);
            }
        } else {
            // Pointed at a file: Search upwards for the containing project
            File parent = file.getParentFile();
            while (parent != null) {
                if (mClient.isProjectDirectory(parent)) {
                    registerProjectFile(fileToProject, file, parent, parent);
                    break;
                }
                parent = parent.getParentFile();
            }
        }
        if (mCanceled) {
            return Collections.emptySet();
        }
    }
    for (Map.Entry<File, Project> entry : fileToProject.entrySet()) {
        File file = entry.getKey();
        Project project = entry.getValue();
        if (!file.equals(project.getDir())) {
            if (file.isDirectory()) {
                try {
                    File dir = file.getCanonicalFile();
                    if (dir.equals(project.getDir())) {
                        continue;
                    }
                } catch (IOException ioe) {
                // pass
                }
            }
            project.addFile(file);
        }
    }
    // Partition the projects up such that we only return projects that aren't
    // included by other projects (e.g. because they are library projects)
    Collection<Project> allProjects = fileToProject.values();
    Set<Project> roots = new HashSet<Project>(allProjects);
    for (Project project : allProjects) {
        roots.removeAll(project.getAllLibraries());
    }
    // projects as no-report projects by default.
    for (Project project : allProjects) {
        // Report issues for all projects explicitly listed or found via a directory
        // traversal -- including library projects.
        project.setReportIssues(true);
    }
    if (LintUtils.assertionsEnabled()) {
        // Make sure that all the project directories are unique. This ensures
        // that we didn't accidentally end up with different project instances
        // for a library project discovered as a directory as well as one
        // initialized from the library project dependency list
        IdentityHashMap<Project, Project> projects = new IdentityHashMap<Project, Project>();
        for (Project project : roots) {
            projects.put(project, project);
            for (Project library : project.getAllLibraries()) {
                projects.put(library, library);
            }
        }
        Set<File> dirs = new HashSet<File>();
        for (Project project : projects.keySet()) {
            assert !dirs.contains(project.getDir());
            dirs.add(project.getDir());
        }
    }
    return roots;
}
Also used : IdentityHashMap(java.util.IdentityHashMap) ArrayList(java.util.ArrayList) IOException(java.io.IOException) LinkedHashMap(java.util.LinkedHashMap) Project(com.android.tools.klint.detector.api.Project) File(java.io.File) PsiFile(com.intellij.psi.PsiFile) Map(java.util.Map) EnumMap(java.util.EnumMap) LinkedHashMap(java.util.LinkedHashMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) HashSet(java.util.HashSet)

Example 5 with Project

use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.

the class IntellijLintProject method createForSingleFile.

/**
   * Creates a project for a single file. Also optionally creates a main project for the file, if applicable.
   *
   * @param client the lint client
   * @param file the file to create a project for
   * @param module the module to create a project for
   * @return a project for the file, as well as a project (or null) for the main Android module
   */
@NonNull
public static Pair<Project, Project> createForSingleFile(@NonNull IntellijLintClient client, @Nullable VirtualFile file, @NonNull Module module) {
    // TODO: Can make this method even more lightweight: we don't need to initialize anything in the project (source paths etc)
    // other than the metadata necessary for this file's type
    LintModuleProject project = createModuleProject(client, module);
    LintModuleProject main = null;
    Map<Project, Module> projectMap = Maps.newHashMap();
    if (project != null) {
        project.setDirectLibraries(Collections.<Project>emptyList());
        if (file != null) {
            project.addFile(VfsUtilCore.virtualToIoFile(file));
        }
        projectMap.put(project, module);
        // using the library, not "1" (the default for a module without a manifest)
        if (!project.isAndroidProject()) {
            Module androidModule = findAndroidModule(module);
            if (androidModule != null) {
                main = createModuleProject(client, androidModule);
                if (main != null) {
                    projectMap.put(main, androidModule);
                    main.setDirectLibraries(Collections.<Project>singletonList(project));
                }
            }
        }
    }
    client.setModuleMap(projectMap);
    //noinspection ConstantConditions
    return Pair.<Project, Project>create(project, main);
}
Also used : Project(com.android.tools.klint.detector.api.Project) Module(com.intellij.openapi.module.Module) NonNull(com.android.annotations.NonNull)

Aggregations

Project (com.android.tools.klint.detector.api.Project)17 File (java.io.File)8 PsiFile (com.intellij.psi.PsiFile)4 IOException (java.io.IOException)4 NonNull (com.android.annotations.NonNull)3 Module (com.intellij.openapi.module.Module)3 AbstractResourceRepository (com.android.ide.common.res2.AbstractResourceRepository)2 ResourceItem (com.android.ide.common.res2.ResourceItem)2 LintClient (com.android.tools.klint.client.api.LintClient)2 ClassContext (com.android.tools.klint.detector.api.ClassContext)2 Context (com.android.tools.klint.detector.api.Context)2 JavaContext (com.android.tools.klint.detector.api.JavaContext)2 Location (com.android.tools.klint.detector.api.Location)2 ResourceContext (com.android.tools.klint.detector.api.ResourceContext)2 XmlContext (com.android.tools.klint.detector.api.XmlContext)2 HashSet (java.util.HashSet)2 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)2 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)1 ResourceFile (com.android.ide.common.res2.ResourceFile)1 ResourceUrl (com.android.ide.common.resources.ResourceUrl)1