From e10d8a6fe03ff467a4691bdead53209db18b5abb Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 30 Sep 2014 09:07:17 +0400 Subject: [PATCH] ExternalDeclarationsProvider introduced --- .../cli/jvm/compiler/JetCoreEnvironment.java | 4 +- compiler/frontend.java/frontend.java.iml | 1 - .../kotlin/resolve/jvm/JvmAnalyzerFacade.kt | 15 ++++-- .../jvm/TopDownAnalyzerFacadeForJVM.java | 7 ++- .../ExternalDeclarationsProvider.kt | 28 +++++++++++ .../extensions/ProjectExtensionDescriptor.kt | 46 +++++++++++++++++++ .../android-compiler-plugin.iml | 1 + .../src/AndroidComponentRegistrar.kt | 17 ++++++- .../jet/lang/resolve/android/AndroidUtil.kt | 10 +--- .../src/META-INF/plugin.xml | 4 ++ 10 files changed, 112 insertions(+), 21 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/extensions/ExternalDeclarationsProvider.kt create mode 100644 compiler/frontend/src/org/jetbrains/jet/extensions/ProjectExtensionDescriptor.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java index 4351d303f33..2a4ddcffb52 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/JetCoreEnvironment.java @@ -56,6 +56,7 @@ import kotlin.Function1; import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; +import org.jetbrains.jet.extensions.ExternalDeclarationsProvider; import org.jetbrains.kotlin.asJava.JavaElementFinder; import org.jetbrains.kotlin.asJava.KotlinLightClassForPackage; import org.jetbrains.kotlin.asJava.LightClassGenerationSupport; @@ -298,8 +299,9 @@ public class JetCoreEnvironment { for (ComponentRegistrar registrar : configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) { registrar.registerProjectComponents(project, configuration); - } + + ExternalDeclarationsProvider.OBJECT$.registerExtensionPoint(project); } private static void registerProjectExtensionPoints(ExtensionsArea area) { diff --git a/compiler/frontend.java/frontend.java.iml b/compiler/frontend.java/frontend.java.iml index e253bea2077..cfa614d54cd 100644 --- a/compiler/frontend.java/frontend.java.iml +++ b/compiler/frontend.java/frontend.java.iml @@ -14,6 +14,5 @@ - diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt index 0424ea48842..033665a8f67 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt @@ -35,10 +35,9 @@ import org.jetbrains.kotlin.di.InjectorForLazyResolveWithJava import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.jet.lang.psi.JetFile -import com.intellij.openapi.components.ServiceManager -import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor import java.util.ArrayList -import org.jetbrains.jet.lang.resolve.android.searchAndAddAndroidDeclarations +import org.jetbrains.jet.extensions.ExternalDeclarationsProvider +import kotlin.platform.platformStatic public class JvmResolverForModule( override val lazyResolveSession: ResolveSession, @@ -61,7 +60,7 @@ public object JvmAnalyzerFacade : AnalyzerFacade ): JvmResolverForModule { val (syntheticFiles, moduleContentScope) = moduleContent - val filesToAnalyze = searchAndAddAndroidDeclarations(project, syntheticFiles) + val filesToAnalyze = getAllFilesToAnalyze(project, syntheticFiles) val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory( project, globalContext.storageManager, filesToAnalyze, if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope @@ -88,4 +87,12 @@ public object JvmAnalyzerFacade : AnalyzerFacade): List { + val allFiles = ArrayList(baseFiles) + for (externalDeclarationsProvider in ExternalDeclarationsProvider.getInstances(project)) { + allFiles.addAll(externalDeclarationsProvider.getExternalDeclarations()) + } + return allFiles + } + } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java index cbb36cab018..542bcc43bdd 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/TopDownAnalyzerFacadeForJVM.java @@ -116,11 +116,10 @@ public enum TopDownAnalyzerFacadeForJVM { @Nullable List moduleIds, @Nullable IncrementalCacheProvider incrementalCacheProvider ) { - List filesToAnalyze = new ArrayList(files); - searchAndAddAndroidDeclarations(project, filesToAnalyze); + List allFiles = JvmAnalyzerFacade.getAllFilesToAnalyze(project, files); FileBasedDeclarationProviderFactory providerFactory = - new FileBasedDeclarationProviderFactory(topDownAnalysisParameters.getStorageManager(), filesToAnalyze); + new FileBasedDeclarationProviderFactory(topDownAnalysisParameters.getStorageManager(), allFiles); InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm( project, @@ -149,7 +148,7 @@ public enum TopDownAnalyzerFacadeForJVM { } additionalProviders.add(injector.getJavaDescriptorResolver().getPackageFragmentProvider()); - injector.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisParameters, filesToAnalyze, additionalProviders); + injector.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisParameters, allFiles, additionalProviders); return AnalysisResult.success(trace.getBindingContext(), module); } finally { diff --git a/compiler/frontend/src/org/jetbrains/jet/extensions/ExternalDeclarationsProvider.kt b/compiler/frontend/src/org/jetbrains/jet/extensions/ExternalDeclarationsProvider.kt new file mode 100644 index 00000000000..c5f92728650 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/extensions/ExternalDeclarationsProvider.kt @@ -0,0 +1,28 @@ +/* + * 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.extensions + +import org.jetbrains.jet.lang.psi.JetFile + +public trait ExternalDeclarationsProvider { + class object : ProjectExtensionDescriptor( + "org.jetbrains.kotlin.externalDeclarationsProvider", + javaClass() + ) + + public fun getExternalDeclarations(): Collection +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/extensions/ProjectExtensionDescriptor.kt b/compiler/frontend/src/org/jetbrains/jet/extensions/ProjectExtensionDescriptor.kt new file mode 100644 index 00000000000..463629d65b6 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/extensions/ProjectExtensionDescriptor.kt @@ -0,0 +1,46 @@ +/* + * 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.extensions + +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.project.Project +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.extensions.ExtensionPoint + +public open class ProjectExtensionDescriptor(name: String, private val extensionClass: Class) { + public val extensionPointName: ExtensionPointName = ExtensionPointName.create(name)!! + + public fun registerExtensionPoint(project: Project) { + Extensions.getArea(project).registerExtensionPoint( + extensionPointName.getName()!!, + extensionClass.getName(), + ExtensionPoint.Kind.INTERFACE + ) + } + + public fun registerExtension(project: Project, extension: T) { + Extensions.getArea(project).getExtensionPoint(extensionPointName).registerExtension(extension) + } + + public fun getInstances(project: Project): Collection { + val projectArea = Extensions.getArea(project) + if (!projectArea.hasExtensionPoint(extensionPointName.getName()!!)) return listOf() + + return projectArea.getExtensionPoint(extensionPointName).getExtensions().toList() + } +} + diff --git a/plugins/android-compiler-plugin/android-compiler-plugin.iml b/plugins/android-compiler-plugin/android-compiler-plugin.iml index f8a2921965a..7f3d72c1033 100644 --- a/plugins/android-compiler-plugin/android-compiler-plugin.iml +++ b/plugins/android-compiler-plugin/android-compiler-plugin.iml @@ -11,6 +11,7 @@ + diff --git a/plugins/android-compiler-plugin/src/AndroidComponentRegistrar.kt b/plugins/android-compiler-plugin/src/AndroidComponentRegistrar.kt index 3fd4ddf39b9..7bcde46eafc 100644 --- a/plugins/android-compiler-plugin/src/AndroidComponentRegistrar.kt +++ b/plugins/android-compiler-plugin/src/AndroidComponentRegistrar.kt @@ -17,14 +17,18 @@ package org.jetbrains.kotlin.android import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar -import org.jetbrains.jet.lang.resolve.android.CliAndroidUIXmlProcessor import org.jetbrains.jet.config.CompilerConfiguration -import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor import com.intellij.mock.MockProject import org.jetbrains.jet.config.CompilerConfigurationKey import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor import org.jetbrains.kotlin.compiler.plugin.CliOption import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException +import org.jetbrains.jet.extensions.ExternalDeclarationsProvider +import org.jetbrains.jet.lang.psi.JetFile +import org.jetbrains.jet.lang.resolve.android.* +import com.intellij.openapi.components.ServiceManager +import org.jetbrains.jet.utils.emptyOrSingletonList +import com.intellij.openapi.project.Project public object AndroidConfigurationKeys { @@ -54,11 +58,20 @@ public class AndroidCommandLineProcessor : CommandLineProcessor { } } +public class AndroidDeclarationsProvider(private val project: Project) : ExternalDeclarationsProvider { + override fun getExternalDeclarations(): Collection { + val parser = ServiceManager.getService(project, javaClass()) + return emptyOrSingletonList(parser?.parseToPsi(project)) + } +} + public class AndroidComponentRegistrar : ComponentRegistrar { public override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { val androidResPath = configuration.get(AndroidConfigurationKeys.ANDROID_RES_PATH) val androidManifest = configuration.get(AndroidConfigurationKeys.ANDROID_MANIFEST) project.registerService(javaClass(), CliAndroidUIXmlProcessor(project, androidResPath, androidManifest)) + + ExternalDeclarationsProvider.registerExtension(project, AndroidDeclarationsProvider(project)) } } \ No newline at end of file diff --git a/plugins/android-compiler-plugin/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt b/plugins/android-compiler-plugin/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt index aefff285e29..463b2cf6ec8 100644 --- a/plugins/android-compiler-plugin/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt +++ b/plugins/android-compiler-plugin/src/org/jetbrains/jet/lang/resolve/android/AndroidUtil.kt @@ -21,9 +21,9 @@ import com.intellij.psi.PsiElement import com.intellij.openapi.project.Project import org.jetbrains.jet.lang.psi.JetFile import com.intellij.openapi.components.ServiceManager -import java.util.ArrayList import com.intellij.psi.PsiField import com.intellij.psi.PsiClass +import org.jetbrains.jet.utils.emptyOrSingletonList trait AndroidResource @@ -52,14 +52,6 @@ public fun isAndroidSyntheticElement(element: PsiElement?): Boolean { return isAndroidSyntheticFile(element?.getContainingFile()) } -public fun searchAndAddAndroidDeclarations(project: Project, originalFiles: Collection): Collection { - val parser = ServiceManager.getService(project, javaClass()) - val file = parser?.parseToPsi(project) - val files = ArrayList(originalFiles) - if (file != null) files.add(file) - return files -} - public fun isRClassField(element: PsiElement): Boolean { return if (element is PsiField) { val outerClass = element.getParent()?.getParent() diff --git a/plugins/android-idea-plugin/src/META-INF/plugin.xml b/plugins/android-idea-plugin/src/META-INF/plugin.xml index 64d20a2d225..2784221df50 100644 --- a/plugins/android-idea-plugin/src/META-INF/plugin.xml +++ b/plugins/android-idea-plugin/src/META-INF/plugin.xml @@ -15,4 +15,8 @@ + + + +