From 912727e5d2fe569cdf0e069ecb6e401b47958191 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Wed, 19 Nov 2014 01:01:26 +0300 Subject: [PATCH] Unify extension point and extension registration in plugin and cli --- build.xml | 9 ++- .../ide/plugins/PluginManagerCoreProxy.java | 60 +++++++++++++++++ .../jetbrains/jet/cli/js/K2JSCompiler.java | 16 +---- .../jvm/compiler/EnvironmentConfigFiles.java | 35 ++++++++++ .../cli/jvm/compiler/JetCoreEnvironment.java | 67 +++++++++++++++---- .../src/org/jetbrains/jet/utils/PathUtil.java | 3 +- idea/src/META-INF/extensions/common.xml | 10 +++ idea/src/META-INF/extensions/ide.xml | 14 ++++ idea/src/META-INF/extensions/kotlin2js.xml | 8 +++ idea/src/META-INF/plugin.xml | 26 +++---- .../org/jetbrains/k2js/test/BasicTest.java | 3 +- .../NoInternalVisibilityInStdLibTest.kt | 2 +- 12 files changed, 206 insertions(+), 47 deletions(-) create mode 100644 compiler/cli/src/com/intellij/ide/plugins/PluginManagerCoreProxy.java create mode 100644 compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/EnvironmentConfigFiles.java create mode 100644 idea/src/META-INF/extensions/common.xml create mode 100644 idea/src/META-INF/extensions/ide.xml create mode 100644 idea/src/META-INF/extensions/kotlin2js.xml diff --git a/build.xml b/build.xml index ff31ecce32a..0616ffab950 100644 --- a/build.xml +++ b/build.xml @@ -365,6 +365,11 @@ + + + + + @@ -451,7 +456,7 @@ !org/mozilla/javascript/xml/impl/xmlbeans/**, !META-INF/maven**, **.class,**.properties,**.kt,**.kotlin_*, - META-INF/services/**,META-INF/native/**,META-INF/MANIFEST.MF, + META-INF/services/**,META-INF/native/**,META-INF/extensions/**,META-INF/MANIFEST.MF, messages/**) -outjars '${kotlin-home}/lib/kotlin-compiler.jar' @@ -733,7 +738,7 @@ - + diff --git a/compiler/cli/src/com/intellij/ide/plugins/PluginManagerCoreProxy.java b/compiler/cli/src/com/intellij/ide/plugins/PluginManagerCoreProxy.java new file mode 100644 index 00000000000..486a40d2efc --- /dev/null +++ b/compiler/cli/src/com/intellij/ide/plugins/PluginManagerCoreProxy.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2014 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 com.intellij.ide.plugins; + +import com.intellij.openapi.extensions.ExtensionPoint; +import com.intellij.openapi.extensions.ExtensionsArea; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.List; +import java.util.Set; + +// TODO drop this temporary hack to access to PluginManagerCore methods when CoreApplicationEnvironment got similar features. +public class PluginManagerCoreProxy { + private PluginManagerCoreProxy() {} + + @Nullable + public static IdeaPluginDescriptorImpl loadDescriptorFromDir(@NotNull File file, @NotNull String fileName) { + return PluginManagerCore.loadDescriptorFromDir(file, fileName); + } + + @Nullable + public static IdeaPluginDescriptorImpl loadDescriptorFromJar(@NotNull File file, @NotNull String fileName) { + return PluginManagerCore.loadDescriptorFromJar(file, fileName); + } + + // copied as is from PluginManagerCore#registerExtensionPointsAndExtensions + public static void registerExtensionPointsAndExtensions(ExtensionsArea area, List loadedPlugins) { + for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) { + descriptor.registerExtensionPoints(area); + } + + Set epNames = ContainerUtil.newHashSet(); + for (ExtensionPoint point : area.getExtensionPoints()) { + epNames.add(point.getName()); + } + + for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) { + for (String epName : epNames) { + descriptor.registerExtensions(area, epName); + } + } + } +} diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java index 39fe8e75b96..8d74f16fb28 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java @@ -19,8 +19,6 @@ package org.jetbrains.jet.cli.js; import com.google.common.base.Joiner; import com.google.common.base.Predicates; import com.intellij.openapi.Disposable; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.extensions.ExtensionsArea; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -45,13 +43,11 @@ import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage; import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil; +import org.jetbrains.jet.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.config.Services; import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression; -import org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative; -import org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules; import org.jetbrains.jet.utils.PathUtil; import org.jetbrains.k2js.analyze.TopDownAnalyzerFacadeForJS; import org.jetbrains.k2js.config.*; @@ -95,14 +91,8 @@ public class K2JSCompiler extends CLICompiler { configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector); CompileEnvironmentUtil.addSourceFilesCheckingForDuplicates(configuration, arguments.freeArgs); - JetCoreEnvironment environmentForJS = JetCoreEnvironment.createForProduction(rootDisposable, configuration); - - ExtensionsArea rootArea = Extensions.getRootArea(); - rootArea.getExtensionPoint(DiagnosticsWithSuppression.SuppressStringProvider.EP_NAME) - .registerExtension(new SuppressUnusedParameterForJsNative()); - - rootArea.getExtensionPoint(DiagnosticsWithSuppression.DiagnosticSuppressor.EP_NAME) - .registerExtension(new SuppressWarningsFromExternalModules()); + JetCoreEnvironment environmentForJS = + JetCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JS_CONFIG_FILES); Project project = environmentForJS.getProject(); List sourcesFiles = environmentForJS.getSourceFiles(); diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/EnvironmentConfigFiles.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/EnvironmentConfigFiles.java new file mode 100644 index 00000000000..38f9476759e --- /dev/null +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/EnvironmentConfigFiles.java @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2014 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.cli.jvm.compiler; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +public class EnvironmentConfigFiles { + + private static final String EXTENSIONS_DIR = "extensions"; + + private static final String COMMON_CONFIG_FILE = EXTENSIONS_DIR + File.separator + "common.xml"; + private static final String JVM_CONFIG_FILE = EXTENSIONS_DIR + File.separator + "kotlin2jvm.xml"; + private static final String JS_CONFIG_FILE = EXTENSIONS_DIR + File.separator + "kotlin2js.xml"; + + public static final List JVM_CONFIG_FILES = Arrays.asList(COMMON_CONFIG_FILE, JVM_CONFIG_FILE); + public static final List JS_CONFIG_FILES = Arrays.asList(COMMON_CONFIG_FILE, JS_CONFIG_FILE); + + private EnvironmentConfigFiles() {} +} diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java index c4dd0e3ae6c..7b082f2550a 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java @@ -21,6 +21,8 @@ import com.intellij.core.CoreApplicationEnvironment; import com.intellij.core.CoreJavaFileManager; import com.intellij.core.JavaCoreApplicationEnvironment; import com.intellij.core.JavaCoreProjectEnvironment; +import com.intellij.ide.plugins.IdeaPluginDescriptorImpl; +import com.intellij.ide.plugins.PluginManagerCoreProxy; import com.intellij.lang.java.JavaParserDefinition; import com.intellij.mock.MockApplication; import com.intellij.mock.MockProject; @@ -54,7 +56,6 @@ import org.jetbrains.jet.lang.parsing.JetParserDefinition; import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.CodeAnalyzerInitializer; -import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression; import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache; import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.CliDeclarationProviderFactoryService; @@ -64,9 +65,9 @@ import org.jetbrains.jet.utils.PathUtil; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import static com.intellij.core.CoreApplicationEnvironment.registerApplicationExtensionPoint; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.ERROR; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.WARNING; @@ -81,6 +82,15 @@ public class JetCoreEnvironment { public static JetCoreEnvironment createForProduction( @NotNull Disposable parentDisposable, @NotNull CompilerConfiguration configuration + ) { + return createForProduction(parentDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES); + } + + @NotNull + public static JetCoreEnvironment createForProduction( + @NotNull Disposable parentDisposable, + @NotNull CompilerConfiguration configuration, + @NotNull List configFilePaths ) { // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well @@ -95,7 +105,8 @@ public class JetCoreEnvironment { } }); JetCoreEnvironment environment = - new JetCoreEnvironment(parentDisposable, getOrCreateApplicationEnvironmentForProduction(), configuration); + new JetCoreEnvironment(parentDisposable, getOrCreateApplicationEnvironmentForProduction(configFilePaths), configuration); + synchronized (APPLICATION_LOCK) { ourProjectCount++; } @@ -104,18 +115,31 @@ public class JetCoreEnvironment { @TestOnly @NotNull - public static JetCoreEnvironment createForTests(@NotNull Disposable parentDisposable, @NotNull CompilerConfiguration configuration) { + public static JetCoreEnvironment createForTests( + @NotNull Disposable parentDisposable, + @NotNull CompilerConfiguration configuration + ) { + return createForTests(parentDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES); + } + + @TestOnly + @NotNull + public static JetCoreEnvironment createForTests( + @NotNull Disposable parentDisposable, + @NotNull CompilerConfiguration configuration, + @NotNull List extensionConfigs + ) { // Tests are supposed to create a single project and dispose it right after use - return new JetCoreEnvironment(parentDisposable, createApplicationEnvironment(parentDisposable), configuration); + return new JetCoreEnvironment(parentDisposable, createApplicationEnvironment(parentDisposable, extensionConfigs), configuration); } @NotNull - private static JavaCoreApplicationEnvironment getOrCreateApplicationEnvironmentForProduction() { + private static JavaCoreApplicationEnvironment getOrCreateApplicationEnvironmentForProduction(@NotNull List configFilePaths) { synchronized (APPLICATION_LOCK) { if (ourApplicationEnvironment != null) return ourApplicationEnvironment; Disposable parentDisposable = Disposer.newDisposable(); - ourApplicationEnvironment = createApplicationEnvironment(parentDisposable); + ourApplicationEnvironment = createApplicationEnvironment(parentDisposable, configFilePaths); ourProjectCount = 0; Disposer.register(parentDisposable, new Disposable() { @Override @@ -139,10 +163,15 @@ public class JetCoreEnvironment { } @NotNull - private static JavaCoreApplicationEnvironment createApplicationEnvironment(@NotNull Disposable parentDisposable) { + private static JavaCoreApplicationEnvironment createApplicationEnvironment( + @NotNull Disposable parentDisposable, + @NotNull List configFilePaths + ) { JavaCoreApplicationEnvironment applicationEnvironment = new JavaCoreApplicationEnvironment(parentDisposable); - registerApplicationExtensionPointsForCLI(); + for (String config : configFilePaths) { + registerApplicationExtensionPointsAndExtensionsFrom(config); + } registerApplicationServicesForCLI(applicationEnvironment); registerApplicationServices(applicationEnvironment); @@ -150,12 +179,22 @@ public class JetCoreEnvironment { return applicationEnvironment; } - private static void registerApplicationExtensionPointsForCLI() { - registerApplicationExtensionPoint(DiagnosticsWithSuppression.SuppressStringProvider.EP_NAME, - DiagnosticsWithSuppression.SuppressStringProvider.class); + private static void registerApplicationExtensionPointsAndExtensionsFrom(String configFilePath) { + IdeaPluginDescriptorImpl descriptor; + File jar = PathUtil.getPathUtilJar(); + if (jar.isFile()) { + descriptor = PluginManagerCoreProxy.loadDescriptorFromJar(jar, configFilePath); + } + else { + // hack for load extensions when compiler run directly from out directory(e.g. in tests) + File srcDir = jar.getParentFile().getParentFile().getParentFile(); + File pluginDir = new File(srcDir, "idea/src"); + descriptor = PluginManagerCoreProxy.loadDescriptorFromDir(pluginDir, configFilePath); + } - registerApplicationExtensionPoint(DiagnosticsWithSuppression.DiagnosticSuppressor.EP_NAME, - DiagnosticsWithSuppression.DiagnosticSuppressor.class); + assert descriptor != null : "Can not load descriptor from " + configFilePath + " relative to " + jar; + + PluginManagerCoreProxy.registerExtensionPointsAndExtensions(Extensions.getRootArea(), Collections.singletonList(descriptor)); } private static void registerApplicationServicesForCLI(@NotNull JavaCoreApplicationEnvironment applicationEnvironment) { diff --git a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java index 5d10c20312c..f485d7dc840 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java @@ -127,7 +127,8 @@ public class PathUtil { return NO_PATH; } - private static File getPathUtilJar() { + @NotNull + public static File getPathUtilJar() { return getJarPathForClass(PathUtil.class); } diff --git a/idea/src/META-INF/extensions/common.xml b/idea/src/META-INF/extensions/common.xml new file mode 100644 index 00000000000..992abf247e5 --- /dev/null +++ b/idea/src/META-INF/extensions/common.xml @@ -0,0 +1,10 @@ + + org.jetbrains.kotlin + + + + + + diff --git a/idea/src/META-INF/extensions/ide.xml b/idea/src/META-INF/extensions/ide.xml new file mode 100644 index 00000000000..4bcf0a3e379 --- /dev/null +++ b/idea/src/META-INF/extensions/ide.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/idea/src/META-INF/extensions/kotlin2js.xml b/idea/src/META-INF/extensions/kotlin2js.xml new file mode 100644 index 00000000000..954d35a2308 --- /dev/null +++ b/idea/src/META-INF/extensions/kotlin2js.xml @@ -0,0 +1,8 @@ + + org.jetbrains.kotlin + + + + + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index e2625ba1e09..9490a715725 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1,5 +1,5 @@ - - org.jetbrains.kotlin + + org.jetbrains.kotlin Kotlin Kotlin language support @@ -820,18 +820,14 @@ - - - - - - + + + + + + + + + - - - - - - - diff --git a/js/js.tests/test/org/jetbrains/k2js/test/BasicTest.java b/js/js.tests/test/org/jetbrains/k2js/test/BasicTest.java index d4bb9bd6458..49da6199e82 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/BasicTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/BasicTest.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.OutputFileCollection; import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage; +import org.jetbrains.jet.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.lang.psi.JetFile; @@ -84,7 +85,7 @@ public abstract class BasicTest extends KotlinTestWithEnvironment { @Override protected JetCoreEnvironment createEnvironment() { - return JetCoreEnvironment.createForTests(getTestRootDisposable(), new CompilerConfiguration()); + return JetCoreEnvironment.createForTests(getTestRootDisposable(), new CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES); } protected boolean shouldCreateOut() { diff --git a/libraries/stdlib/validator/src/test/kotlin/NoInternalVisibilityInStdLibTest.kt b/libraries/stdlib/validator/src/test/kotlin/NoInternalVisibilityInStdLibTest.kt index ef16928a837..53ffa62860c 100644 --- a/libraries/stdlib/validator/src/test/kotlin/NoInternalVisibilityInStdLibTest.kt +++ b/libraries/stdlib/validator/src/test/kotlin/NoInternalVisibilityInStdLibTest.kt @@ -135,7 +135,7 @@ class NoInternalVisibilityInStdLibTest { Test fun testJsStdlibJar() { doTest(ANALYZE_PACKAGE_ROOTS_FOR_JS, ADDITIONALLY_REQUIRED_PACKAGES_FOR_JS) { val configuration = CompilerConfiguration() - val environment = JetCoreEnvironment.createForProduction(it, configuration) + val environment = JetCoreEnvironment.createForProduction(it, configuration, EnvironmentConfigFiles.JS_CONFIG_FILES) val project = environment.getProject() val pathToJsStdlibJar = KOTLIN_ROOT_PATH + PathUtil.getKotlinPathsForDistDirectory().getJsLibJarPath().path val config = LibrarySourcesConfig(project, "testModule", listOf("@", pathToJsStdlibJar), EcmaVersion.defaultVersion(), false, false)