[Raw FIR] Synchronize enum entry building in PSI / light AST modes

This commit is contained in:
Mikhail Glukhikh
2020-01-09 12:44:39 +03:00
parent 65a44e2e20
commit 2b05320ae9
19 changed files with 353 additions and 44 deletions
@@ -612,7 +612,7 @@ class DeclarationsConverter(
* primaryConstructor branch
*/
private fun convertPrimaryConstructor(primaryConstructor: LighterASTNode?, classWrapper: ClassWrapper): PrimaryConstructor? {
if (primaryConstructor == null && classWrapper.hasSecondaryConstructor) return null
if (primaryConstructor == null && !classWrapper.isEnumEntry() && classWrapper.hasSecondaryConstructor) return null
if (classWrapper.isInterface()) return null
var modifiers = Modifier()
@@ -32,6 +32,10 @@ class ClassWrapper(
return className == SpecialNames.NO_NAME_PROVIDED && isObject()
}
fun isEnumEntry(): Boolean {
return classKind == ClassKind.ENUM_ENTRY
}
private fun isObject(): Boolean {
return classKind == ClassKind.OBJECT
}
@@ -40,11 +40,21 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/psi2fir/testData/rawBuilder/declarations"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("annotation.kt")
public void testAnnotation() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
}
@TestMetadata("complexTypes.kt")
public void testComplexTypes() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
}
@TestMetadata("constructorInObject.kt")
public void testConstructorInObject() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
}
@TestMetadata("derivedClass.kt")
public void testDerivedClass() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
@@ -27,10 +27,16 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
private fun compareBase(path: String, withTestData: Boolean, compareFir: (File) -> Boolean) {
var counter = 0
var errorCounter = 0
val differentFiles = mutableListOf<File>()
val onEachFile: (File) -> Unit = { file ->
if (!compareFir(file)) errorCounter++
counter++
if (!compareFir(file)) {
errorCounter++
differentFiles += file
}
if (!file.name.endsWith(".fir.kt")) {
counter++
}
}
println("BASE PATH: $path")
if (!withTestData) {
@@ -40,6 +46,9 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
}
println("All scanned files: $counter")
println("Files that aren't equal to FIR: $errorCounter")
if (errorCounter > 0) {
println(differentFiles)
}
TestCase.assertEquals(0, errorCounter)
}
@@ -64,6 +73,9 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
fun testCompareDiagnostics() {
val lightTreeConverter = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = false)
compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file ->
if (file.name.endsWith(".fir.kt")) {
return@compareBase true
}
val notEditedText = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
val text = notEditedText.replace("(<!>)|(<!.*?!>)".toRegex(), "").replaceAfter(".java", "")
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, val stubMode: Boolean) : BaseFirBuilder<PsiElement>(session) {
@@ -475,14 +476,21 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va
val delegatedEntrySelfType =
FirResolvedTypeRefImpl(source = null, ConeClassLikeTypeImpl(obj.symbol.toLookupTag(), emptyArray(), isNullable = false))
extractSuperTypeListEntriesTo(obj, delegatedEntrySelfType, delegatedEnumSelfTypeRef, ClassKind.ENUM_ENTRY)
extractAnnotationsTo(obj)
obj.superTypeRefs += delegatedEnumSelfTypeRef
obj.declarations += primaryConstructor.toFirConstructor(
superTypeListEntries.firstIsInstanceOrNull(),
delegatedEnumSelfTypeRef,
delegatedEntrySelfType,
owner = this
)
for (declaration in declarations) {
obj.declarations += declaration.toFirDeclaration(
delegatedEnumSelfTypeRef,
delegatedSelfType = null,
delegatedSelfType = delegatedEntrySelfType,
this,
hasPrimaryConstructor = false
hasPrimaryConstructor = true
)
}
@@ -0,0 +1,20 @@
@Target(AnnotationTarget.ANNOTATION_CLASS) annotation class base
@base annotation class derived
@base class correct(@base val x: Int) {
@base constructor(): this(0)
}
@base enum class My {
@base FIRST,
@base SECOND
}
@base fun foo(@base y: @base Int): Int {
@base fun bar(@base z: @base Int) = z + 1
@base val local = bar(y)
return local
}
@base val z = 0
@@ -0,0 +1,62 @@
FILE: annotation.kt
@Target(AnnotationTarget#.ANNOTATION_CLASS#) public? final? annotation class base : R|kotlin/Annotation| {
public? constructor(): R|base| {
super<R|kotlin/Any|>()
}
}
@base() public? final? annotation class derived : R|kotlin/Annotation| {
public? constructor(): R|derived| {
super<R|kotlin/Any|>()
}
}
@base() public? final? class correct : R|kotlin/Any| {
public? constructor(@base() x: Int): R|correct| {
super<R|kotlin/Any|>()
}
@base() public? final? val x: Int = R|<local>/x|
public? get(): Int
@base() public? constructor(): R|correct| {
this<R|correct|>(IntegerLiteral(0))
}
}
@base() public? final? enum class My : R|kotlin/Enum<My>| {
private constructor(): R|My| {
super<R|kotlin/Any|>()
}
public final static enum entry FIRST: R|My| = @base() object : R|My| {
public? constructor(): R|anonymous| {
super<R|My|>()
}
}
public final static enum entry SECOND: R|My| = @base() object : R|My| {
public? constructor(): R|anonymous| {
super<R|My|>()
}
}
public final static fun values(): R|kotlin/Array<My>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|My| {
}
}
@base() public? final? fun foo(@base() y: @base() Int): Int {
@base() local final? fun bar(@base() z: @base() Int): <implicit> {
^bar z#.plus#(IntegerLiteral(1))
}
@base() lval local: <implicit> = bar#(y#)
^foo local#
}
@base() public? final? val z: <implicit> = IntegerLiteral(0)
public? get(): <implicit>
@@ -0,0 +1,20 @@
object A {
constructor()
init {}
}
enum class B {
X() {
constructor()
}
}
class C {
companion object {
constructor()
}
}
val anonObject = object {
constructor()
}
@@ -0,0 +1,54 @@
FILE: constructorInObject.kt
public? final? object A : R|kotlin/Any| {
public? constructor(): R|A| {
super<R|kotlin/Any|>()
}
init {
}
}
public? final? enum class B : R|kotlin/Enum<B>| {
private constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final static enum entry X: R|B| = object : R|B| {
public? constructor(): R|anonymous| {
super<R|B|>()
}
public? constructor(): R|anonymous| {
this<R|anonymous|>()
}
}
public final static fun values(): R|kotlin/Array<B>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|B| {
}
}
public? final? class C : R|kotlin/Any| {
public? constructor(): R|C| {
super<R|kotlin/Any|>()
}
public? final? companion object Companion : R|kotlin/Any| {
public? constructor(): R|C.Companion| {
super<R|kotlin/Any|>()
}
}
}
public? final? val anonObject: <implicit> = object : R|kotlin/Any| {
public? constructor(): <ERROR TYPE REF: Constructor in object> {
super<<ERROR TYPE REF: No super type>>()
}
}
public? get(): <implicit>
@@ -4,33 +4,27 @@ FILE: enums.kt
super<R|kotlin/Any|>()
}
public final static val FIRST: R|Order| = object : R|Order| {
public? constructor(): R|Order| {
public final static enum entry FIRST: R|Order| = object : R|Order| {
public? constructor(): R|anonymous| {
super<R|Order|>()
}
}
public final static val SECOND: R|Order| = object : R|Order| {
public? constructor(): R|Order| {
public final static enum entry SECOND: R|Order| = object : R|Order| {
public? constructor(): R|anonymous| {
super<R|Order|>()
}
}
public final static val THIRD: R|Order| = object : R|Order| {
public? constructor(): R|Order| {
public final static enum entry THIRD: R|Order| = object : R|Order| {
public? constructor(): R|anonymous| {
super<R|Order|>()
}
}
public final static fun values(): R|kotlin/Array<Order>| {
}
@@ -49,9 +43,9 @@ FILE: enums.kt
internal final? val r: Double = R|<local>/r|
internal get(): Double
public final static val MERCURY: R|Planet| = object : Planet {
public? constructor(): Planet {
super<Planet>(Double(1.0), Double(2.0))
public final static enum entry MERCURY: R|Planet| = object : R|Planet| {
public? constructor(): R|anonymous| {
super<R|Planet|>(Double(1.0), Double(2.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
@@ -60,11 +54,9 @@ FILE: enums.kt
}
public final static val VENERA: R|Planet| = object : Planet {
public? constructor(): Planet {
super<Planet>(Double(3.0), Double(4.0))
public final static enum entry VENERA: R|Planet| = object : R|Planet| {
public? constructor(): R|anonymous| {
super<R|Planet|>(Double(3.0), Double(4.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
@@ -73,11 +65,9 @@ FILE: enums.kt
}
public final static val EARTH: R|Planet| = object : Planet {
public? constructor(): Planet {
super<Planet>(Double(5.0), Double(6.0))
public final static enum entry EARTH: R|Planet| = object : R|Planet| {
public? constructor(): R|anonymous| {
super<R|Planet|>(Double(5.0), Double(6.0))
}
public? open? override fun sayHello(): R|kotlin/Unit| {
@@ -86,8 +76,6 @@ FILE: enums.kt
}
public? final? val g: Double = G#.times#(m#).div#(r#.times#(r#))
public? get(): Double
@@ -21,9 +21,9 @@ FILE: enums2.kt
public? final? val x: Some = R|<local>/x|
public? get(): Some
public final static val FIRST: R|SomeEnum| = object : SomeEnum {
public? constructor(): SomeEnum {
super<SomeEnum>(O1#)
public final static enum entry FIRST: R|SomeEnum| = object : R|SomeEnum| {
public? constructor(): R|anonymous| {
super<R|SomeEnum|>(O1#)
}
public? open? override fun check(y: Some): Boolean {
@@ -32,11 +32,9 @@ FILE: enums2.kt
}
public final static val SECOND: R|SomeEnum| = object : SomeEnum {
public? constructor(): SomeEnum {
super<SomeEnum>(O2#)
public final static enum entry SECOND: R|SomeEnum| = object : R|SomeEnum| {
public? constructor(): R|anonymous| {
super<R|SomeEnum|>(O2#)
}
public? open? override fun check(y: Some): Boolean {
@@ -45,8 +43,6 @@ FILE: enums2.kt
}
public? abstract fun check(y: Some): Boolean
public final static fun values(): R|kotlin/Array<SomeEnum>| {
@@ -40,11 +40,21 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/psi2fir/testData/rawBuilder/declarations"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("annotation.kt")
public void testAnnotation() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
}
@TestMetadata("complexTypes.kt")
public void testComplexTypes() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
}
@TestMetadata("constructorInObject.kt")
public void testConstructorInObject() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
}
@TestMetadata("derivedClass.kt")
public void testDerivedClass() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
@@ -5,7 +5,7 @@ object A {
enum class B {
X() {
<!CONSTRUCTOR_IN_OBJECT!>constructor()<!>
<!UNRESOLVED_REFERENCE!>constructor()<!>
}
}
@@ -0,0 +1,57 @@
//constructor annotation/Target(vararg annotation/AnnotationTarget)
//│ enum class annotation/AnnotationTarget: Enum<annotation/AnnotationTarget>
//│ │ enum entry annotation/AnnotationTarget.ANNOTATION_CLASS
//│ │ │
@Target(AnnotationTarget.ANNOTATION_CLASS) annotation class base
//constructor base()
//│
@base annotation class derived
//constructor base() constructor base()
//│ │
@base class correct(@base val x: Int) {
// constructor base() Int
// │ │
@base constructor(): this(0)
}
//constructor base()
//│
@base enum class My {
// constructor base()
// │
@base FIRST,
// constructor base()
// │
@base SECOND
}
//constructor base()
//│ constructor base()
//│ │ constructor base()
//│ │ │
@base fun foo(@base y: @base Int): Int {
// constructor base()
// │ constructor base()
// │ │ constructor base()
// │ │ │ Int
// │ │ │ │ foo.bar.z: Int
// │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ Int
// │ │ │ │ │ │ │
@base fun bar(@base z: @base Int) = z + 1
// constructor base()
// │ fun foo.bar(Int): Int
// │ Int │ foo.y: Int
// │ │ │ │
@base val local = bar(y)
// val foo.local: Int
// │
return local
}
//constructor base()
//│ Int Int
//│ │ │
@base val z = 0
@@ -0,0 +1,24 @@
object A {
constructor()
init {}
}
enum class B {
// constructor B()
// │
X() {
constructor()
}
}
class C {
companion object {
constructor()
}
}
// Any
// │
val anonObject = object {
constructor()
}
@@ -0,0 +1,19 @@
// T fun (() -> T).invoke(): T
// │ │
fun <T> run(block: () -> T): T = block()
fun test_1() {
// fun <T> run<Unit>(() -> Unit): Unit
// │
run { return@run }
// fun <T> run<???>(() -> ???): ???
// │
run { return }
}
fun test_2() {
// fun <T> run<Int>(() -> Int): Int
// │ Int
// │ │
run(fun (): Int { return 1 })
}
@@ -0,0 +1,5 @@
fun test() {
// class Array<T>: Any, Cloneable, java/io/Serializable
// │
Array<String>::class
}
@@ -40,11 +40,21 @@ public class FirVisualizerForRawFirDataGenerated extends AbstractFirVisualizer {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/psi2fir/testData/rawBuilder/declarations"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("annotation.kt")
public void testAnnotation() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
}
@TestMetadata("complexTypes.kt")
public void testComplexTypes() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
}
@TestMetadata("constructorInObject.kt")
public void testConstructorInObject() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
}
@TestMetadata("derivedClass.kt")
public void testDerivedClass() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
@@ -40,11 +40,21 @@ public class PsiVisualizerForRawFirDataGenerated extends AbstractPsiVisualizer {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/psi2fir/testData/rawBuilder/declarations"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("annotation.kt")
public void testAnnotation() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
}
@TestMetadata("complexTypes.kt")
public void testComplexTypes() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
}
@TestMetadata("constructorInObject.kt")
public void testConstructorInObject() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
}
@TestMetadata("derivedClass.kt")
public void testDerivedClass() throws Exception {
runTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");