From 471ddc5a93186f54a26956feafa9cb3a7c99d89d Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 2 Sep 2016 18:37:25 +0300 Subject: [PATCH] Kapt: Write annotations with the "SOURCE" retention if kapt2 is enabled (cherry picked from commit 6177b2b) --- .../kotlin/codegen/AnnotationCodegen.java | 14 ++-- .../kotlin/codegen/ClassBuilderFactories.java | 71 +++++++++++-------- .../kotlin/codegen/ClassBuilderMode.java | 41 +++++++++-- .../kotlin/codegen/ClosureCodegen.java | 6 +- .../DefaultParameterValueSubstitutor.kt | 2 +- .../kotlin/codegen/FunctionCodegen.java | 6 +- .../codegen/ImplementationBodyCodegen.java | 20 +++--- .../kotlin/codegen/KotlinCodegenFacade.java | 2 +- .../kotlin/codegen/MemberCodegen.java | 11 ++- .../kotlin/codegen/MultifileClassCodegen.kt | 4 +- .../codegen/MultifileClassPartCodegen.kt | 4 +- .../kotlin/codegen/PackagePartCodegen.java | 2 +- .../kotlin/codegen/PropertyCodegen.java | 2 +- .../codegen/PropertyReferenceCodegen.kt | 2 +- .../kotlin/codegen/SamWrapperCodegen.java | 2 +- .../kotlin/codegen/ScriptCodegen.java | 2 +- .../codegen/state/KotlinTypeMapper.java | 6 +- .../compiler/KotlinToJVMBytecodeCompiler.kt | 15 ++-- .../kotlin/cli/jvm/config/Kapt2EnabledKey.kt} | 7 +- .../kotlin/cli/jvm/repl/ReplInterpreter.kt | 9 ++- .../codegen/AbstractBytecodeListingTest.kt | 5 +- .../kotlin/codegen/CodegenTestUtil.java | 10 ++- .../kotlin/generators/tests/GenerateTests.kt | 5 ++ .../evaluate/KotlinEvaluationBuilder.kt | 2 +- .../annotation-processing.iml | 1 + .../processing/AnnotationProcessingPlugin.kt | 20 +++--- .../testData/sourceRetention/withSource.kt | 15 ++++ .../testData/sourceRetention/withSource.txt | 22 ++++++ .../testData/sourceRetention/withoutSource.kt | 15 ++++ .../sourceRetention/withoutSource.txt | 21 ++++++ ...ctBytecodeListingTestForSourceRetention.kt | 31 ++++++++ ...istingTestForSourceRetentionGenerated.java | 49 +++++++++++++ 32 files changed, 317 insertions(+), 107 deletions(-) rename compiler/{backend/src/org/jetbrains/kotlin/codegen/classBuilderModeUtil.kt => cli/src/org/jetbrains/kotlin/cli/jvm/config/Kapt2EnabledKey.kt} (79%) create mode 100644 plugins/annotation-processing/testData/sourceRetention/withSource.kt create mode 100644 plugins/annotation-processing/testData/sourceRetention/withSource.txt create mode 100644 plugins/annotation-processing/testData/sourceRetention/withoutSource.kt create mode 100644 plugins/annotation-processing/testData/sourceRetention/withoutSource.txt create mode 100644 plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/AbstractBytecodeListingTestForSourceRetention.kt create mode 100644 plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/BytecodeListingTestForSourceRetentionGenerated.java diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 304fc6126ac..d74a8f7d62a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -281,7 +281,7 @@ public abstract class AnnotationCodegen { ClassifierDescriptor classifierDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor; RetentionPolicy rp = getRetentionPolicy(classifierDescriptor); - if (rp == RetentionPolicy.SOURCE && typeMapper.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (rp == RetentionPolicy.SOURCE && !typeMapper.getClassBuilderMode().generateSourceRetentionAnnotations) { return null; } @@ -407,14 +407,10 @@ public abstract class AnnotationCodegen { private Void visitUnsupportedValue(ConstantValue value) { ClassBuilderMode mode = typeMapper.getClassBuilderMode(); - switch (mode) { - case FULL: - throw new IllegalStateException("Don't know how to compile annotation value " + value); - case LIGHT_CLASSES: - case KAPT: - return null; - default: - throw new IllegalStateException("Unknown builder mode: " + mode); + if (mode.generateBodies) { + throw new IllegalStateException("Don't know how to compile annotation value " + value); + } else { + return null; } } }; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderFactories.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderFactories.java index bec8d118fc6..872be1bdc26 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderFactories.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderFactories.java @@ -31,7 +31,7 @@ public class ClassBuilderFactories { @NotNull @Override public ClassBuilderMode getClassBuilderMode() { - return ClassBuilderMode.FULL; + return ClassBuilderMode.full(false); } @NotNull @@ -55,13 +55,22 @@ public class ClassBuilderFactories { throw new IllegalStateException(); } }; + + public static ClassBuilderFactory TEST = new TestClassBuilderFactory(false); + + public static ClassBuilderFactory TEST_WITH_SOURCE_RETENTION_ANNOTATIONS = new TestClassBuilderFactory(true); + + private static class TestClassBuilderFactory implements ClassBuilderFactory { + private final boolean generateSourceRetentionAnnotations; + + public TestClassBuilderFactory(boolean generateSourceRetentionAnnotations) { + this.generateSourceRetentionAnnotations = generateSourceRetentionAnnotations; + } - @NotNull - public static ClassBuilderFactory TEST = new ClassBuilderFactory() { @NotNull @Override public ClassBuilderMode getClassBuilderMode() { - return ClassBuilderMode.FULL; + return ClassBuilderMode.full(generateSourceRetentionAnnotations); } @NotNull @@ -89,38 +98,40 @@ public class ClassBuilderFactories { public void close() { } - }; - + } + @NotNull - public static ClassBuilderFactory BINARIES = new ClassBuilderFactory() { - @NotNull - @Override - public ClassBuilderMode getClassBuilderMode() { - return ClassBuilderMode.FULL; - } + public static ClassBuilderFactory binaries(final boolean generateSourceRetentionAnnotations) { + return new ClassBuilderFactory() { + @NotNull + @Override + public ClassBuilderMode getClassBuilderMode() { + return ClassBuilderMode.full(generateSourceRetentionAnnotations); + } - @NotNull - @Override - public ClassBuilder newClassBuilder(@NotNull JvmDeclarationOrigin origin) { - return new AbstractClassBuilder.Concrete(new BinaryClassWriter()); - } + @NotNull + @Override + public ClassBuilder newClassBuilder(@NotNull JvmDeclarationOrigin origin) { + return new AbstractClassBuilder.Concrete(new BinaryClassWriter()); + } - @Override - public String asText(ClassBuilder builder) { - throw new UnsupportedOperationException("BINARIES generator asked for text"); - } + @Override + public String asText(ClassBuilder builder) { + throw new UnsupportedOperationException("BINARIES generator asked for text"); + } - @Override - public byte[] asBytes(ClassBuilder builder) { - ClassWriter visitor = (ClassWriter) builder.getVisitor(); - return visitor.toByteArray(); - } + @Override + public byte[] asBytes(ClassBuilder builder) { + ClassWriter visitor = (ClassWriter) builder.getVisitor(); + return visitor.toByteArray(); + } - @Override - public void close() { + @Override + public void close() { - } - }; + } + }; + } private ClassBuilderFactories() { } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java index 557f7bb086a..2b75a4dc449 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java @@ -16,17 +16,50 @@ package org.jetbrains.kotlin.codegen; -public enum ClassBuilderMode { +public class ClassBuilderMode { + public final boolean generateBodies; + public final boolean generateMetadata; + public final boolean generateSourceRetentionAnnotations; + + private ClassBuilderMode(boolean generateBodies, boolean generateMetadata, boolean generateSourceRetentionAnnotations) { + this.generateBodies = generateBodies; + this.generateMetadata = generateMetadata; + this.generateSourceRetentionAnnotations = generateSourceRetentionAnnotations; + } + + public static ClassBuilderMode full(boolean generateSourceRetentionAnnotations) { + return generateSourceRetentionAnnotations ? KAPT2 : FULL; + } + /** * Full function bodies */ - FULL, + private final static ClassBuilderMode FULL = new ClassBuilderMode( + /* bodies = */ true, + /* metadata = */ true, + /* sourceRetention = */ false); + + /** + * Full function bodies, write annotations with the "source" retention. + */ + private final static ClassBuilderMode KAPT2 = new ClassBuilderMode( + /* bodies = */ true, + /* metadata = */ true, + /* sourceRetention = */ true); + /** * Generating light classes: Only function signatures */ - LIGHT_CLASSES, + public final static ClassBuilderMode LIGHT_CLASSES = new ClassBuilderMode( + /* bodies = */ false, + /* metadata = */ false, + /* sourceRetention = */ true); + /** * Function signatures + metadata (to support incremental compilation with kapt) */ - KAPT; + public final static ClassBuilderMode KAPT = new ClassBuilderMode( + /* bodies = */ false, + /* metadata = */ true, + /* sourceRetention = */ true); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 11a61eb0a0b..e734f00ac21 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -308,7 +308,7 @@ public class ClosureCodegen extends MemberCodegen { v.newMethod(JvmDeclarationOriginKt.OtherOrigin(element, funDescriptor), ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC, bridge.getName(), bridge.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY); - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; + if (!state.getClassBuilderMode().generateBodies) return; mv.visitCode(); @@ -342,7 +342,7 @@ public class ClosureCodegen extends MemberCodegen { // TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction? private void generateFunctionReferenceMethods(@NotNull FunctionDescriptor descriptor) { int flags = ACC_PUBLIC | ACC_FINAL; - boolean generateBody = state.getClassBuilderMode() == ClassBuilderMode.FULL; + boolean generateBody = state.getClassBuilderMode().generateBodies; { MethodVisitor mv = @@ -412,7 +412,7 @@ public class ClosureCodegen extends MemberCodegen { Method constructor = new Method("", Type.VOID_TYPE, argTypes); MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(element, funDescriptor), visibilityFlag, "", constructor.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (state.getClassBuilderMode().generateBodies) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt index d08dbe01e82..175f820a3b0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt @@ -138,7 +138,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { annotationCodegen.genAnnotations(it.value, signature.valueParameters[it.index].asmType) } - if (state.classBuilderMode != ClassBuilderMode.FULL) { + if (!state.classBuilderMode.generateBodies) { FunctionCodegen.generateLocalVariablesForParameters(mv, signature, null, Label(), Label(), remainingParameters, isStatic) mv.visitEnd() return diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 892cada62a8..5bcd66b57ee 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -199,7 +199,7 @@ public class FunctionCodegen { parentBodyCodegen.addAdditionalTask(new JvmStaticGenerator(functionDescriptor, origin, state, parentBodyCodegen)); } - if (state.getClassBuilderMode() != ClassBuilderMode.FULL || isAbstractMethod(functionDescriptor, contextKind, state)) { + if (!state.getClassBuilderMode().generateBodies || isAbstractMethod(functionDescriptor, contextKind, state)) { generateLocalVariableTable( mv, jvmSignature, @@ -715,7 +715,7 @@ public class FunctionCodegen { // enum constructors have two additional synthetic parameters which somewhat complicate this task AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType()); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (state.getClassBuilderMode().generateBodies) { if (this.owner instanceof MultifileClassFacadeContext) { mv.visitCode(); generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner); @@ -889,7 +889,7 @@ public class FunctionCodegen { MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.Bridge(descriptor, origin), flags, bridge.getName(), bridge.getDescriptor(), null, null); - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; + if (!state.getClassBuilderMode().generateBodies) return; mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index bea54cbb5e0..ce6734a6942 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -154,7 +154,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (!ktClass.hasModifier(KtTokens.OPEN_KEYWORD) && !isAbstract) { // Light-class mode: Do not make enum classes final since PsiClass corresponding to enum is expected to be inheritable from - isFinal = !(ktClass.isEnum() && state.getClassBuilderMode() != ClassBuilderMode.FULL); + isFinal = !(ktClass.isEnum() && !state.getClassBuilderMode().generateBodies); } isStatic = !ktClass.isInner(); } @@ -165,8 +165,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { int access = 0; - if (state.getClassBuilderMode() != ClassBuilderMode.FULL && !DescriptorUtils.isTopLevelDeclaration(descriptor)) { - // ClassBuilderMode.LIGHT_CLASSES means we are generating light classes & looking at a nested or inner class + if (!state.getClassBuilderMode().generateBodies && !DescriptorUtils.isTopLevelDeclaration(descriptor)) { + // !ClassBuilderMode.generateBodies means we are generating light classes & looking at a nested or inner class // Light class generation is implemented so that Cls-classes only read bare code of classes, // without knowing whether these classes are inner or not (see ClassStubBuilder.EMPTY_STRATEGY) // Thus we must write full accessibility flags on inner classes in this mode @@ -251,7 +251,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void writeEnclosingMethod() { // Do not emit enclosing method in "light-classes mode" since currently we generate local light classes as if they're top level - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) { + if (!state.getClassBuilderMode().generateBodies) { return; } @@ -796,7 +796,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JvmDeclarationOriginKt.OtherOrigin(myClass, valuesFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUES.asString(), "()" + type.getDescriptor(), null, null ); - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; + if (!state.getClassBuilderMode().generateBodies) return; mv.visitCode(); mv.visitFieldInsn(GETSTATIC, classAsmType.getInternalName(), ENUM_VALUES_FIELD_NAME, type.getDescriptor()); @@ -816,7 +816,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { }); MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, valueOfFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUE_OF.asString(), "(Ljava/lang/String;)" + classAsmType.getDescriptor(), null, null); - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; + if (!state.getClassBuilderMode().generateBodies) return; mv.visitCode(); mv.visitLdcInsn(classAsmType); @@ -836,7 +836,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null); - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; + if (!state.getClassBuilderMode().generateBodies) return; // Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of InstructionAdapter v = createOrGetClInitCodegen().v; markLineNumberForElement(element, v); @@ -876,7 +876,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { //This field are always static and final so if it has constant initializer don't do anything in clinit, //field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4 // TODO: test this code - if (state.getClassBuilderMode() == ClassBuilderMode.FULL && info.defaultValue == null) { + if (state.getClassBuilderMode().generateBodies && info.defaultValue == null) { ExpressionCodegen codegen = createOrGetClInitCodegen(); int companionObjectIndex = putCompanionObjectInLocalVar(codegen); StackValue.local(companionObjectIndex, OBJECT_TYPE).put(OBJECT_TYPE, codegen.v); @@ -1195,7 +1195,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void lookupConstructorExpressionsInClosureIfPresent() { - if (state.getClassBuilderMode() != ClassBuilderMode.FULL || descriptor.getConstructors().isEmpty()) return; + if (!state.getClassBuilderMode().generateBodies || descriptor.getConstructors().isEmpty()) return; KtVisitorVoid visitor = new KtVisitorVoid() { @Override @@ -1552,7 +1552,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void initializeEnumConstants(@NotNull List enumEntries) { - if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; + if (!state.getClassBuilderMode().generateBodies) return; ExpressionCodegen codegen = createOrGetClInitCodegen(); InstructionAdapter iv = codegen.v; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java index 1fb9f7b1bf5..d70ccbdeefd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java @@ -82,7 +82,7 @@ public class KotlinCodegenFacade { } private static void doCheckCancelled(GenerationState state) { - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (state.getClassBuilderMode().generateBodies) { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 1026735e729..20789073dd0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -67,7 +67,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*; -import static org.jetbrains.kotlin.codegen.ClassBuilderModeUtilKt.shouldGenerateMetadata; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; @@ -128,7 +127,7 @@ public abstract class MemberCodegen diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt index e79d6a62a22..397de3899f3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt @@ -77,7 +77,7 @@ class MultifileClassPartCodegen( } override fun generate() { - if (state.classBuilderMode != ClassBuilderMode.FULL) return + if (!state.classBuilderMode.generateBodies) return super.generate() @@ -132,7 +132,7 @@ class MultifileClassPartCodegen( } } - if (state.classBuilderMode == ClassBuilderMode.FULL) { + if (state.classBuilderMode.generateBodies) { generateInitializers { createOrGetClInitCodegen() } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java index 32410427527..85a71cbb1da 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java @@ -96,7 +96,7 @@ public class PackagePartCodegen extends MemberCodegen { } } - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (state.getClassBuilderMode().generateBodies) { generateInitializers(new Function0() { @Override public ExpressionCodegen invoke() { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 46bf31d4e6e..e199ad3aaf8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -230,7 +230,7 @@ public class PropertyCodegen { KtExpression defaultValue = p.getDefaultValue(); if (defaultValue != null) { ConstantValue constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext, true); - assert state.getClassBuilderMode() != ClassBuilderMode.FULL || constant != null + assert !state.getClassBuilderMode().generateBodies || constant != null : "Default value for annotation parameter should be compile time value: " + defaultValue.getText(); if (constant != null) { AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(mv, memberCodegen, typeMapper); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt index 177de955ed7..03b02ad1dba 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt @@ -149,7 +149,7 @@ class PropertyReferenceCodegen( private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) { val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.name, method.descriptor, null, null) - if (state.classBuilderMode == ClassBuilderMode.FULL) { + if (state.classBuilderMode.generateBodies) { val iv = InstructionAdapter(mv) iv.visitCode() iv.generate() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java index 384d3bdb059..83b24d6ecf1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java @@ -130,7 +130,7 @@ public class SamWrapperCodegen { MethodVisitor mv = cv.newMethod(JvmDeclarationOriginKt.OtherOrigin(samType.getJavaClassDescriptor()), visibility, "", Type.getMethodDescriptor(Type.VOID_TYPE, functionType), null, null); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (state.getClassBuilderMode().generateBodies) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java index 1bed737a7b7..8c4fd8c5c6e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.java @@ -150,7 +150,7 @@ public class ScriptCodegen extends MemberCodegen { ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), null, null); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (state.getClassBuilderMode().generateBodies) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 9ba6a9ccaca..dd10eb32b94 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -114,7 +114,7 @@ public class KotlinTypeMapper { @Override public void processErrorType(@NotNull KotlinType kotlinType, @NotNull ClassDescriptor descriptor) { - if (classBuilderMode == ClassBuilderMode.FULL) { + if (classBuilderMode.generateBodies) { throw new IllegalStateException(generateErrorMessageForErrorType(kotlinType, descriptor)); } } @@ -1109,7 +1109,7 @@ public class KotlinTypeMapper { } private void writeFormalTypeParameter(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull JvmSignatureWriter sw) { - if (classBuilderMode != ClassBuilderMode.FULL && typeParameterDescriptor.getName().isSpecial()) { + if (!classBuilderMode.generateBodies && typeParameterDescriptor.getName().isSpecial()) { // If a type parameter has no name, the code below fails, but it should recover in case of light classes return; } @@ -1259,7 +1259,7 @@ public class KotlinTypeMapper { // We may generate a slightly wrong signature for a local class / anonymous object in light classes mode but we don't care, // because such classes are not accessible from the outside world - if (classBuilderMode == ClassBuilderMode.FULL) { + if (classBuilderMode.generateBodies) { ResolvedCall superCall = findFirstDelegatingSuperCall(descriptor); if (superCall == null) return; writeSuperConstructorCallParameters(sw, descriptor, superCall, captureThis != null); diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 11b6a7e4ab9..d004220dc32 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -129,7 +129,7 @@ object KotlinToJVMBytecodeCompiler { val targetDescription = "in targets [" + chunk.joinToString { input -> input.getModuleName() + "-" + input.getModuleType() } + "]" var result = analyze(environment, targetDescription) - + if (result is AnalysisResult.RetryWithAdditionalJavaRoots) { val oldReadOnlyValue = projectConfiguration.isReadOnly projectConfiguration.isReadOnly = false @@ -142,14 +142,14 @@ object KotlinToJVMBytecodeCompiler { // Clear package caches (see KotlinJavaPsiFacade) (PsiManager.getInstance(environment.project).modificationTracker as? PsiModificationTrackerImpl)?.incCounter() - + // Clear all diagnostic messages projectConfiguration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]?.clear() - + // Repeat analysis with additional Java roots (kapt generated sources) result = analyze(environment, targetDescription) } - + if (result == null || !result.shouldGenerateCode) return false ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() @@ -249,7 +249,7 @@ object KotlinToJVMBytecodeCompiler { try { try { tryConstructClass(scriptClass, scriptArgs) - ?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n") + ?: throw RuntimeException("unable to find appropriate constructor for class ${scriptClass.name} accepting arguments $scriptArgs\n") } finally { // NB: these lines are required (see KT-9546) but aren't covered by tests @@ -428,7 +428,7 @@ object KotlinToJVMBytecodeCompiler { K2JVMCompiler.reportPerf(environment.configuration, message) val analysisResult = analyzerWithCompilerReport.analysisResult - + return if (!analyzerWithCompilerReport.hasErrors() || analysisResult is AnalysisResult.RetryWithAdditionalJavaRoots) analysisResult else @@ -442,9 +442,10 @@ object KotlinToJVMBytecodeCompiler { sourceFiles: List, module: Module? ): GenerationState { + val isKapt2Enabled = environment.project.getUserData(IS_KAPT2_ENABLED_KEY) ?: false val generationState = GenerationState( environment.project, - ClassBuilderFactories.BINARIES, + ClassBuilderFactories.binaries(isKapt2Enabled), result.moduleDescriptor, result.bindingContext, sourceFiles, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/classBuilderModeUtil.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/config/Kapt2EnabledKey.kt similarity index 79% rename from compiler/backend/src/org/jetbrains/kotlin/codegen/classBuilderModeUtil.kt rename to compiler/cli/src/org/jetbrains/kotlin/cli/jvm/config/Kapt2EnabledKey.kt index 5675a09fa81..9a98f7eca82 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/classBuilderModeUtil.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/config/Kapt2EnabledKey.kt @@ -14,7 +14,8 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen +package org.jetbrains.kotlin.cli.jvm.config -fun ClassBuilderMode.shouldGenerateMetadata() = - this == ClassBuilderMode.FULL || this == ClassBuilderMode.KAPT \ No newline at end of file +import com.intellij.openapi.util.Key + +val IS_KAPT2_ENABLED_KEY = Key("IsKapt2EnabledKey") \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.kt index 042a7a39bb8..f5809801f7f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplInterpreter.kt @@ -113,9 +113,12 @@ class ReplInterpreter( } val state = GenerationState( - psiFile.project, ClassBuilderFactories.BINARIES, analyzerEngine.module, - analyzerEngine.trace.bindingContext, listOf(psiFile), configuration - ) + psiFile.project, + ClassBuilderFactories.binaries(false), + analyzerEngine.module, + analyzerEngine.trace.bindingContext, + listOf(psiFile), + configuration) compileScript(psiFile.script!!, earlierLines.map(EarlierLine::getScriptDescriptor), state, CompilationErrorHandler.THROW_EXCEPTION) diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt b/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt index a498f9ecee2..40a53f83adc 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/AbstractBytecodeListingTest.kt @@ -23,12 +23,15 @@ import org.jetbrains.org.objectweb.asm.Opcodes.* import java.io.File abstract class AbstractBytecodeListingTest : CodegenTestCase() { + protected open val classBuilderFactory: ClassBuilderFactory + get() = ClassBuilderFactories.TEST + override fun doTest(filename: String) { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL) loadFileByFullPath(filename) val ktFile = File(filename) val txtFile = File(ktFile.parentFile, ktFile.nameWithoutExtension + ".txt") - val generatedFiles = CodegenTestUtil.generateFiles(myEnvironment, myFiles) + val generatedFiles = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory) .getClassFiles() .sortedBy { it.relativePath } .map { diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/CodegenTestUtil.java b/compiler/tests-common/org/jetbrains/kotlin/codegen/CodegenTestUtil.java index b9e30f0df81..e9aafdfafbe 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/CodegenTestUtil.java +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/CodegenTestUtil.java @@ -46,13 +46,21 @@ public class CodegenTestUtil { @NotNull public static ClassFileFactory generateFiles(@NotNull KotlinCoreEnvironment environment, @NotNull CodegenTestFiles files) { + return generateFiles(environment, files, ClassBuilderFactories.TEST); + } + + @NotNull + public static ClassFileFactory generateFiles( + @NotNull KotlinCoreEnvironment environment, + @NotNull CodegenTestFiles files, + @NotNull ClassBuilderFactory classBuilderFactory) { AnalysisResult analysisResult = JvmResolveUtil.analyzeAndCheckForErrors(files.getPsiFiles(), environment); analysisResult.throwIfError(); AnalyzingUtils.throwExceptionOnErrors(analysisResult.getBindingContext()); CompilerConfiguration configuration = environment.getConfiguration(); GenerationState state = new GenerationState( environment.getProject(), - ClassBuilderFactories.TEST, + classBuilderFactory, analysisResult.getModuleDescriptor(), analysisResult.getBindingContext(), files.getPsiFiles(), diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 6553c78f652..cb0cc9d5d80 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.addImport.AbstractAddImportTest import org.jetbrains.kotlin.android.* import org.jetbrains.kotlin.android.configure.AbstractConfigureProjectTest import org.jetbrains.kotlin.annotation.AbstractAnnotationProcessorBoxTest +import org.jetbrains.kotlin.annotation.processing.test.sourceRetention.AbstractBytecodeListingTestForSourceRetention import org.jetbrains.kotlin.annotation.processing.test.wrappers.AbstractJavaModelWrappersTest import org.jetbrains.kotlin.annotation.processing.test.wrappers.AbstractKotlinModelWrappersTest import org.jetbrains.kotlin.asJava.AbstractCompilerLightClassTest @@ -1073,6 +1074,10 @@ fun main(args: Array) { testClass() { model("kotlinWrappers", extension = "kt") } + + testClass() { + model("sourceRetention", extension = "kt") + } } testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") { diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt index ceb6ab42839..2875ae53e6c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt @@ -390,7 +390,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour val state = GenerationState( fileForDebugger.project, - if (!DEBUG_MODE) ClassBuilderFactories.BINARIES else ClassBuilderFactories.TEST, + if (!DEBUG_MODE) ClassBuilderFactories.binaries(false) else ClassBuilderFactories.TEST, moduleDescriptor, bindingContext, files, diff --git a/plugins/annotation-processing/annotation-processing.iml b/plugins/annotation-processing/annotation-processing.iml index 8bc37eae375..5b09fa22829 100644 --- a/plugins/annotation-processing/annotation-processing.iml +++ b/plugins/annotation-processing/annotation-processing.iml @@ -15,5 +15,6 @@ + \ No newline at end of file diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt index aa24889b0c9..252bc9f56c4 100755 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt @@ -20,13 +20,15 @@ import com.intellij.mock.MockProject import com.intellij.openapi.extensions.Extensions import org.jetbrains.kotlin.annotation.ClasspathBasedAnnotationProcessingExtension import org.jetbrains.kotlin.annotation.processing.diagnostic.DefaultErrorMessagesAnnotationProcessing +import org.jetbrains.kotlin.cli.jvm.config.IS_KAPT2_ENABLED_KEY +import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot +import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot 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 -import org.jetbrains.kotlin.config.ContentRoot import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension @@ -93,13 +95,6 @@ class AnnotationProcessingCommandLineProcessor : CommandLineProcessor { } class AnnotationProcessingComponentRegistrar : ComponentRegistrar { - private companion object { - private val JVM_CLASSPATH_ROOT = "org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot" - private val JAVA_SOURCE_ROOT = "org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot" - - private val CLASSPATH_ROOTS = listOf(JVM_CLASSPATH_ROOT, JAVA_SOURCE_ROOT) - } - override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { val generatedOutputDir = configuration.get(AnnotationProcessingConfigurationKeys.GENERATED_OUTPUT_DIR) ?: return val apClasspath = configuration.get(AnnotationProcessingConfigurationKeys.ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File) ?: return @@ -111,12 +106,10 @@ class AnnotationProcessingComponentRegistrar : ComponentRegistrar { val contentRoots = configuration[JVMConfigurationKeys.CONTENT_ROOTS] ?: emptyList() - fun ContentRoot.jvmRootFile() = javaClass.getMethod("getFile")(this) as File - - val compileClasspath = contentRoots.filter { it.javaClass.canonicalName in CLASSPATH_ROOTS }.map { it.jvmRootFile() } + val compileClasspath = contentRoots.filterIsInstance().map { it.file } val classpath = apClasspath + compileClasspath - val javaRoots = contentRoots.filter { it.javaClass.canonicalName == JAVA_SOURCE_ROOT }.map { it.jvmRootFile() } + val javaRoots = contentRoots.filterIsInstance().map { it.file } val classesOutputDir = File(configuration.get(AnnotationProcessingConfigurationKeys.CLASS_FILES_OUTPUT_DIR) ?: configuration[JVMConfigurationKeys.MODULES]!!.first().getOutputDirectory()) @@ -126,6 +119,9 @@ class AnnotationProcessingComponentRegistrar : ComponentRegistrar { Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME) .registerExtension(DefaultErrorMessagesAnnotationProcessing()) + // Annotations with the "SOURCE" retention will be written to class files + project.putUserData(IS_KAPT2_ENABLED_KEY, true) + val annotationProcessingExtension = ClasspathBasedAnnotationProcessingExtension( classpath, generatedOutputDirFile, classesOutputDir, javaRoots, verboseOutput, incrementalDataFile) diff --git a/plugins/annotation-processing/testData/sourceRetention/withSource.kt b/plugins/annotation-processing/testData/sourceRetention/withSource.kt new file mode 100644 index 00000000000..c4a917d64e0 --- /dev/null +++ b/plugins/annotation-processing/testData/sourceRetention/withSource.kt @@ -0,0 +1,15 @@ +// Same as withoutSource.kt + +@Retention(AnnotationRetention.SOURCE) +annotation class SourceAnno + +@Retention(AnnotationRetention.BINARY) +annotation class BinaryAnno + +@Retention(AnnotationRetention.RUNTIME) +annotation class RuntimeAnno + +@SourceAnno +@BinaryAnno +@RuntimeAnno +class Test \ No newline at end of file diff --git a/plugins/annotation-processing/testData/sourceRetention/withSource.txt b/plugins/annotation-processing/testData/sourceRetention/withSource.txt new file mode 100644 index 00000000000..5046723ba8d --- /dev/null +++ b/plugins/annotation-processing/testData/sourceRetention/withSource.txt @@ -0,0 +1,22 @@ +@kotlin.annotation.Retention +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class BinaryAnno + +@kotlin.annotation.Retention +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class RuntimeAnno + +@kotlin.annotation.Retention +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class SourceAnno + +@RuntimeAnno +@kotlin.Metadata +@SourceAnno +@BinaryAnno +public final class Test { + public method (): void +} \ No newline at end of file diff --git a/plugins/annotation-processing/testData/sourceRetention/withoutSource.kt b/plugins/annotation-processing/testData/sourceRetention/withoutSource.kt new file mode 100644 index 00000000000..8a42e91e835 --- /dev/null +++ b/plugins/annotation-processing/testData/sourceRetention/withoutSource.kt @@ -0,0 +1,15 @@ +// Same as withSource.kt + +@Retention(AnnotationRetention.SOURCE) +annotation class SourceAnno + +@Retention(AnnotationRetention.BINARY) +annotation class BinaryAnno + +@Retention(AnnotationRetention.RUNTIME) +annotation class RuntimeAnno + +@SourceAnno +@BinaryAnno +@RuntimeAnno +class Test \ No newline at end of file diff --git a/plugins/annotation-processing/testData/sourceRetention/withoutSource.txt b/plugins/annotation-processing/testData/sourceRetention/withoutSource.txt new file mode 100644 index 00000000000..2b9ada9f9de --- /dev/null +++ b/plugins/annotation-processing/testData/sourceRetention/withoutSource.txt @@ -0,0 +1,21 @@ +@kotlin.annotation.Retention +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class BinaryAnno + +@kotlin.annotation.Retention +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class RuntimeAnno + +@kotlin.annotation.Retention +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class SourceAnno + +@RuntimeAnno +@kotlin.Metadata +@BinaryAnno +public final class Test { + public method (): void +} diff --git a/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/AbstractBytecodeListingTestForSourceRetention.kt b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/AbstractBytecodeListingTestForSourceRetention.kt new file mode 100644 index 00000000000..333e2b0ff8c --- /dev/null +++ b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/AbstractBytecodeListingTestForSourceRetention.kt @@ -0,0 +1,31 @@ +/* + * 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.annotation.processing.test.sourceRetention + +import org.jetbrains.kotlin.codegen.AbstractBytecodeListingTest +import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.codegen.ClassBuilderFactory + +abstract class AbstractBytecodeListingTestForSourceRetention : AbstractBytecodeListingTest() { + override val classBuilderFactory: ClassBuilderFactory + get() { + return if (getTestName(true).contains("withSource", ignoreCase = true)) + ClassBuilderFactories.TEST_WITH_SOURCE_RETENTION_ANNOTATIONS + else + ClassBuilderFactories.TEST + } +} \ No newline at end of file diff --git a/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/BytecodeListingTestForSourceRetentionGenerated.java b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/BytecodeListingTestForSourceRetentionGenerated.java new file mode 100644 index 00000000000..4c671a92789 --- /dev/null +++ b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/sourceRetention/BytecodeListingTestForSourceRetentionGenerated.java @@ -0,0 +1,49 @@ +/* + * 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.annotation.processing.test.sourceRetention; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +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/annotation-processing/testData/sourceRetention") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class BytecodeListingTestForSourceRetentionGenerated extends AbstractBytecodeListingTestForSourceRetention { + public void testAllFilesPresentInSourceRetention() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/annotation-processing/testData/sourceRetention"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("withSource.kt") + public void testWithSource() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("plugins/annotation-processing/testData/sourceRetention/withSource.kt"); + doTest(fileName); + } + + @TestMetadata("withoutSource.kt") + public void testWithoutSource() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("plugins/annotation-processing/testData/sourceRetention/withoutSource.kt"); + doTest(fileName); + } +}