diff --git a/.idea/artifacts/KotlinPlugin.xml b/.idea/artifacts/KotlinPlugin.xml index 91e7055017f..7d68ec67b24 100644 --- a/.idea/artifacts/KotlinPlugin.xml +++ b/.idea/artifacts/KotlinPlugin.xml @@ -86,6 +86,12 @@ + + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml index 4bd955523f5..ee900a4aa0d 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -77,6 +77,7 @@ + diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java index 787c6c8ad21..a3ee57bf325 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java +++ b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPaths.java @@ -51,6 +51,9 @@ public interface KotlinPaths { @NotNull File getAllOpenPluginJarPath(); + @NotNull + File getNoArgPluginJarPath(); + @NotNull File getCompilerPath(); diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java index afd05e5ebe6..7159b40f4ab 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java +++ b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinPathsFromHomeDir.java @@ -88,6 +88,12 @@ public class KotlinPathsFromHomeDir implements KotlinPaths { return getLibraryFile(PathUtil.ALLOPEN_PLUGIN_JAR_NAME); } + @NotNull + @Override + public File getNoArgPluginJarPath() { + return getLibraryFile(PathUtil.NOARG_PLUGIN_JAR_NAME); + } + @NotNull @Override public File getCompilerPath() { diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java b/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java index 3bce0e86d01..7cba9fc3239 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/kotlin/utils/PathUtil.java @@ -30,6 +30,7 @@ public class PathUtil { public static final String JS_LIB_JAR_NAME = "kotlin-jslib.jar"; public static final String ALLOPEN_PLUGIN_JAR_NAME = "allopen-compiler-plugin.jar"; + public static final String NOARG_PLUGIN_JAR_NAME = "noarg-compiler-plugin.jar"; public static final String JS_LIB_SRC_JAR_NAME = "kotlin-jslib-sources.jar"; public static final String KOTLIN_JAVA_RUNTIME_JAR = "kotlin-runtime.jar"; public static final String KOTLIN_JAVA_REFLECT_JAR = "kotlin-reflect.jar"; diff --git a/idea/src/META-INF/gradle.xml b/idea/src/META-INF/gradle.xml index aedc0407b42..5f861ec32b6 100644 --- a/idea/src/META-INF/gradle.xml +++ b/idea/src/META-INF/gradle.xml @@ -36,6 +36,8 @@ + + diff --git a/idea/src/META-INF/maven.xml b/idea/src/META-INF/maven.xml index 09f2d439b63..a5d3014eed2 100644 --- a/idea/src/META-INF/maven.xml +++ b/idea/src/META-INF/maven.xml @@ -4,6 +4,7 @@ + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 0ff79f1151f..4528b47d0c2 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2016,6 +2016,10 @@ + + + + diff --git a/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt b/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt index 72774c8125b..7505f98322c 100644 --- a/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt +++ b/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.noarg.gradle import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.internal.AbstractTask +import org.gradle.api.artifacts.ResolvedArtifact import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.compile.AbstractCompile @@ -34,6 +35,9 @@ class NoArgGradleSubplugin : Plugin { } } + fun Project.getBuildscriptArtifacts(): Set = + buildscript.configurations.findByName("classpath")?.resolvedConfiguration?.resolvedArtifacts ?: emptySet() + override fun apply(project: Project) { val noArgExtension = project.extensions.create("noArg", NoArgExtension::class.java) @@ -41,10 +45,18 @@ class NoArgGradleSubplugin : Plugin { val fqNamesAsString = noArgExtension.myAnnotations.joinToString(",") project.extensions.extraProperties.set("kotlinNoArgAnnotations", fqNamesAsString) - open class TaskForAllOpen : AbstractTask() - project.tasks.add(project.tasks.create("noArgDataStorageTask", TaskForAllOpen::class.java).apply { + val allBuildscriptArtifacts = project.getBuildscriptArtifacts() + project.rootProject.getBuildscriptArtifacts() + val noArgCompilerPluginFile = allBuildscriptArtifacts.filter { + val id = it.moduleVersion.id + id.group == NoArgKotlinGradleSubplugin.NOARG_GROUP_NAME + && id.name == NoArgKotlinGradleSubplugin.NOARG_ARTIFACT_NAME + }.firstOrNull()?.file?.absolutePath ?: "" + + open class TaskForNoArg : AbstractTask() + project.tasks.add(project.tasks.create("noArgDataStorageTask", TaskForNoArg::class.java).apply { isEnabled = false - description = "Supported no-arg annotations: " + fqNamesAsString + description = "Supported annotations: " + fqNamesAsString + + "; Compiler plugin classpath: $noArgCompilerPluginFile" }) } } @@ -58,7 +70,7 @@ class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin { private val ANNOTATIONS_ARG_NAME = "annotation" } - override fun isApplicable(project: Project, task: AbstractCompile) = AllOpenGradleSubplugin.isEnabled(project) + override fun isApplicable(project: Project, task: AbstractCompile) = NoArgGradleSubplugin.isEnabled(project) override fun apply( project: Project, @@ -69,11 +81,11 @@ class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin { ): List { if (!NoArgGradleSubplugin.isEnabled(project)) return emptyList() - val allOpenExtension = project.extensions.findByType(AllOpenExtension::class.java) ?: return emptyList() + val noArgExtension = project.extensions.findByType(NoArgExtension::class.java) ?: return emptyList() val options = mutableListOf() - for (anno in allOpenExtension.myAnnotations) { + for (anno in noArgExtension.myAnnotations) { options += SubpluginOption(ANNOTATIONS_ARG_NAME, anno) } @@ -82,5 +94,5 @@ class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin { override fun getArtifactName() = "kotlin-noarg" override fun getGroupName() = "org.jetbrains.kotlin" - override fun getPluginName() = "org.jetbrains.kotlin.noarg" + override fun getCompilerPluginId() = "org.jetbrains.kotlin.noarg" } \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/noarg-cli.iml b/plugins/noarg/noarg-cli/noarg-cli.iml index 78dc34b41a7..4e3bbad80a6 100644 --- a/plugins/noarg/noarg-cli/noarg-cli.iml +++ b/plugins/noarg/noarg-cli/noarg-cli.iml @@ -11,5 +11,6 @@ + \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/src/NoArgClassBuilderInterceptorExtension.kt b/plugins/noarg/noarg-cli/src/NoArgClassBuilderInterceptorExtension.kt index 3bb9ae79dad..0f0d07c3855 100644 --- a/plugins/noarg/noarg-cli/src/NoArgClassBuilderInterceptorExtension.kt +++ b/plugins/noarg/noarg-cli/src/NoArgClassBuilderInterceptorExtension.kt @@ -24,21 +24,13 @@ import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.diagnostics.DiagnosticSink -import org.jetbrains.kotlin.extensions.AnnotationBasedExtension import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes -class CliNoArgClassBuilderInterceptorExtension( - private val noArgAnnotationFqNames: List -) : AbstractNoArgClassBuilderInterceptorExtension() { - override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner) = noArgAnnotationFqNames -} - -abstract class AbstractNoArgClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension, AnnotationBasedExtension { +class NoArgClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension { override fun interceptClassBuilderFactory( interceptedFactory: ClassBuilderFactory, bindingContext: BindingContext, @@ -96,12 +88,14 @@ abstract class AbstractNoArgClassBuilderInterceptorExtension : ClassBuilderInter if (origin is KtClass) { val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, origin] as? ClassDescriptor - if (descriptor != null && descriptor.kind == ClassKind.CLASS && descriptor.hasSpecialAnnotation (origin)) { + if (descriptor != null && descriptor.kind == ClassKind.CLASS && origin.isNoArgClass()) { hasSpecialAnnotation = true } } } + private fun KtClass.isNoArgClass() = this.getUserData(NO_ARG_CLASS_KEY) ?: false + override fun newMethod( origin: JvmDeclarationOrigin, access: Int, diff --git a/plugins/noarg/noarg-cli/src/NoArgClassKey.kt b/plugins/noarg/noarg-cli/src/NoArgClassKey.kt new file mode 100644 index 00000000000..e7daf12b785 --- /dev/null +++ b/plugins/noarg/noarg-cli/src/NoArgClassKey.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg + +import com.intellij.openapi.util.Key + +val NO_ARG_CLASS_KEY = Key("org.jetbrains.kotlin.noarg.NoArgClassKey") \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/src/NoArgPlugin.kt b/plugins/noarg/noarg-cli/src/NoArgPlugin.kt index 0359d9fa699..a5ab81d5ae8 100644 --- a/plugins/noarg/noarg-cli/src/NoArgPlugin.kt +++ b/plugins/noarg/noarg-cli/src/NoArgPlugin.kt @@ -17,6 +17,8 @@ package org.jetbrains.kotlin.noarg import com.intellij.mock.MockProject +import com.intellij.openapi.extensions.Extensions +import org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.compiler.plugin.CliOption import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException @@ -24,6 +26,13 @@ import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey +import org.jetbrains.kotlin.container.StorageComponentContainer +import org.jetbrains.kotlin.container.useInstance +import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages +import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor +import org.jetbrains.kotlin.noarg.diagnostic.CliNoArgDeclarationChecker +import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform object NoArgConfigurationKeys { val ANNOTATION: CompilerConfigurationKey> = @@ -38,7 +47,7 @@ class NoArgCommandLineProcessor : CommandLineProcessor { required = false, allowMultipleOccurrences = true) } - override val pluginId = "org.jetbrains.kotlin.noarg" + override val pluginId = PLUGIN_ID override val pluginOptions = listOf(ANNOTATION_OPTION) override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) = when (option) { @@ -56,6 +65,17 @@ class NoArgComponentRegistrar : ComponentRegistrar { val annotations = configuration.get(NoArgConfigurationKeys.ANNOTATION) ?: return if (annotations.isEmpty()) return - ClassBuilderInterceptorExtension.registerExtension(project, CliNoArgClassBuilderInterceptorExtension(annotations)) + Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesNoArg()) + StorageComponentContainerContributor.registerExtension(project, CliNoArgComponentContainerContributor(annotations)) + + ClassBuilderInterceptorExtension.registerExtension(project, NoArgClassBuilderInterceptorExtension()) + } +} + +class CliNoArgComponentContainerContributor(val annotations: List) : StorageComponentContainerContributor { + override fun addDeclarations(container: StorageComponentContainer, platform: TargetPlatform) { + if (platform is JvmPlatform) { + container.useInstance(CliNoArgDeclarationChecker(annotations)) + } } } \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt new file mode 100644 index 00000000000..2e55f00d35b --- /dev/null +++ b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.diagnostic + +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.extensions.AnnotationBasedExtension +import org.jetbrains.kotlin.noarg.NO_ARG_CLASS_KEY +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker +import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny +import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue + +class CliNoArgDeclarationChecker(val noArgAnnotationFqNames: List) : AbstractNoArgDeclarationChecker() { + override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner) = noArgAnnotationFqNames +} + +abstract class AbstractNoArgDeclarationChecker : DeclarationChecker, AnnotationBasedExtension { + override fun check( + declaration: KtDeclaration, + descriptor: DeclarationDescriptor, + diagnosticHolder: DiagnosticSink, + bindingContext: BindingContext, + languageVersionSettings: LanguageVersionSettings + ) { + // Handle only classes + if (descriptor !is ClassDescriptor || declaration !is KtClass) return + if (descriptor.kind != ClassKind.CLASS) return + + val hasSpecialAnnotation = descriptor.hasSpecialAnnotation(declaration) + declaration.putUserData(NO_ARG_CLASS_KEY, hasSpecialAnnotation) + if (hasSpecialAnnotation) { + val superClass = descriptor.getSuperClassOrAny() + if (superClass.constructors.none { it.isNoArgConstructor() } && !superClass.hasSpecialAnnotation(declaration)) { + val reportTarget = declaration.nameIdentifier ?: declaration.getClassOrInterfaceKeyword() ?: declaration + diagnosticHolder.report(ErrorsNoArg.NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS.on(reportTarget)) + } + } + } + + private fun ConstructorDescriptor.isNoArgConstructor() = (valueParameters.isEmpty()) || valueParameters.all { it.hasDefaultValue() } +} \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt new file mode 100644 index 00000000000..6de21ade399 --- /dev/null +++ b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/DefaultErrorMessagesNoArg.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.diagnostic + +import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages +import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap + +class DefaultErrorMessagesNoArg : DefaultErrorMessages.Extension { + private companion object { + val MAP = DiagnosticFactoryToRendererMap("AnnotationProcessing") + + init { + MAP.put(ErrorsNoArg.NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS, "Zero-argument constructor was not found in the superclass") + } + } + + override fun getMap() = MAP +} \ No newline at end of file diff --git a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/ErrorsNoArg.java b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/ErrorsNoArg.java new file mode 100644 index 00000000000..bf984dbbfdd --- /dev/null +++ b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/ErrorsNoArg.java @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.diagnostic; + +import com.intellij.psi.PsiElement; +import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0; +import org.jetbrains.kotlin.diagnostics.Errors; + +import static org.jetbrains.kotlin.diagnostics.Severity.WARNING; + +public interface ErrorsNoArg { + DiagnosticFactory0 NO_NOARG_CONSTRUCTOR_IN_SUPERCLASS = DiagnosticFactory0.create(WARNING); + + @SuppressWarnings("UnusedDeclaration") + Object _initializer = new Object() { + { + Errors.Initializer.initializeFactoryNames(ErrorsNoArg.class); + } + }; + +} diff --git a/plugins/noarg/noarg-ide/noarg-ide.iml b/plugins/noarg/noarg-ide/noarg-ide.iml new file mode 100644 index 00000000000..3bae23383a3 --- /dev/null +++ b/plugins/noarg/noarg-ide/noarg-ide.iml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt b/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt new file mode 100644 index 00000000000..04614cec42c --- /dev/null +++ b/plugins/noarg/noarg-ide/src/IdeNoArgDeclarationChecker.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.ide + +import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleUtilCore +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootModificationTracker +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import org.jetbrains.kotlin.idea.facet.KotlinFacet +import org.jetbrains.kotlin.noarg.diagnostic.AbstractNoArgDeclarationChecker +import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor.Companion.PLUGIN_ID +import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor.Companion.ANNOTATION_OPTION +import org.jetbrains.kotlin.psi.KtModifierListOwner +import java.util.* + +class IdeNoArgDeclarationChecker(val project: Project) : AbstractNoArgDeclarationChecker() { + private companion object { + val ANNOTATION_OPTION_PREFIX = "plugin:$PLUGIN_ID:${ANNOTATION_OPTION.name}=" + } + + private val cache: CachedValue>> = cachedValue(project) { + CachedValueProvider.Result.create(WeakHashMap>(), ProjectRootModificationTracker.getInstance(project)) + } + + override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner): List { + val module = ModuleUtilCore.findModuleForPsiElement(modifierListOwner) ?: return emptyList() + + return cache.value.getOrPut(module) { + val kotlinFacet = KotlinFacet.get(module) ?: return@getOrPut emptyList() + val commonArgs = kotlinFacet.configuration.settings.compilerInfo.commonCompilerArguments ?: return@getOrPut emptyList() + + commonArgs.pluginOptions + ?.filter { it.startsWith(ANNOTATION_OPTION_PREFIX) } + ?.map { it.substring(ANNOTATION_OPTION_PREFIX.length) } + ?: emptyList() + } + } + + private fun cachedValue(project: Project, result: () -> CachedValueProvider.Result): CachedValue { + return CachedValuesManager.getManager(project).createCachedValue(result, false) + } +} \ No newline at end of file diff --git a/plugins/noarg/noarg-ide/src/IdeStorageComponentContainerContributor.kt b/plugins/noarg/noarg-ide/src/IdeStorageComponentContainerContributor.kt new file mode 100644 index 00000000000..b04cb8aa031 --- /dev/null +++ b/plugins/noarg/noarg-ide/src/IdeStorageComponentContainerContributor.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.ide + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.container.StorageComponentContainer +import org.jetbrains.kotlin.container.useInstance +import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor +import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform + +class IdeNoArgComponentContainerContributor(val project: Project) : StorageComponentContainerContributor { + override fun addDeclarations(container: StorageComponentContainer, platform: TargetPlatform) { + if (platform is JvmPlatform) { + container.useInstance(IdeNoArgDeclarationChecker(project)) + } + } +} \ No newline at end of file diff --git a/plugins/noarg/noarg-ide/src/NoArgGradleProjectImportHandler.kt b/plugins/noarg/noarg-ide/src/NoArgGradleProjectImportHandler.kt new file mode 100644 index 00000000000..ef60c31a576 --- /dev/null +++ b/plugins/noarg/noarg-ide/src/NoArgGradleProjectImportHandler.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.ide + +import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor +import org.jetbrains.kotlin.annotation.plugin.ide.AbstractGradleImportHandler +import org.jetbrains.kotlin.utils.PathUtil + +class NoArgGradleProjectImportHandler : AbstractGradleImportHandler() { + override val compilerPluginId = NoArgCommandLineProcessor.PLUGIN_ID + override val pluginName = "noarg" + override val annotationOptionName = NoArgCommandLineProcessor.ANNOTATION_OPTION.name + override val dataStorageTaskName = "noArgDataStorageTask" + override val pluginJarFileFromIdea = PathUtil.getKotlinPathsForIdeaPlugin().noArgPluginJarPath +} \ No newline at end of file diff --git a/plugins/noarg/noarg-ide/src/NoArgMavenProjectImportHandler.kt b/plugins/noarg/noarg-ide/src/NoArgMavenProjectImportHandler.kt new file mode 100644 index 00000000000..1a8ef64d1a1 --- /dev/null +++ b/plugins/noarg/noarg-ide/src/NoArgMavenProjectImportHandler.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2016 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.kotlin.noarg.ide + +import org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor +import org.jetbrains.kotlin.annotation.plugin.ide.AbstractMavenImportHandler + +class NoArgMavenProjectImportHandler : AbstractMavenImportHandler() { + private companion object { + val ANNOTATATION_PARAMETER_PREFIX = "no-arg:${NoArgCommandLineProcessor.ANNOTATION_OPTION.name}=" + private val JPA_NOARG_ANNOTATIONS = listOf("javax.persistence.Entity") + } + + override val compilerPluginId = NoArgCommandLineProcessor.PLUGIN_ID + override val pluginName = "noarg" + override val annotationOptionName = NoArgCommandLineProcessor.ANNOTATION_OPTION.name + override val mavenPluginArtifactName = "kotlin-maven-noarg" + + override fun getAnnotations(enabledCompilerPlugins: List, compilerPluginOptions: List): List? { + if ("no-arg" !in enabledCompilerPlugins && "jpa" !in enabledCompilerPlugins) { + return null + } + + val annotations = mutableListOf() + if ("jpa" in enabledCompilerPlugins) { + annotations.addAll(JPA_NOARG_ANNOTATIONS) + } + + annotations.addAll(compilerPluginOptions.mapNotNull { text -> + if (!text.startsWith(ANNOTATATION_PARAMETER_PREFIX)) return@mapNotNull null + text.substring(ANNOTATATION_PARAMETER_PREFIX.length) + }) + + return annotations + } +} \ No newline at end of file