Unify extension point and extension registration in plugin and cli

This commit is contained in:
Zalim Bashorov
2014-11-19 01:01:26 +03:00
parent 14d663bcab
commit 912727e5d2
12 changed files with 206 additions and 47 deletions
+7 -2
View File
@@ -365,6 +365,11 @@
<fileset dir="${basedir}/compiler/backend/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/resources" includes="manifest.properties"/>
<fileset dir="idea/src">
<include name="META-INF/extensions/common.xml"/>
<include name="META-INF/extensions/kotlin2js.xml"/>
</fileset>
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
<zipgroupfileset dir="${basedir}/ideaSDK/lib" includes="jna-utils.jar"/>
@@ -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 @@
<fileset dir="${basedir}/idea/idea-analysis/src" excludes="**/*.java, **/*.kt"/>
</copy>
<jar jarfile="${output}/kotlin-for-upsource0.jar">
<jar jarfile="${output}/kotlin-for-upsource0.jar">
<fileset dir="${output}/classes/idea-analysis"/>
<fileset dir="${output}/classes/compiler"/>
<fileset dir="${output}/classes/runtime"/>
@@ -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<IdeaPluginDescriptorImpl> loadedPlugins) {
for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) {
descriptor.registerExtensionPoints(area);
}
Set<String> epNames = ContainerUtil.newHashSet();
for (ExtensionPoint point : area.getExtensionPoints()) {
epNames.add(point.getName());
}
for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) {
for (String epName : epNames) {
descriptor.registerExtensions(area, epName);
}
}
}
}
@@ -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<K2JSCompilerArguments> {
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<JetFile> sourcesFiles = environmentForJS.getSourceFiles();
@@ -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<String> JVM_CONFIG_FILES = Arrays.asList(COMMON_CONFIG_FILE, JVM_CONFIG_FILE);
public static final List<String> JS_CONFIG_FILES = Arrays.asList(COMMON_CONFIG_FILE, JS_CONFIG_FILE);
private EnvironmentConfigFiles() {}
}
@@ -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<String> 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<String> 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<String> 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<String> 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) {
@@ -127,7 +127,8 @@ public class PathUtil {
return NO_PATH;
}
private static File getPathUtilJar() {
@NotNull
public static File getPathUtilJar() {
return getJarPathForClass(PathUtil.class);
}
+10
View File
@@ -0,0 +1,10 @@
<idea-plugin>
<id>org.jetbrains.kotlin</id>
<extensionPoints>
<extensionPoint name="suppressStringProvider"
interface="org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression$SuppressStringProvider"/>
<extensionPoint name="diagnosticSuppressor"
interface="org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression$DiagnosticSuppressor"/>
</extensionPoints>
</idea-plugin>
+14
View File
@@ -0,0 +1,14 @@
<idea-plugin>
<extensionPoints>
<extensionPoint name="updater" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint"/>
<extensionPoint name="projectConfigurator" interface="org.jetbrains.jet.plugin.configuration.KotlinProjectConfigurator"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<projectConfigurator implementation="org.jetbrains.jet.plugin.configuration.KotlinJavaModuleConfigurator"/>
<projectConfigurator implementation="org.jetbrains.jet.plugin.configuration.KotlinJsModuleConfigurator"/>
<!-- diagnosticSuppressor decelerated in common.xml -->
<diagnosticSuppressor implementation="org.jetbrains.jet.plugin.debugger.DiagnosticSuppressorForDebugger"/>
</extensions>
</idea-plugin>
@@ -0,0 +1,8 @@
<idea-plugin>
<id>org.jetbrains.kotlin</id>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<suppressStringProvider implementation="org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative"/>
<diagnosticSuppressor implementation="org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules"/>
</extensions>
</idea-plugin>
+11 -15
View File
@@ -1,5 +1,5 @@
<idea-plugin version="2" url="http://kotlin.jetbrains.org">
<id>org.jetbrains.kotlin</id>
<idea-plugin version="2" url="http://kotlin.jetbrains.org" xmlns:xi="http://www.w3.org/2001/XInclude">
<id>org.jetbrains.kotlin</id>
<name>Kotlin</name>
<description>Kotlin language support</description>
@@ -820,18 +820,14 @@
</extensions>
<extensionPoints>
<extensionPoint name="updater" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint"/>
<extensionPoint name="projectConfigurator" interface="org.jetbrains.jet.plugin.configuration.KotlinProjectConfigurator"/>
<extensionPoint name="suppressStringProvider" interface="org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression$SuppressStringProvider"/>
<extensionPoint name="diagnosticSuppressor" interface="org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression$DiagnosticSuppressor"/>
</extensionPoints>
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensionPoints>
<xi:include href="extensions/common.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<xi:include href="extensions/kotlin2js.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<projectConfigurator implementation="org.jetbrains.jet.plugin.configuration.KotlinJavaModuleConfigurator"/>
<projectConfigurator implementation="org.jetbrains.jet.plugin.configuration.KotlinJsModuleConfigurator"/>
<suppressStringProvider implementation="org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative"/>
<diagnosticSuppressor implementation="org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules"/>
<diagnosticSuppressor implementation="org.jetbrains.jet.plugin.debugger.DiagnosticSuppressorForDebugger"/>
</extensions>
</idea-plugin>
@@ -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() {
@@ -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)