Generate IrTypeParameter and IrValueParameter declarations

This commit is contained in:
Dmitry Petrov
2017-03-15 17:47:46 +03:00
parent 03b664febd
commit 8cea27b5bb
149 changed files with 2251 additions and 331 deletions
@@ -18,14 +18,20 @@ package org.jetbrains.kotlin.ir
import com.intellij.openapi.util.text.StringUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.dumpTreesFromLineNumber
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.utils.rethrow
import java.io.File
import java.util.*
import java.util.regex.Pattern
abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
@@ -52,10 +58,13 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
for (irTreeFileLabel in expectations.irTreeFileLabels) {
val actualTrees = irFile.dumpTreesFromLineNumber(irTreeFileLabel.lineNumber)
KotlinTestUtils.assertEqualsToFile(irTreeFileLabel.expectedTextFile, actualTrees)
verify(irFile, irFileDump)
// Check that deep copy produces an equivalent result
val copiedTrees = irFile.transform(DeepCopyIrTree(), null).dumpTreesFromLineNumber(irTreeFileLabel.lineNumber)
KotlinTestUtils.assertEqualsToFile(irTreeFileLabel.expectedTextFile, copiedTrees)
val irFileCopy = irFile.transform(DeepCopyIrTree(), null)
val copiedTrees = irFileCopy.dumpTreesFromLineNumber(irTreeFileLabel.lineNumber)
TestCase.assertEquals("IR dump mismatch after deep copy", actualTrees, copiedTrees)
verify(irFileCopy, irFileCopy.dump())
}
try {
@@ -67,6 +76,84 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
}
}
private fun verify(irFile: IrFile, dump: String) {
val irVerifier = IrVerifier()
irVerifier.verify(irFile)
TestCase.assertFalse(irVerifier.errorsAsMessage + "\n\n\n" + dump, irVerifier.hasErrors)
}
private class IrVerifier : IrElementVisitorVoid {
private val errors = ArrayList<String>()
val hasErrors get() = errors.isNotEmpty()
val errorsAsMessage get() = errors.joinToString(prefix = "IR verifier errors:\n", separator = "\n")
private fun error(message: String) {
errors.add(message)
}
fun verify(irFile: IrFile) {
irFile.acceptChildrenVoid(this)
}
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitFunction(declaration: IrFunction) {
val functionDescriptor = declaration.descriptor
checkTypeParameters(functionDescriptor, declaration, functionDescriptor.typeParameters)
declaration.dispatchReceiverParameter?.descriptor.let { dispatchReceiverDescriptor ->
if (dispatchReceiverDescriptor != functionDescriptor.dispatchReceiverParameter) {
error("$functionDescriptor: Dispatch receiver parameter mismatch: " +
"$dispatchReceiverDescriptor != ${functionDescriptor.dispatchReceiverParameter}")
}
}
declaration.extensionReceiverParameter?.descriptor.let { extensionReceiverDescriptor ->
if (extensionReceiverDescriptor != functionDescriptor.extensionReceiverParameter) {
error("$functionDescriptor: Extension receiver parameter mismatch: " +
"$extensionReceiverDescriptor != ${functionDescriptor.extensionReceiverParameter}")
}
}
val declaredValueParameters = declaration.valueParameters.map { it.descriptor }
val actualValueParameters = functionDescriptor.valueParameters
if (declaredValueParameters.size != actualValueParameters.size) {
error("$functionDescriptor: Value parameters mismatch: $declaredValueParameters != $actualValueParameters")
}
else {
declaredValueParameters.zip(actualValueParameters).forEach { (declaredValueParameter, actualValueParameter) ->
if (declaredValueParameter != actualValueParameter) {
error("$functionDescriptor: Value parameters mismatch: $declaredValueParameter != $actualValueParameter")
}
}
}
}
override fun visitClass(declaration: IrClass) {
checkTypeParameters(declaration.descriptor, declaration, declaration.descriptor.declaredTypeParameters)
}
private fun checkTypeParameters(descriptor: DeclarationDescriptor, declaration: IrTypeParametersContainer, expectedTypeParameters: List<TypeParameterDescriptor>) {
val declaredTypeParameters = declaration.typeParameters.map { it.descriptor }
if (declaredTypeParameters.size != expectedTypeParameters.size) {
error("$descriptor: Type parameters mismatch: $declaredTypeParameters != $expectedTypeParameters")
}
else {
declaredTypeParameters.zip(expectedTypeParameters).forEach { (declaredTypeParameter, expectedTypeParameter) ->
if (declaredTypeParameter != expectedTypeParameter) {
error("$descriptor: Type parameters mismatch: $declaredTypeParameter != $expectedTypeParameter")
}
}
}
}
}
internal class Expectations(val regexps: List<RegexpInText>, val irTreeFileLabels: List<IrTreeFileLabel>)
internal class RegexpInText(val numberOfOccurrences: Int, val needle: String) {
@@ -287,6 +287,69 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("compiler/testData/ir/irText/declarations/parameters")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Parameters extends AbstractIrTextTestCase {
public void testAllFilesPresentInParameters() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/declarations/parameters"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("class.kt")
public void testClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/class.kt");
doTest(fileName);
}
@TestMetadata("constructor.kt")
public void testConstructor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/constructor.kt");
doTest(fileName);
}
@TestMetadata("dataClassMembers.kt")
public void testDataClassMembers() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/dataClassMembers.kt");
doTest(fileName);
}
@TestMetadata("defaultPropertyAccessors.kt")
public void testDefaultPropertyAccessors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/defaultPropertyAccessors.kt");
doTest(fileName);
}
@TestMetadata("delegatedMembers.kt")
public void testDelegatedMembers() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/delegatedMembers.kt");
doTest(fileName);
}
@TestMetadata("fun.kt")
public void testFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/fun.kt");
doTest(fileName);
}
@TestMetadata("lambdas.kt")
public void testLambdas() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/lambdas.kt");
doTest(fileName);
}
@TestMetadata("localFun.kt")
public void testLocalFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/localFun.kt");
doTest(fileName);
}
@TestMetadata("propertyAccessors.kt")
public void testPropertyAccessors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/parameters/propertyAccessors.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/ir/irText/declarations/provideDelegate")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)