Implement backend error reporting on unsupported script capturing

#KT-30616 fixed
#KT-43995 fixed
#KT-19424 fixed
#KT-49443 fixed
This commit is contained in:
Ilya Chernikov
2021-11-30 17:14:24 +01:00
committed by TeamCityServer
parent cb5e451e05
commit 10c5071eda
22 changed files with 444 additions and 34 deletions
@@ -27,6 +27,11 @@ object JvmBackendErrors {
val SUSPENSION_POINT_INSIDE_MONITOR by error1<PsiElement, String>()
val SCRIPT_CAPTURING_OBJECT by error1<PsiElement, String>()
val SCRIPT_CAPTURING_INTERFACE by error1<PsiElement, String>()
val SCRIPT_CAPTURING_ENUM by error1<PsiElement, String>()
val SCRIPT_CAPTURING_ENUM_ENTRY by error1<PsiElement, String>()
init {
RootDiagnosticRendererFactory.registerFactory(KtDefaultJvmErrorMessages)
}
@@ -60,5 +65,10 @@ object KtDefaultJvmErrorMessages : BaseDiagnosticRendererFactory() {
map.put(JvmBackendErrors.TYPEOF_SUSPEND_TYPE, "Suspend functional types are not supported in typeOf")
map.put(JvmBackendErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, "Non-reified type parameters with recursive bounds are not supported yet: {0}", STRING)
map.put(JvmBackendErrors.SUSPENSION_POINT_INSIDE_MONITOR, "A suspension point at {0} is inside a critical section", STRING)
map.put(JvmBackendErrors.SCRIPT_CAPTURING_OBJECT, "Object {0} captures the script class instance. Try to use class or anonymous object instead", STRING)
map.put(JvmBackendErrors.SCRIPT_CAPTURING_INTERFACE, "Interface {0} captures the script class instance. Try to use class instead", STRING)
map.put(JvmBackendErrors.SCRIPT_CAPTURING_ENUM, "Enum class {0} captures the script class instance. Try to use class or anonymous object instead", STRING)
map.put(JvmBackendErrors.SCRIPT_CAPTURING_ENUM_ENTRY, "Enum entry {0} captures the script class instance. Try to use class or anonymous object instead", STRING)
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.config.JvmSerializeIrMode
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
@@ -249,6 +250,9 @@ open class JvmIrCodegenFactory(
override fun invokeCodegen(input: CodegenFactory.CodegenInput) {
val (state, context, module, notifyCodegenStart) = input as JvmIrCodegenInput
if ((state.diagnosticReporter as? BaseDiagnosticsCollector)?.hasErrors == true) return
notifyCodegenStart()
jvmCodegenPhases.invokeToplevel(PhaseConfig(jvmCodegenPhases), context, module)
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmInnerClassesSupport
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmBackendErrors
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -97,8 +99,18 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext, val inner
if (clazz is IrClassImpl && !clazz.isInner ) {
val closure = annotator.getClassClosure(clazz)
if (closure.capturedValues.singleOrNull()?.owner?.type == irScript.thisReceiver.type) {
if (clazz.isClass) {
capturingClasses.add(clazz)
fun reportError(factory: KtDiagnosticFactory1<String>, name: Name? = null) {
context.ktDiagnosticReporter.at(clazz).report(factory, (name ?: clazz.name).asString())
}
when {
clazz.isInterface -> reportError(JvmBackendErrors.SCRIPT_CAPTURING_INTERFACE)
clazz.isEnumClass -> reportError(JvmBackendErrors.SCRIPT_CAPTURING_ENUM)
clazz.isEnumEntry -> reportError(JvmBackendErrors.SCRIPT_CAPTURING_ENUM_ENTRY)
// TODO: ClosureAnnotator is not catching companion's closures, so the following reporting never happens. Make it work or drop
clazz.isCompanion -> reportError(JvmBackendErrors.SCRIPT_CAPTURING_OBJECT, SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT)
clazz.kind.isSingleton -> reportError(JvmBackendErrors.SCRIPT_CAPTURING_OBJECT)
clazz.isClass -> capturingClasses.add(clazz)
}
}
}
@@ -0,0 +1,10 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
// KT-30616
val foo = "hello"
<!SCRIPT_CAPTURING_ENUM!>enum class Bar(val s: String = foo) {
Eleven("0")
}<!>
@@ -0,0 +1,30 @@
package
public final class EnumCapturesProperty : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor EnumCapturesProperty(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public final val foo: kotlin.String = "hello"
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final enum class Bar : kotlin.Enum<EnumCapturesProperty.Bar> {
enum entry Eleven
private constructor Bar(/*0*/ s: kotlin.String = ...)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final val s: kotlin.String
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: EnumCapturesProperty.Bar): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<EnumCapturesProperty.Bar!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumCapturesProperty.Bar
public final /*synthesized*/ fun values(): kotlin.Array<EnumCapturesProperty.Bar>
}
}
@@ -0,0 +1,9 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
// KT-30616
val foo = "hello"
<!SCRIPT_CAPTURING_ENUM!>enum class Bar(val s: String) {
Eleven(s = foo)
}<!>
@@ -0,0 +1,30 @@
package
public final class EnumEntryCapturesProperty : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor EnumEntryCapturesProperty(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public final val foo: kotlin.String = "hello"
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final enum class Bar : kotlin.Enum<EnumEntryCapturesProperty.Bar> {
enum entry Eleven
private constructor Bar(/*0*/ s: kotlin.String)
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
public final val s: kotlin.String
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: EnumEntryCapturesProperty.Bar): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<EnumEntryCapturesProperty.Bar!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumEntryCapturesProperty.Bar
public final /*synthesized*/ fun values(): kotlin.Array<EnumEntryCapturesProperty.Bar>
}
}
@@ -0,0 +1,14 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
fun foo() = B().bar()
val life = 42
<!SCRIPT_CAPTURING_INTERFACE!>interface A {
val x get() = life
}<!>
class B : A {
fun bar() = x
}
@@ -0,0 +1,27 @@
package
public final class InterfaceCapturesProperty : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor InterfaceCapturesProperty(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public final val life: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public interface A {
public open val x: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class B : InterfaceCapturesProperty.A {
public constructor B()
public open override /*1*/ /*fake_override*/ val x: kotlin.Int
public final fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,10 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
fun foo() = B.bar()
val life = 42
<!SCRIPT_CAPTURING_OBJECT!>object B<!> {
fun bar() = life
}
@@ -0,0 +1,19 @@
package
public final class ObjectCapturesProperty : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor ObjectCapturesProperty(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public final val life: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public object B {
private constructor B()
public final fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,14 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
fun foo() = B.bar()
val life = 42
class A {
val x = life
}
<!SCRIPT_CAPTURING_OBJECT!>object B<!> {
fun bar() = A().x
}
@@ -0,0 +1,27 @@
package
public final class ObjectCapturesPropertyIndirect : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor ObjectCapturesPropertyIndirect(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public final val life: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class A {
public constructor A()
public final val x: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object B {
private constructor B()
public final fun bar(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,23 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
// see KT-49443
// two similar examples check dependency on declarations ordering
interface I {
fun rename()
}
<!SCRIPT_CAPTURING_OBJECT!>object ZipHelper<!> {
fun buildZip() {
DefaultEachEntryConfiguration(0).rename()
}
}
class DefaultEachEntryConfiguration(val entry: Int) : I {
override fun rename() {
entry.copy()
}
}
fun Int.copy() = Unit
@@ -0,0 +1,35 @@
package
public final class ObjectCapturesPropertyViaExtension1 : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor ObjectCapturesPropertyViaExtension1(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final fun kotlin.Int.copy(): kotlin.Unit
public final class DefaultEachEntryConfiguration : ObjectCapturesPropertyViaExtension1.I {
public constructor DefaultEachEntryConfiguration(/*0*/ entry: kotlin.Int)
public final val entry: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun rename(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface I {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract fun rename(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object ZipHelper {
private constructor ZipHelper()
public final fun buildZip(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,23 @@
// !RENDER_DIAGNOSTICS_FULL_TEXT
// TARGET_BACKEND: JVM_IR
// see KT-49443
// two similar examples check dependency on declarations ordering
interface I {
fun rename()
}
class DefaultEachEntryConfiguration(val entry: Int) : I {
override fun rename() {
entry.copy()
}
}
<!SCRIPT_CAPTURING_OBJECT!>object ZipHelper<!> {
fun buildZip() {
DefaultEachEntryConfiguration(0).rename()
}
}
fun Int.copy() = Unit
@@ -0,0 +1,35 @@
package
public final class ObjectCapturesPropertyViaExtension2 : kotlin.script.templates.standard.ScriptTemplateWithArgs {
public constructor ObjectCapturesPropertyViaExtension2(/*0*/ args: kotlin.Array<kotlin.String>)
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final fun kotlin.Int.copy(): kotlin.Unit
public final class DefaultEachEntryConfiguration : ObjectCapturesPropertyViaExtension2.I {
public constructor DefaultEachEntryConfiguration(/*0*/ entry: kotlin.Int)
public final val entry: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun rename(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface I {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract fun rename(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object ZipHelper {
private constructor ZipHelper()
public final fun buildZip(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -22,7 +22,7 @@ import java.util.regex.Pattern;
public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnosticsTestWithJvmIrBackend {
@Test
public void testAllFilesPresentInTestsWithJvmBackend() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -67,7 +67,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class DuplicateJvmSignature {
@Test
public void testAllFilesPresentInDuplicateJvmSignature() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -100,7 +100,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
@Test
public void testAllFilesPresentInAccidentalOverrides() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/accidentalOverrides"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/accidentalOverrides"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -194,7 +194,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class Bridges {
@Test
public void testAllFilesPresentInBridges() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/bridges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/bridges"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -222,7 +222,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class Erasure {
@Test
public void testAllFilesPresentInErasure() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/erasure"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/erasure"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -334,7 +334,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class FinalMembersFromBuiltIns {
@Test
public void testAllFilesPresentInFinalMembersFromBuiltIns() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/finalMembersFromBuiltIns"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/finalMembersFromBuiltIns"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -356,7 +356,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class FunctionAndProperty {
@Test
public void testAllFilesPresentInFunctionAndProperty() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/functionAndProperty"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/functionAndProperty"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -474,7 +474,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class SpecialNames {
@Test
public void testAllFilesPresentInSpecialNames() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/specialNames"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/specialNames"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -544,7 +544,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class Statics {
@Test
public void testAllFilesPresentInStatics() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/statics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/statics"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -590,7 +590,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class Synthesized {
@Test
public void testAllFilesPresentInSynthesized() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/synthesized"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/synthesized"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -606,7 +606,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class TraitImpl {
@Test
public void testAllFilesPresentInTraitImpl() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -653,7 +653,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class MultifileClasses {
@Test
public void testAllFilesPresentInMultifileClasses() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/multifileClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/multifileClasses"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -663,13 +663,65 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/scripts")
@TestDataPath("$PROJECT_ROOT")
public class Scripts {
@Test
public void testAllFilesPresentInScripts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/scripts"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("enumCapturesProperty.kts")
public void testEnumCapturesProperty() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumCapturesProperty.kts");
}
@Test
@TestMetadata("enumEntryCapturesProperty.kts")
public void testEnumEntryCapturesProperty() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/enumEntryCapturesProperty.kts");
}
@Test
@TestMetadata("interfaceCapturesProperty.kts")
public void testInterfaceCapturesProperty() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/interfaceCapturesProperty.kts");
}
@Test
@TestMetadata("objectCapturesProperty.kts")
public void testObjectCapturesProperty() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesProperty.kts");
}
@Test
@TestMetadata("objectCapturesPropertyIndirect.kts")
public void testObjectCapturesPropertyIndirect() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyIndirect.kts");
}
@Test
@TestMetadata("objectCapturesPropertyViaExtension1.kts")
public void testObjectCapturesPropertyViaExtension1() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension1.kts");
}
@Test
@TestMetadata("objectCapturesPropertyViaExtension2.kts")
public void testObjectCapturesPropertyViaExtension2() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJvmBackend/scripts/objectCapturesPropertyViaExtension2.kts");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/typeOf")
@TestDataPath("$PROJECT_ROOT")
public class TypeOf {
@Test
public void testAllFilesPresentInTypeOf() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/typeOf"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/typeOf"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -691,7 +743,7 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
public class ValueClasses {
@Test
public void testAllFilesPresentInValueClasses() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/valueClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/valueClasses"), Pattern.compile("^(.+)\\.kts?$"), null, TargetBackend.JVM_IR, true);
}
@Test
@@ -651,6 +651,16 @@ public class DiagnosticsTestWithOldJvmBackendGenerated extends AbstractDiagnosti
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/scripts")
@TestDataPath("$PROJECT_ROOT")
public class Scripts {
@Test
public void testAllFilesPresentInScripts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/scripts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_OLD, true);
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/typeOf")
@TestDataPath("$PROJECT_ROOT")
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigu
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.ScriptingEnvironmentConfigurator
abstract class AbstractDiagnosticsTestWithJvmBackend<I : ResultingArtifact.BackendInput<I>> : AbstractKotlinCompilerTest() {
abstract val targetBackend: TargetBackend
@@ -53,6 +54,7 @@ abstract class AbstractDiagnosticsTestWithJvmBackend<I : ResultingArtifact.Backe
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator,
::ScriptingEnvironmentConfigurator,
)
useMetaInfoProcessors(::OldNewInferenceMetaInfoProcessor)
@@ -40,7 +40,7 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
}
testClass<AbstractDiagnosticsTestWithJvmIrBackend> {
model("diagnostics/testsWithJvmBackend", targetBackend = TargetBackend.JVM_IR)
model("diagnostics/testsWithJvmBackend", pattern = "^(.+)\\.kts?$", targetBackend = TargetBackend.JVM_IR)
}
testClass<AbstractDiagnosticsNativeTest> {
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.impl
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptCompilerProxy
@@ -192,7 +195,11 @@ private fun doCompile(
)
val generationState =
generate(analysisResult, sourceFiles, context.environment.configuration)
generate(analysisResult, sourceFiles, context.environment.configuration, messageCollector)
if (messageCollector.hasErrors()) return failure(
messageCollector
)
return makeCompiledScript(
generationState,
@@ -224,20 +231,27 @@ private fun analyze(sourceFiles: Collection<KtFile>, environment: KotlinCoreEnvi
}
private fun generate(
analysisResult: AnalysisResult, sourceFiles: List<KtFile>, kotlinCompilerConfiguration: CompilerConfiguration
): GenerationState = GenerationState.Builder(
sourceFiles.first().project,
ClassBuilderFactories.BINARIES,
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
sourceFiles,
kotlinCompilerConfiguration
).codegenFactory(
if (kotlinCompilerConfiguration.getBoolean(JVMConfigurationKeys.IR))
JvmIrCodegenFactory(
kotlinCompilerConfiguration,
kotlinCompilerConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG),
) else DefaultCodegenFactory
).build().also {
KotlinCodegenFacade.compileCorrectFiles(it)
analysisResult: AnalysisResult, sourceFiles: List<KtFile>, kotlinCompilerConfiguration: CompilerConfiguration,
messageCollector: MessageCollector
): GenerationState {
val diagnosticsReporter = DiagnosticReporterFactory.createReporter()
return GenerationState.Builder(
sourceFiles.first().project,
ClassBuilderFactories.BINARIES,
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
sourceFiles,
kotlinCompilerConfiguration
).codegenFactory(
if (kotlinCompilerConfiguration.getBoolean(JVMConfigurationKeys.IR))
JvmIrCodegenFactory(
kotlinCompilerConfiguration,
kotlinCompilerConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG),
) else DefaultCodegenFactory
).diagnosticReporter(
diagnosticsReporter
).build().also {
KotlinCodegenFacade.compileCorrectFiles(it)
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector)
}
}