NoArg: Add compiler plugin
This commit is contained in:
committed by
Yan Zhulanow
parent
6abde4223b
commit
e626b121ad
Generated
+1
@@ -76,6 +76,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" group="plugins/lint" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" group="plugins/lint" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-idea/lint-idea.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-idea/lint-idea.iml" group="plugins/lint" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/non-compiler-tests/non-compiler-tests.iml" filepath="$PROJECT_DIR$/non-compiler-tests/non-compiler-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" filepath="$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/plugins-tests/plugins-tests.iml" filepath="$PROJECT_DIR$/plugins/plugins-tests/plugins-tests.iml" group="plugins" />
|
||||
|
||||
@@ -842,6 +842,29 @@
|
||||
<fileset dir="${basedir}/plugins/allopen/allopen-cli/src" includes="META-INF/services/**"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="noarg-compiler-plugin">
|
||||
<cleandir dir="${output}/classes/noarg-compiler-plugin"/>
|
||||
<javac2 destdir="${output}/classes/noarg-compiler-plugin" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<withKotlin modulename="noarg">
|
||||
<compilerarg value="-version"/>
|
||||
</withKotlin>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src>
|
||||
<pathelement path="plugins/noarg/noarg-cli/src"/>
|
||||
</src>
|
||||
<classpath>
|
||||
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
</javac2>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/noarg-compiler-plugin.jar">
|
||||
<fileset dir="${output}/classes/noarg-compiler-plugin"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
<fileset dir="${basedir}/plugins/noarg/noarg-cli/src" includes="META-INF/services/**"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="annotation-processing-under-jdk8">
|
||||
<property environment="env"/>
|
||||
@@ -1250,11 +1273,11 @@
|
||||
depends="builtins,stdlib,kotlin-test,core,reflection,pack-runtime,pack-runtime-sources,script-runtime,mock-runtime-for-test"/>
|
||||
|
||||
<target name="dist"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,kotlin-build-common,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,annotation-processing-under-jdk8,daemon-client,kotlin-build-common-test"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,kotlin-build-common,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,annotation-processing-under-jdk8,daemon-client,kotlin-build-common-test"
|
||||
description="Builds redistributables from sources"/>
|
||||
|
||||
<target name="dist-quick"
|
||||
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,annotation-processing-under-jdk8"
|
||||
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,annotation-processing-under-jdk8"
|
||||
description="Builds everything, but classes are reused from project out dir, doesn't run proguard and javadoc"/>
|
||||
|
||||
<target name="dist-quick-compiler-only"
|
||||
|
||||
@@ -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.extensions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
interface AnnotationBasedExtension {
|
||||
fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner): List<String>
|
||||
|
||||
fun DeclarationDescriptor.hasSpecialAnnotation(modifierListOwner: KtModifierListOwner): Boolean {
|
||||
if (annotations.any { it.isASpecialAnnotation(modifierListOwner) }) return true
|
||||
|
||||
if (this is ClassDescriptor) {
|
||||
for (superType in TypeUtils.getAllSupertypes(defaultType)) {
|
||||
val superTypeDescriptor = superType.constructor.declarationDescriptor as? ClassDescriptor ?: continue
|
||||
if (superTypeDescriptor.annotations.any { it.isASpecialAnnotation(modifierListOwner) }) return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun AnnotationDescriptor.isASpecialAnnotation(
|
||||
modifierListOwner: KtModifierListOwner,
|
||||
allowMetaAnnotations: Boolean = true
|
||||
): Boolean {
|
||||
val annotationType = type.constructor.declarationDescriptor ?: return false
|
||||
if (annotationType.fqNameSafe.asString() in getAnnotationFqNames(modifierListOwner)) return true
|
||||
|
||||
if (allowMetaAnnotations) {
|
||||
for (metaAnnotation in annotationType.annotations) {
|
||||
if (metaAnnotation.isASpecialAnnotation(modifierListOwner, allowMetaAnnotations = false)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -145,6 +145,7 @@ import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBytecodeSha
|
||||
import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidSyntheticPropertyDescriptorTest
|
||||
import org.jetbrains.kotlin.modules.xml.AbstractModuleXmlParserTest
|
||||
import org.jetbrains.kotlin.multiplatform.AbstractMultiPlatformIntegrationTest
|
||||
import org.jetbrains.kotlin.noarg.AbstractBytecodeListingTestForNoArg
|
||||
import org.jetbrains.kotlin.parsing.AbstractParsingTest
|
||||
import org.jetbrains.kotlin.psi.patternMatching.AbstractPsiUnifierTest
|
||||
import org.jetbrains.kotlin.renderer.AbstractDescriptorRendererTest
|
||||
@@ -1165,6 +1166,12 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("plugins/plugins-tests/tests", "plugins/noarg/noarg-cli/testData") {
|
||||
testClass<AbstractBytecodeListingTestForNoArg>() {
|
||||
model("bytecodeListing", extension = "kt")
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
|
||||
testClass<AbstractAndroidCompletionTest>() {
|
||||
model("android/completion", recursive = false, extension = null)
|
||||
|
||||
@@ -16,26 +16,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.allopen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.extensions.AnnotationBasedExtension
|
||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
class CliAllOpenDeclarationAttributeAltererExtension(
|
||||
private val allOpenAnnotationFqNames: List<String>
|
||||
) : AbstractAllOpenDeclarationAttributeAltererExtension() {
|
||||
override fun getAllOpenAnnotationFqNames(modifierListOwner: KtModifierListOwner) = allOpenAnnotationFqNames
|
||||
override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner) = allOpenAnnotationFqNames
|
||||
}
|
||||
|
||||
abstract class AbstractAllOpenDeclarationAttributeAltererExtension : DeclarationAttributeAltererExtension {
|
||||
abstract fun getAllOpenAnnotationFqNames(modifierListOwner: KtModifierListOwner): List<String>
|
||||
|
||||
abstract class AbstractAllOpenDeclarationAttributeAltererExtension : DeclarationAttributeAltererExtension, AnnotationBasedExtension {
|
||||
override fun refineDeclarationModality(
|
||||
modifierListOwner: KtModifierListOwner,
|
||||
declaration: DeclarationDescriptor?,
|
||||
@@ -49,43 +44,12 @@ abstract class AbstractAllOpenDeclarationAttributeAltererExtension : Declaration
|
||||
|
||||
// Explicit final
|
||||
if (modifierListOwner.hasModifier(KtTokens.FINAL_KEYWORD)) {
|
||||
return null
|
||||
return Modality.FINAL
|
||||
}
|
||||
|
||||
val descriptor = declaration ?: containingDeclaration ?: return null
|
||||
if (descriptor.hasAllOpenAnnotation(modifierListOwner)) return Modality.OPEN
|
||||
if (descriptor.hasSpecialAnnotation(modifierListOwner)) return Modality.OPEN
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.hasAllOpenAnnotation(modifierListOwner: KtModifierListOwner): Boolean {
|
||||
if (annotations.any { it.isAllOpenAnnotation(modifierListOwner) }) return true
|
||||
|
||||
if (this is ClassDescriptor) {
|
||||
for (superType in TypeUtils.getAllSupertypes(defaultType)) {
|
||||
val superTypeDescriptor = superType.constructor.declarationDescriptor as? ClassDescriptor ?: continue
|
||||
if (superTypeDescriptor.annotations.any { it.isAllOpenAnnotation(modifierListOwner) }) return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun AnnotationDescriptor.isAllOpenAnnotation(
|
||||
modifierListOwner: KtModifierListOwner,
|
||||
allowMetaAnnotations: Boolean = true
|
||||
): Boolean {
|
||||
val annotationType = type.constructor.declarationDescriptor ?: return false
|
||||
if (annotationType.fqNameSafe.asString() in getAllOpenAnnotationFqNames(modifierListOwner)) return true
|
||||
|
||||
if (allowMetaAnnotations) {
|
||||
for (metaAnnotation in annotationType.annotations) {
|
||||
if (metaAnnotation.isAllOpenAnnotation(modifierListOwner, allowMetaAnnotations = false)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.allopen.ide
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||
@@ -39,11 +40,8 @@ class IdeAllOpenDeclarationAttributeAltererExtension(val project: Project) : Abs
|
||||
CachedValueProvider.Result.create(WeakHashMap<Module, List<String>>(), ProjectRootModificationTracker.getInstance(project))
|
||||
}
|
||||
|
||||
override fun getAllOpenAnnotationFqNames(modifierListOwner: KtModifierListOwner): List<String> {
|
||||
val project = modifierListOwner.project
|
||||
|
||||
val virtualFile = modifierListOwner.containingFile?.virtualFile ?: return emptyList()
|
||||
val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(virtualFile) ?: return emptyList()
|
||||
override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner): List<String> {
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(modifierListOwner) ?: return emptyList()
|
||||
|
||||
return cache.value.getOrPut(module) {
|
||||
val kotlinFacet = KotlinFacet.get(module) ?: return@getOrPut emptyList()
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="module" module-name="backend" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
</component>
|
||||
</module>
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.noarg.NoArgCommandLineProcessor
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.noarg.NoArgComponentRegistrar
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactory
|
||||
import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
|
||||
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<String>
|
||||
) : AbstractNoArgClassBuilderInterceptorExtension() {
|
||||
override fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner) = noArgAnnotationFqNames
|
||||
}
|
||||
|
||||
abstract class AbstractNoArgClassBuilderInterceptorExtension : ClassBuilderInterceptorExtension, AnnotationBasedExtension {
|
||||
override fun interceptClassBuilderFactory(
|
||||
interceptedFactory: ClassBuilderFactory,
|
||||
bindingContext: BindingContext,
|
||||
diagnostics: DiagnosticSink
|
||||
): ClassBuilderFactory = NoArgClassBuilderFactory(interceptedFactory, bindingContext)
|
||||
|
||||
private inner class NoArgClassBuilderFactory(
|
||||
private val delegateFactory: ClassBuilderFactory,
|
||||
val bindingContext: BindingContext
|
||||
) : ClassBuilderFactory {
|
||||
|
||||
override fun newClassBuilder(origin: JvmDeclarationOrigin): ClassBuilder {
|
||||
return AllOpenClassBuilder(delegateFactory.newClassBuilder(origin), bindingContext)
|
||||
}
|
||||
|
||||
override fun getClassBuilderMode() = delegateFactory.classBuilderMode
|
||||
|
||||
override fun asText(builder: ClassBuilder?): String? {
|
||||
return delegateFactory.asText((builder as AllOpenClassBuilder).delegateClassBuilder)
|
||||
}
|
||||
|
||||
override fun asBytes(builder: ClassBuilder?): ByteArray? {
|
||||
return delegateFactory.asBytes((builder as AllOpenClassBuilder).delegateClassBuilder)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
delegateFactory.close()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class AllOpenClassBuilder(
|
||||
internal val delegateClassBuilder: ClassBuilder,
|
||||
val bindingContext: BindingContext
|
||||
) : DelegatingClassBuilder() {
|
||||
override fun getDelegate() = delegateClassBuilder
|
||||
|
||||
private var superClassInternalName = ""
|
||||
private var hasSpecialAnnotation = false
|
||||
private var noArgConstructorGenerated = false
|
||||
|
||||
override fun defineClass(
|
||||
origin: PsiElement?,
|
||||
version: Int,
|
||||
access: Int,
|
||||
name: String,
|
||||
signature: String?,
|
||||
superName: String,
|
||||
interfaces: Array<out String>
|
||||
) {
|
||||
super.defineClass(origin, version, access, name, signature, superName, interfaces)
|
||||
|
||||
hasSpecialAnnotation = false
|
||||
noArgConstructorGenerated = false
|
||||
superClassInternalName = superName
|
||||
|
||||
if (origin is KtClass) {
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, origin] as? ClassDescriptor
|
||||
if (descriptor != null && descriptor.kind == ClassKind.CLASS && descriptor.hasSpecialAnnotation (origin)) {
|
||||
hasSpecialAnnotation = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun newMethod(
|
||||
origin: JvmDeclarationOrigin,
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String,
|
||||
signature: String?,
|
||||
exceptions: Array<out String>?
|
||||
): MethodVisitor {
|
||||
if (name == "<init>" && desc == "()V") {
|
||||
noArgConstructorGenerated = true
|
||||
}
|
||||
|
||||
return super.newMethod(origin, access, name, desc, signature, exceptions)
|
||||
}
|
||||
|
||||
override fun done() {
|
||||
val superClassInternalName = this.superClassInternalName
|
||||
if (hasSpecialAnnotation && !noArgConstructorGenerated && superClassInternalName.isNotEmpty()) {
|
||||
super.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null).apply {
|
||||
visitCode()
|
||||
visitVarInsn(Opcodes.ALOAD, 0)
|
||||
visitMethodInsn(Opcodes.INVOKESPECIAL, superClassInternalName, "<init>", "()V", false)
|
||||
visitInsn(Opcodes.RETURN)
|
||||
visitMaxs(1, 1)
|
||||
visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
super.done()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.mock.MockProject
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
||||
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
|
||||
|
||||
object NoArgConfigurationKeys {
|
||||
val ANNOTATION: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create("annotation qualified name")
|
||||
}
|
||||
|
||||
class NoArgCommandLineProcessor : CommandLineProcessor {
|
||||
companion object {
|
||||
val PLUGIN_ID = "org.jetbrains.kotlin.noarg"
|
||||
|
||||
val ANNOTATION_OPTION = CliOption("annotation", "<fqname>", "Annotation qualified names",
|
||||
required = false, allowMultipleOccurrences = true)
|
||||
}
|
||||
|
||||
override val pluginId = "org.jetbrains.kotlin.noarg"
|
||||
override val pluginOptions = listOf(ANNOTATION_OPTION)
|
||||
|
||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) = when (option) {
|
||||
ANNOTATION_OPTION -> {
|
||||
val paths = configuration.getList(NoArgConfigurationKeys.ANNOTATION).toMutableList()
|
||||
paths.add(value)
|
||||
configuration.put(NoArgConfigurationKeys.ANNOTATION, paths)
|
||||
}
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
}
|
||||
}
|
||||
|
||||
class NoArgComponentRegistrar : ComponentRegistrar {
|
||||
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||
val annotations = configuration.get(NoArgConfigurationKeys.ANNOTATION) ?: return
|
||||
if (annotations.isEmpty()) return
|
||||
|
||||
ClassBuilderInterceptorExtension.registerExtension(project, CliNoArgClassBuilderInterceptorExtension(annotations))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
@NoArg
|
||||
annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
interface Intf
|
||||
|
||||
@NoArg
|
||||
enum class Colors { RED, WHITE }
|
||||
|
||||
@NoArg
|
||||
object Obj
|
||||
|
||||
class MyClass(a: Int) {
|
||||
@NoArg
|
||||
fun someFun() {}
|
||||
|
||||
@field:NoArg @get:NoArg @set:NoArg
|
||||
var abc: String = ""
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public final enum class Colors {
|
||||
private synthetic final static field $VALUES: Colors[]
|
||||
public final static field RED: Colors
|
||||
public final static field WHITE: Colors
|
||||
static method <clinit>(): void
|
||||
protected method <init>(p0: java.lang.String, p1: int): void
|
||||
public static method valueOf(p0: java.lang.String): Colors
|
||||
public static method values(): Colors[]
|
||||
}
|
||||
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public interface Intf
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class MyClass {
|
||||
private @NoArg @org.jetbrains.annotations.NotNull field abc: java.lang.String
|
||||
public method <init>(p0: int): void
|
||||
public final @NoArg @org.jetbrains.annotations.NotNull method getAbc(): java.lang.String
|
||||
public final @NoArg method setAbc(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
public final @NoArg method someFun(): void
|
||||
}
|
||||
|
||||
@NoArg
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public final class Obj {
|
||||
public final static field INSTANCE: Obj
|
||||
static method <clinit>(): void
|
||||
private method <init>(): void
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
annotation class MetaAnno
|
||||
|
||||
@NoArg
|
||||
interface BaseIntf
|
||||
|
||||
@NoArg
|
||||
class Test(a: String = "", i: Int = 2)
|
||||
|
||||
class Test2 : BaseIntf {
|
||||
constructor(a: String = "", b: Long = 0L) {}
|
||||
}
|
||||
|
||||
@MetaAnno
|
||||
class Test3(a: String) {
|
||||
constructor() : this("") {}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public interface BaseIntf
|
||||
|
||||
@NoArg
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class MetaAnno
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public final class Test {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: int): void
|
||||
public synthetic method <init>(p0: java.lang.String, p1: int, p2: int, p3: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Test2 {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: long): void
|
||||
public synthetic method <init>(p0: java.lang.String, p1: long, p2: int, p3: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
}
|
||||
|
||||
@MetaAnno
|
||||
@kotlin.Metadata
|
||||
public final class Test3 {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
annotation class MyAnno
|
||||
|
||||
@MyAnno
|
||||
interface Base
|
||||
|
||||
@MyAnno
|
||||
class Test(a: String) : Base
|
||||
@@ -0,0 +1,19 @@
|
||||
@MyAnno
|
||||
@kotlin.Metadata
|
||||
public interface Base
|
||||
|
||||
@NoArg
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class MyAnno
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@MyAnno
|
||||
@kotlin.Metadata
|
||||
public final class Test {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
annotation class NoArg
|
||||
|
||||
class Test(a: String)
|
||||
@@ -0,0 +1,8 @@
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Test {
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
annotation class NoArg
|
||||
annotation class NoArg2
|
||||
|
||||
@NoArg @NoArg2
|
||||
class Test(a: String)
|
||||
@@ -0,0 +1,15 @@
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg2
|
||||
|
||||
@NoArg
|
||||
@NoArg2
|
||||
@kotlin.Metadata
|
||||
public final class Test {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
class Test(a: String)
|
||||
@@ -0,0 +1,10 @@
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public final class Test {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
annotation class NoArg
|
||||
|
||||
@NoArg
|
||||
interface BaseIntf
|
||||
|
||||
open class Test1(a: String) : BaseIntf
|
||||
|
||||
class Test12(b: Int) : Test1("")
|
||||
|
||||
@NoArg
|
||||
abstract class BaseClass
|
||||
|
||||
class MyClass(a: String) : BaseClass()
|
||||
@@ -0,0 +1,31 @@
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public abstract class BaseClass {
|
||||
public method <init>(): void
|
||||
}
|
||||
|
||||
@NoArg
|
||||
@kotlin.Metadata
|
||||
public interface BaseIntf
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class MyClass {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class NoArg
|
||||
|
||||
@kotlin.Metadata
|
||||
public class Test1 {
|
||||
public method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Test12 {
|
||||
public method <init>(): void
|
||||
public method <init>(p0: int): void
|
||||
}
|
||||
@@ -38,5 +38,6 @@
|
||||
<orderEntry type="module" module-name="jps-tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="kapt3" scope="TEST" />
|
||||
<orderEntry type="module" module-name="allopen-cli" scope="TEST" />
|
||||
<orderEntry type="module" module-name="noarg-cli" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.extensions.Extensions
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.codegen.AbstractBytecodeListingTest
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg
|
||||
|
||||
abstract class AbstractBytecodeListingTestForNoArg : AbstractBytecodeListingTest() {
|
||||
private companion object {
|
||||
val NOARG_ANNOTATIONS = listOf("NoArg", "NoArg2", "test.NoArg")
|
||||
}
|
||||
|
||||
override fun setupEnvironment(environment: KotlinCoreEnvironment) {
|
||||
Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesNoArg())
|
||||
StorageComponentContainerContributor.registerExtension(environment.project, CliNoArgComponentContainerContributor(NOARG_ANNOTATIONS))
|
||||
ClassBuilderInterceptorExtension.registerExtension(environment.project, NoArgClassBuilderInterceptorExtension())
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class BytecodeListingTestForNoArgGenerated extends AbstractBytecodeListingTestForNoArg {
|
||||
public void testAllFilesPresentInBytecodeListing() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/noarg/noarg-cli/testData/bytecodeListing"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annoOnNotClass.kt")
|
||||
public void testAnnoOnNotClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/annoOnNotClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParameters.kt")
|
||||
public void testDefaultParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/defaultParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inherited.kt")
|
||||
public void testInherited() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/inherited.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noNoArg.kt")
|
||||
public void testNoNoArg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/noNoArg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("severalNoArg.kt")
|
||||
public void testSeveralNoArg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/severalNoArg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superTypes.kt")
|
||||
public void testSuperTypes() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/noarg/noarg-cli/testData/bytecodeListing/superTypes.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user