Move detecting java to FrameworkDetector. Search for markers only on project root update.

This commit is contained in:
Nikolay Krasko
2013-02-21 20:13:43 +04:00
parent 78d1ccab62
commit 27da87afe5
11 changed files with 134 additions and 148 deletions
@@ -34,7 +34,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.compiler.runner.*;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
import java.io.File;
import java.io.IOException;
@@ -50,7 +50,7 @@ public class JetCompiler implements TranslatingCompiler {
return false;
}
Module module = compileContext.getModuleByFile(virtualFile);
if (module != null && JsModuleDetector.isJsModule(module)) {
if (module != null && KotlinFrameworkDetector.isJsModule(module)) {
return false;
}
return true;
@@ -42,7 +42,7 @@ import org.jetbrains.jet.compiler.runner.CompilerEnvironment;
import org.jetbrains.jet.compiler.runner.CompilerRunnerUtil;
import org.jetbrains.jet.compiler.runner.OutputItemsCollectorImpl;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
import java.io.File;
import java.io.PrintStream;
@@ -63,7 +63,7 @@ public final class K2JSCompiler implements TranslatingCompiler {
if (module == null) {
return false;
}
return JsModuleDetector.isJsModule(module);
return KotlinFrameworkDetector.isJsModule(module);
}
@Override
@@ -178,7 +178,7 @@ public final class K2JSCompiler implements TranslatingCompiler {
}
private static void addLibLocationAndTarget(@NotNull Module module, @NotNull ArrayList<String> args) {
Pair<List<String>, String> libLocationAndTarget = JsModuleDetector.getLibLocationAndTargetForProject(module);
Pair<List<String>, String> libLocationAndTarget = KotlinFrameworkDetector.getLibLocationAndTargetForProject(module);
StringBuilder sb = StringBuilderSpinAllocator.alloc();
AccessToken token = ReadAction.start();
@@ -28,8 +28,8 @@ import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
import org.jetbrains.jet.plugin.libraries.DecompiledDataFactory;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
public class JetTypesCompletionHelper {
private JetTypesCompletionHelper() {}
@@ -45,7 +45,7 @@ public class JetTypesCompletionHelper {
jetCompletionResult.addAllElements(namesCache.getJetClassesDescriptors(
jetCompletionResult.getShortNameFilter(), jetCompletionResult.getResolveSession()));
if (!JsModuleDetector.isJsModule((JetFile) parameters.getOriginalFile())) {
if (!KotlinFrameworkDetector.isJsModule((JetFile) parameters.getOriginalFile())) {
addAdaptedJavaCompletion(parameters,jetCompletionResult);
}
}
@@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.plugin.completion.JetLookupObject;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper;
public class JetClassInsertHandler implements InsertHandler<LookupElement> {
@@ -60,7 +60,7 @@ public class JetClassInsertHandler implements InsertHandler<LookupElement> {
if (targetElement != null) {
ImportInsertHelper.addImportDirectiveOrChangeToFqName(fqn, jetFile, context.getStartOffset(), targetElement);
}
else if (JsModuleDetector.isJsModule(jetFile)) {
else if (KotlinFrameworkDetector.isJsModule(jetFile)) {
ImportInsertHelper.addImportDirective(fqn, jetFile);
}
}
@@ -0,0 +1,113 @@
package org.jetbrains.jet.plugin.framework;
import com.intellij.ProjectTopics;
import com.intellij.openapi.application.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.ui.EditorNotifications;
import com.intellij.util.Alarm;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.plugin.util.ApplicationUtils;
import org.jetbrains.jet.plugin.versions.KotlinLibrariesNotificationProvider;
import org.jetbrains.jet.plugin.versions.KotlinRuntimeLibraryUtil;
import org.jetbrains.jet.utils.KotlinPathsFromHomeDir;
import org.jetbrains.jet.utils.PathUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class KotlinFrameworkDetector {
private static final Key<CachedValue<Boolean>> IS_KOTLIN_JS_MODULE = Key.create("IS_KOTLIN_JS_MODULE");
private static final Key<CachedValue<Boolean>> IS_KOTLIN_JAVA_MODULE = Key.create("IS_KOTLIN_JAVA_MODULE");
private KotlinFrameworkDetector() {
}
public static boolean isJsModule(@NotNull JetFile file) {
Module module = ModuleUtilCore.findModuleForPsiElement(file);
return module != null && isJsModule(module);
}
public static boolean isJavaModule(@NotNull final Module module) {
CachedValue<Boolean> result = module.getUserData(IS_KOTLIN_JAVA_MODULE);
if (result == null) {
result = CachedValuesManager.getManager(module.getProject()).createCachedValue(new CachedValueProvider<Boolean>() {
@Override
public Result<Boolean> compute() {
GlobalSearchScope scope = module.getModuleWithDependenciesAndLibrariesScope(false);
return Result.create(KotlinRuntimeLibraryUtil.getKotlinRuntimeMarkerClass(scope) != null,
ProjectRootModificationTracker.getInstance(module.getProject()));
}
}, false);
module.putUserData(IS_KOTLIN_JAVA_MODULE, result);
}
return result.getValue();
}
private static Boolean checkModuleHasJavaScriptLibrary(final Module module) {
final Ref<Boolean> found = Ref.create(Boolean.FALSE);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
ModuleRootManager.getInstance(module).orderEntries().librariesOnly().forEachLibrary(new Processor<Library>() {
@Override
public boolean process(Library library) {
String libraryName = library.getName();
if (libraryName != null && libraryName.contains(PathUtil.JS_LIB_JAR_NAME)) {
found.set(Boolean.TRUE);
return false;
}
return true;
}
});
}
});
return found.get();
}
public static boolean isJsModule(@NotNull final Module module) {
CachedValue<Boolean> result = module.getUserData(IS_KOTLIN_JS_MODULE);
if (result == null) {
result = CachedValuesManager.getManager(module.getProject()).createCachedValue(new CachedValueProvider<Boolean>() {
@Override
public Result<Boolean> compute() {
return Result.create(checkModuleHasJavaScriptLibrary(module),
ProjectRootModificationTracker.getInstance(module.getProject()));
}
}, false);
module.putUserData(IS_KOTLIN_JS_MODULE, result);
}
return result.getValue();
}
public static Pair<List<String>, String> getLibLocationAndTargetForProject(Module module) {
return Pair.<List<String>, String>create(new ArrayList<String>(), "ecma3");
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
public final class AnalyzerFacadeProvider {
@@ -54,7 +55,7 @@ public final class AnalyzerFacadeProvider {
@NotNull
private static AnalyzerFacade getAnalyzerFacadeForModule(@NotNull Module module) {
if (JsModuleDetector.isJsModule(module)) {
if (KotlinFrameworkDetector.isJsModule(module)) {
return JSAnalyzerFacadeForIDEA.INSTANCE;
}
return AnalyzerFacadeForJVM.INSTANCE;
@@ -21,10 +21,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.config.LibrarySourcesConfig;
import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationAndTargetForProject;
import java.util.ArrayList;
public final class IDEAConfig extends LibrarySourcesConfig {
public IDEAConfig(@NotNull Project project) {
super(project, "default", getLibLocationAndTargetForProject(project).first, EcmaVersion.defaultVersion());
super(project, "default", new ArrayList<String>(), EcmaVersion.defaultVersion());
}
}
@@ -1,91 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.project;
import com.google.common.collect.Lists;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetFile;
import java.util.List;
/**
* This class has utility functions to determine whether the project (or module) is js project.
*/
public final class JsModuleDetector {
private JsModuleDetector() {
}
public static boolean isJsModule(@NotNull Module module) {
// TODO: fix
return false;
}
public static boolean isJsModule(@NotNull JetFile file) {
VirtualFile virtualFile = file.getOriginalFile().getVirtualFile();
if (virtualFile != null) {
Module module = ProjectRootManager.getInstance(file.getProject()).getFileIndex().getModuleForFile(virtualFile);
if (module != null) {
return isJsModule(module);
}
}
return false;
}
@NotNull
public static Pair<List<String>, String> getLibLocationAndTargetForProject(@NotNull Project project) {
Module module = getJSModule(project);
if (module == null) {
return Pair.empty();
}
else {
return getLibLocationAndTargetForProject(module);
}
}
@NotNull
public static Pair<List<String>, String> getLibLocationAndTargetForProject(@NotNull Module module) {
throw new IllegalStateException("Under construction");
//K2JSModuleComponent jsModuleComponent = K2JSModuleComponent.getInstance(module);
//String pathToJavaScriptLibrary = jsModuleComponent.getPathToJavaScriptLibrary();
//String basePath = ModuleRootManager.getInstance(module).getContentRoots()[0].getPath();
//List<String> pathsToJSLib = Lists.newArrayList();
//if (pathToJavaScriptLibrary != null) {
// pathsToJSLib.add(basePath + pathToJavaScriptLibrary);
//}
//return Pair.create(pathsToJSLib, jsModuleComponent.getEcmaVersion().toString());
}
@Nullable
private static Module getJSModule(@NotNull Project project) {
Module[] modules = ModuleManager.getInstance(project).getModules();
for (Module module : modules) {
if (isJsModule(module)) {
return module;
}
}
return null;
}
}
@@ -52,7 +52,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.actions.JetAddImportAction;
import org.jetbrains.jet.plugin.caches.JetShortNamesCache;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.util.JetPsiHeuristicsUtil;
@@ -162,7 +162,7 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
public static Collection<FqName> getClassNames(@NotNull String referenceName, @NotNull JetFile file, @NotNull KotlinCodeAnalyzer analyzer) {
Set<FqName> possibleResolveNames = Sets.newHashSet();
if (!JsModuleDetector.isJsModule(file)) {
if (!KotlinFrameworkDetector.isJsModule(file)) {
possibleResolveNames.addAll(getClassesFromCache(referenceName, file));
}
else {
@@ -199,7 +199,7 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
}
private static PsiShortNamesCache getShortNamesCache(@NotNull JetFile jetFile) {
if (JsModuleDetector.isJsModule(jetFile)) {
if (KotlinFrameworkDetector.isJsModule(jetFile)) {
return JetShortNamesCache.getKotlinInstance(jetFile.getProject());
}
@@ -31,9 +31,8 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.plugin.JetMainDetector;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
public class JetRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable {
@Nullable
@@ -56,7 +55,7 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im
return null;
}
if (JsModuleDetector.isJsModule(module)) {
if (KotlinFrameworkDetector.isJsModule(module)) {
return null;
}
@@ -20,7 +20,6 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.intellij.facet.impl.DefaultFacetsProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -28,10 +27,7 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.roots.AnnotationOrderRootType;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
@@ -46,13 +42,13 @@ import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.indexing.ID;
import com.intellij.util.text.UniqueNameGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
@@ -62,8 +58,6 @@ import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import static org.jetbrains.jet.plugin.project.JsModuleDetector.isJsModule;
public class KotlinRuntimeLibraryUtil {
public static final String LIBRARY_NAME = "KotlinRuntime";
public static final String KOTLIN_RUNTIME_JAR = "kotlin-runtime.jar";
@@ -138,7 +132,7 @@ public class KotlinRuntimeLibraryUtil {
}
public static boolean isModuleAlreadyConfigured(Module module) {
return isMavenModule(module) || isJsModule(module) || isWithJavaModule(module);
return isMavenModule(module) || KotlinFrameworkDetector.isJsModule(module) || KotlinFrameworkDetector.isJavaModule(module);
}
private static boolean isMavenModule(@NotNull Module module) {
@@ -147,15 +141,8 @@ public class KotlinRuntimeLibraryUtil {
return "true".equals(module.getOptionValue("org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule"));
}
private static boolean isWithJavaModule(Module module) {
// Can find a reference to kotlin class in module scope
GlobalSearchScope scope = module.getModuleWithDependenciesAndLibrariesScope(false);
return getKotlinRuntimeMarkerClass(scope) != null;
}
@Nullable
private static PsiClass getKotlinRuntimeMarkerClass(@NotNull GlobalSearchScope scope) {
public static PsiClass getKotlinRuntimeMarkerClass(@NotNull GlobalSearchScope scope) {
FqName kotlinPackageFqName = FqName.topLevel(Name.identifier("kotlin"));
String kotlinPackageClassFqName = PackageClassUtils.getPackageClassFqName(kotlinPackageFqName).getFqName();
@@ -176,29 +163,6 @@ public class KotlinRuntimeLibraryUtil {
return null;
}
public static boolean isLibraryCanBeUsedAsJavaRuntime(@Nullable Library library) {
if (library == null) {
return false;
}
for (VirtualFile root : library.getFiles(OrderRootType.CLASSES)) {
if (root.getName().equals(KOTLIN_RUNTIME_JAR)) {
return true;
}
}
return false;
}
private static String getUniqueLibraryName(final String baseName, final LibraryTable.ModifiableModel model) {
return UniqueNameGenerator.generateUniqueName(baseName, "", "", " (", ")", new Condition<String>() {
@Override
public boolean value(String s) {
return model.getLibraryByName(s) == null;
}
});
}
public static void updateRuntime(
@NotNull final Project project,
@NotNull final Runnable jarNotFoundHandler