[AA] Allow specifying REx file contents in testdata.

Tests can now specify the code generated by a resolve extension from
within the test's testdata. Module-level directives control whether
resolve extensions are enabled for that module, as well as package names
and source shadowing regexes. File-level directives allow a `// FILE:`
block within the testdata to be converted into a KtResolveExtensionFile
and removed from the module as a whole. (This requires a new
`ModuleStructureTransformer`, because we need to be able to entirely
remove the files in question.)

Any test can add support for these directives by calling
`KtResolveExtensionTestSupport.configure` from within their
`configureTest` stanza. This allows this functionality to be used in
conjuction with any test base class.

^KT-59329
This commit is contained in:
Justin Paupore
2023-06-14 23:49:03 -07:00
committed by Ilya Kirillov
parent 7a69f13fd6
commit 734b87b97e
41 changed files with 666 additions and 565 deletions
@@ -0,0 +1,29 @@
// MODULE: extendedModule
// WITH_RESOLVE_EXTENSION
// RESOLVE_EXTENSION_PACKAGE: generated
// FILE: resolve1.kt
// RESOLVE_EXTENSION_FILE
package generated
// RESOLVE_EXTENSION_CLASSIFIER: GeneratedClass1
class GeneratedClass1
// FILE: resolve2.kt
// RESOLVE_EXTENSION_FILE
package generated
// RESOLVE_EXTENSION_CLASSIFIER: GeneratedClass2
class GeneratedClass2() {
fun generatedClassMember2(): GeneratedClass1 = TODO()
}
// MODULE: dependency2
// MODULE: main(extendedModule, dependency2)()()
import generated.*
fun main() {
val a = GeneratedClass2()
a.gener<caret>atedClassMember2()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in generated.GeneratedClass2) fun generatedClassMember2(): generated.GeneratedClass1
@@ -0,0 +1,19 @@
// MODULE: extendedModule
// WITH_RESOLVE_EXTENSION
// RESOLVE_EXTENSION_PACKAGE: generated
// FILE: extension.kt
// RESOLVE_EXTENSION_FILE
package generated
// RESOLVE_EXTENSION_CALLABLE: generatedTopLevelExtensionFunction1
fun String.generatedTopLevelExtensionFunction1(boolean: Boolean): Int
// MODULE: dependency2
// MODULE: main(extendedModule, dependency2)()()
import generated.*
fun main() {
"string".generatedTopLeve<caret>lExtensionFunction1(true)
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in generated) fun kotlin.String.generatedTopLevelExtensionFunction1(boolean: kotlin.Boolean): kotlin.Int
@@ -0,0 +1,19 @@
// UNRESOLVED_REFERENCE
// MODULE: extendedModule
// WITH_RESOLVE_EXTENSION
// RESOLVE_EXTENSION_PACKAGE: generated
// RESOLVE_EXTENSION_SHADOWED: \.hidden\.kt$
// FILE: declarations.hidden.kt
package foo
fun bar() = "baz"
// MODULE: dependency2
// MODULE: main(extendedModule, dependency2)()()
// FILE: main.kt
fun main() {
val x = foo.<caret>bar()
}
@@ -0,0 +1,23 @@
// UNRESOLVED_REFERENCE
// MODULE: extendedModule
// WITH_RESOLVE_EXTENSION
// RESOLVE_EXTENSION_PACKAGE: generated
// RESOLVE_EXTENSION_SHADOWED: \.hidden\.[a-z]+$
// FILE: TestClass.hidden.java
package foo;
public class TestClass {
public TestClass() {}
}
// MODULE: dependency2
// MODULE: main(extendedModule, dependency2)()()
// FILE: main.kt
package foo
fun main() {
val x = <caret>TestClass()
}
@@ -0,0 +1,26 @@
// MODULE: extendedModule
// WITH_RESOLVE_EXTENSION
// RESOLVE_EXTENSION_PACKAGE: generated
// RESOLVE_EXTENSION_SHADOWED: \.hidden\.kt$
// FILE: extension.kt
// RESOLVE_EXTENSION_FILE
package generated
// RESOLVE_EXTENSION_CALLABLE: generatedOverloadedExtensionFunction
fun Any.generatedOverloadedExtensionFunction(): Int = TODO()
// FILE: generated.hidden.kt
package generated
fun String.generatedOverloadedExtensionFunction(): Int = TODO()
// MODULE: dependency2
// MODULE: main(extendedModule, dependency2)()()
// FILE: main.kt
import generated.*
fun main() {
"string".generatedOverloadedExtension<caret>Function()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in generated) fun kotlin.Any.generatedOverloadedExtensionFunction(): kotlin.Int
@@ -0,0 +1,31 @@
// MODULE: extendedModule
// WITH_RESOLVE_EXTENSION
// RESOLVE_EXTENSION_PACKAGE: generated
// FILE: extension.kt
// RESOLVE_EXTENSION_FILE
package generated
// RESOLVE_EXTENSION_CLASSIFIER: GeneratedClass1
class GeneratedClass1
// RESOLVE_EXTENSION_CALLABLE: generatedTopLevelFunction1
fun generatedTopLevelFunction1(): GeneratedClass2
// FILE: extension2.kt
// RESOLVE_EXTENSION_FILE
package generated
// RESOLVE_EXTENSION_CLASSIFIER: GeneratedClass2
class GeneratedClass2 {
fun generatedClassMember2(): GeneratedClass1
}
// MODULE: dependency2
// MODULE: main(extendedModule, dependency2)()()
import generated.*
fun main() {
generatedTopLevelFunc<caret>tion1()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in generated) fun generatedTopLevelFunction1(): generated.GeneratedClass2