not configured sdk notification

This commit is contained in:
Maxim Manuylov
2012-07-21 16:04:45 +04:00
committed by Evgeny Gerashchenko
parent 0e7e45f58e
commit 6af84a23b3
5 changed files with 196 additions and 22 deletions
+1
View File
@@ -78,6 +78,7 @@
<framework.type implementation="org.jetbrains.jet.plugin.sdk.KotlinFrameworkType"/>
<library.presentationProvider implementation="org.jetbrains.jet.plugin.sdk.KotlinSdkPresentationProvider"/>
<editorNotificationProvider implementation="org.jetbrains.jet.plugin.sdk.KotlinSdkNotConfiguredNotificationProvider"/>
<internalFileTemplate name="Kotlin File"/>
<internalFileTemplate name="Kotlin Class"/>
@@ -17,8 +17,14 @@
package org.jetbrains.jet.plugin;
import com.google.common.collect.Lists;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
@@ -77,4 +83,24 @@ public class JetPluginUtil {
}
return libraryScope == ((NamespaceDescriptor) declaration).getMemberScope();
}
@Nullable
public static Module getModuleForKotlinFile(@NotNull final VirtualFile file, @NotNull final Project project) {
if (file.getFileType() != JetFileType.INSTANCE) return null;
if (CompilerManager.getInstance(project).isExcludedFromCompilation(file)) return null;
final Module module = ModuleUtil.findModuleForFile(file, project);
if (module == null || isMavenModule(module)) return null;
return module;
}
private static boolean isMavenModule(@NotNull final Module module) {
for (final VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) {
if (root.findChild("pom.xml") != null) {
return true;
}
}
return false;
}
}
@@ -20,13 +20,11 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.fileChooser.FileTextField;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
@@ -55,7 +53,7 @@ import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.JetPluginUtil;
import org.jetbrains.jet.utils.PathUtil;
import javax.swing.*;
@@ -83,15 +81,9 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file) {
try {
if (file.getFileType() != JetFileType.INSTANCE) return null;
if (CompilerManager.getInstance(myProject).isExcludedFromCompilation(file)) return null;
final Module module = ModuleUtil.findModuleForFile(file, myProject);
final Module module = JetPluginUtil.getModuleForKotlinFile(file, myProject);
if (module == null) return null;
if (isMavenModule(module)) return null;
if (isJsModule(module)) return null;
GlobalSearchScope scope = module.getModuleWithDependenciesAndLibrariesScope(false);
@@ -251,14 +243,6 @@ public class ConfigureKotlinLibraryNotificationProvider implements EditorNotific
});
}
private static boolean isMavenModule(@NotNull Module module) {
for (VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) {
if (root.findChild("pom.xml") != null) return true;
}
return false;
}
private static class ChoosePathDialog extends DialogWrapper {
private final Project myProject;
private TextFieldWithBrowseButton myPathField;
@@ -0,0 +1,110 @@
/*
* Copyright 2010-2012 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.sdk;
import com.intellij.ProjectTopics;
import com.intellij.ide.util.frameworkSupport.AddFrameworkSupportDialog;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.plugin.JetPluginUtil;
import java.io.File;
import java.util.Collection;
/**
* @author Maxim.Manuylov
* Date: 19.05.12
*/
public class KotlinSdkNotConfiguredNotificationProvider implements EditorNotifications.Provider<EditorNotificationPanel> {
@NotNull private static final Key<EditorNotificationPanel> KEY = Key.create("configure.kotlin.sdk");
@NotNull private final Project myProject;
public KotlinSdkNotConfiguredNotificationProvider(@NotNull final Project project, @NotNull final EditorNotifications notifications) {
myProject = project;
project.getMessageBus().connect(project).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
@Override
public void beforeRootsChange(final ModuleRootEvent event) {}
@Override
public void rootsChanged(final ModuleRootEvent event) {
notifications.updateAllNotifications();
}
});
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Nullable
@Override
public EditorNotificationPanel createNotificationPanel(@NotNull final VirtualFile file) {
try {
final Module module = JetPluginUtil.getModuleForKotlinFile(file, myProject);
if (module == null) return null;
final GlobalSearchScope scope = module.getModuleWithDependenciesAndLibrariesScope(false);
if (!containsKotlinCompilerJar(FilenameIndex.getVirtualFilesByName(myProject, KotlinSdkUtil.KOTLIN_COMPILER_JAR, scope))) {
return createNotificationPanel(module);
}
}
catch (final ProcessCanceledException ignore) {}
catch (final IndexNotReadyException ignore) {}
return null;
}
private static boolean containsKotlinCompilerJar(@NotNull final Collection<VirtualFile> jars) {
for (final VirtualFile jar : jars) {
if (KotlinSdkUtil.isKotlinCompilerJar(new File(jar.getPath()))) {
return true;
}
}
return false;
}
@NotNull
private static EditorNotificationPanel createNotificationPanel(@NotNull final Module module) {
final EditorNotificationPanel panel = new EditorNotificationPanel();
panel.setText("Kotlin SDK is not configured for module \"" + module.getName() + "\"");
panel.createActionLabel("Configure Kotlin SDK", new Runnable() {
@Override
public void run() {
final AddFrameworkSupportDialog dialog = AddFrameworkSupportDialog.createDialog(module);
if (dialog != null) {
dialog.show();
}
}
});
return panel;
}
}
@@ -25,6 +25,9 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
/**
* @author Maxim.Manuylov
@@ -39,7 +42,11 @@ public class KotlinSdkUtil {
return new KotlinSdkProperties("");
}
};
@NotNull private static final String KOTLIN_COMPILER_JAR = "kotlin-compiler.jar";
@NotNull public static final String KOTLIN_COMPILER_JAR = "kotlin-compiler.jar";
@NotNull private static final String[] KOTLIN_COMPILER_JAR_ENTRY_NAMES = {
"org/jetbrains/jet/cli/KotlinCompiler.class",
"org/jetbrains/jet/cli/jvm/K2JVMCompiler.class"
};
private KotlinSdkUtil() {}
@@ -48,7 +55,7 @@ public class KotlinSdkUtil {
}
private static boolean isSDKHome(@NotNull final File dir) {
return dir.isDirectory() && new File(new File(dir, "lib"), KOTLIN_COMPILER_JAR).isFile();
return dir.isDirectory() && isKotlinCompilerJar(getKotlinCompilerJar(dir));
}
@Nullable
@@ -57,14 +64,36 @@ public class KotlinSdkUtil {
return FileUtil.loadFile(new File(sdkHomePath, "build.txt")).trim();
}
catch (final IOException e) {
return null;
try {
return getJarImplementationVersion(getKotlinCompilerJar(new File(sdkHomePath)));
}
catch (final IOException e1) {
return null;
}
}
}
@Nullable
private static String getJarImplementationVersion(@NotNull final File jar) throws IOException {
final JarFile jarFile = new JarFile(jar);
try {
final Manifest manifest = jarFile.getManifest();
return manifest == null ? null : manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}
finally {
jarFile.close();
}
}
@NotNull
private static File getKotlinCompilerJar(@NotNull final File sdkHome) {
return new File(new File(sdkHome, "lib"), KOTLIN_COMPILER_JAR);
}
@Nullable
public static String detectSDKVersion(@NotNull final List<VirtualFile> jars) {
for (final VirtualFile jar : jars) {
if (jar.getName().equals(KOTLIN_COMPILER_JAR)) {
if (jar.getName().equals(KOTLIN_COMPILER_JAR) && isKotlinCompilerJar(new File(jar.getPath()))) {
final VirtualFile libDir = jar.getParent();
if (libDir != null) {
final VirtualFile sdkHomeDir = libDir.getParent();
@@ -77,6 +106,30 @@ public class KotlinSdkUtil {
return null;
}
public static boolean isKotlinCompilerJar(@NotNull final File jar) {
try {
return doIsKotlinCompilerJar(jar);
}
catch (final IOException e) {
return false;
}
}
private static boolean doIsKotlinCompilerJar(@NotNull final File jar) throws IOException {
final JarFile jarFile = new JarFile(jar);
try {
for (final String entryName : KOTLIN_COMPILER_JAR_ENTRY_NAMES) {
if (jarFile.getJarEntry(entryName) != null) {
return true;
}
}
return false;
}
finally {
jarFile.close();
}
}
@NotNull
public static String getSDKName(@NotNull final String version) {
return "Kotlin " + version;