2 * Copyright 2000-2017 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.openapi.compiler;
18 import com.intellij.compiler.CompilerConfiguration;
19 import com.intellij.openapi.application.Application;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.application.ReadAction;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.module.Module;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.project.ProjectUtil;
26 import com.intellij.openapi.roots.CompilerModuleExtension;
27 import com.intellij.openapi.roots.ModuleRootManager;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.openapi.vfs.VirtualFileManager;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33 import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
36 import java.util.Arrays;
39 * A set of utility methods for working with paths
41 public class CompilerPaths {
42 private static final Logger LOG = Logger.getInstance(CompilerPaths.class);
45 * @return a root directory where generated files for various compilers are stored
47 public static File getGeneratedDataDirectory(Project project) {
48 return new File(getCompilerSystemDirectory(project), ".generated");
52 * @return a root directory where compiler caches for the given project are stored
54 public static File getCacheStoreDirectory(final Project project) {
55 return new File(getCompilerSystemDirectory(project), ".caches");
59 * @return a directory under IDEA "system" directory where all files related to compiler subsystem are stored (such as compiler caches or generated files)
62 public static File getCompilerSystemDirectory(@NotNull Project project) {
63 return ProjectUtil.getProjectCachePath(project, "compiler").toFile();
67 * @param forTestClasses true if directory for test sources, false - for sources.
68 * @return a directory to which the sources (or test sources depending on the second parameter) should be compiled.
69 * Null is returned if output directory is not specified or is not valid
72 public static VirtualFile getModuleOutputDirectory(@NotNull Module module, boolean forTestClasses) {
73 final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
74 if (compilerModuleExtension == null) {
79 final VirtualFile path = compilerModuleExtension.getCompilerOutputPathForTests();
84 outPath = compilerModuleExtension.getCompilerOutputPath();
88 outPath = compilerModuleExtension.getCompilerOutputPath();
90 if (outPath == null) {
93 if (!outPath.isValid()) {
94 LOG.info("Requested output path for module " + module.getName() + " is not valid");
101 * The same as {@link #getModuleOutputDirectory} but returns String.
102 * The method still returns a non-null value if the output path is specified in Settings but does not exist on disk.
105 public static String getModuleOutputPath(final Module module, boolean forTestClasses) {
106 final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
107 if (extension == null) {
110 final String outPathUrl;
111 final Application application = ApplicationManager.getApplication();
112 if (forTestClasses) {
113 if (application.isDispatchThread()) {
114 final String url = extension.getCompilerOutputUrlForTests();
115 outPathUrl = url != null ? url : extension.getCompilerOutputUrl();
118 outPathUrl = ReadAction.compute(() -> {
119 final String url = extension.getCompilerOutputUrlForTests();
120 return url != null ? url : extension.getCompilerOutputUrl();
124 else { // for ordinary classes
125 if (application.isDispatchThread()) {
126 outPathUrl = extension.getCompilerOutputUrl();
129 outPathUrl = ReadAction.compute(() -> extension.getCompilerOutputUrl());
132 return outPathUrl != null? VirtualFileManager.extractPath(outPathUrl) : null;
136 public static String getAnnotationProcessorsGenerationPath(Module module, boolean forTests) {
137 final AnnotationProcessingConfiguration config = CompilerConfiguration.getInstance(module.getProject()).getAnnotationProcessingConfiguration(module);
138 final String sourceDirName = config.getGeneratedSourcesDirectoryName(forTests);
139 if (config.isOutputRelativeToContentRoot()) {
140 final String[] roots = ModuleRootManager.getInstance(module).getContentRootUrls();
141 if (roots.length == 0) {
144 if (roots.length > 1) {
147 return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(roots[0]): VirtualFileManager.extractPath(roots[0]) + "/" + sourceDirName;
151 final String path = getModuleOutputPath(module, forTests);
155 return StringUtil.isEmpty(sourceDirName)? path : path + "/" + sourceDirName;