diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt new file mode 100644 index 00000000000..1c6eca58766 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt @@ -0,0 +1,102 @@ +/* + * 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.psi2ir + +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor +import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.expressions.IrReturnExpressionImpl +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext + +interface IrDeclarationGenerator : IrGenerator { + val irDeclaration: IrDeclaration + val parent: IrDeclarationGenerator? +} + +abstract class IrDeclarationGeneratorBase( + override val context: IrGeneratorContext, + override val irDeclaration: IrDeclaration, + override val parent: IrDeclarationGenerator, + val containingFile: PsiSourceManager.PsiFileEntry +) : IrDeclarationGenerator { + val irExpressionGenerator = IrExpressionGenerator(context, containingFile) + + fun generateAnnotationEntries(annotationEntries: List) { + // TODO create IrAnnotation's for each KtAnnotationEntry + } + + fun generateMemberDeclaration(ktDeclaration: KtDeclaration, containingDeclaration: IrCompoundDeclaration) { + when (ktDeclaration) { + is KtNamedFunction -> + generateFunctionDeclaration(ktDeclaration, containingDeclaration) + is KtProperty -> + generatePropertyDeclaration(ktDeclaration, containingDeclaration) + is KtClassOrObject -> + TODO("classOrObject") + is KtTypeAlias -> + TODO("typealias") + } + } + + private fun loc(ktElement: KtElement) = containingFile.getSourceLocationForElement(ktElement) + + fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction, containingDeclaration: IrCompoundDeclaration) { + val sourceLocation = loc(ktNamedFunction) + val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" } + val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression")) + val irFunction = IrFunctionImpl(sourceLocation, containingDeclaration, functionDescriptor, body) + containingDeclaration.addChildDeclaration(irFunction) + } + + fun generatePropertyDeclaration(ktProperty: KtProperty, containingDeclaration: IrCompoundDeclaration) { + val sourceLocation = loc(ktProperty) + val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) { "unresolved property" } + val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?") + if (ktProperty.hasDelegate()) TODO("handle delegated property") + val initializer = ktProperty.initializer?.let { generateExpressionBody(it) } + val irProperty = IrSimplePropertyImpl(sourceLocation, containingDeclaration, propertyDescriptor, initializer) + containingDeclaration.addChildDeclaration(irProperty) + + val irGetter: IrPropertyGetter? = ktProperty.getter?.let { ktGetter -> + val getterLocation = loc(ktGetter) + val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" } + val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?") + val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter")) + IrPropertyGetterImpl(getterLocation, irProperty, getterDescriptor, getterBody) + } + val irSetter: IrPropertySetter? = ktProperty.setter?.let { ktSetter -> + val getterLocation = loc(ktSetter) + val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" } + val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?") + val getterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter")) + IrPropertySetterImpl(getterLocation, irProperty, setterDescriptor, getterBody) + } + irProperty.initialize(irGetter, irSetter) + } + + fun generateExpressionBody(ktBody: KtExpression): IrBody { + val sourceLocation = loc(ktBody) + val bodyExpression = irExpressionGenerator.generateExpression(ktBody) + + return if (ktBody is KtBlockExpression) + bodyExpression + else + IrReturnExpressionImpl(sourceLocation, bodyExpression.type, bodyExpression) + } +} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt new file mode 100644 index 00000000000..54349bd7022 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt @@ -0,0 +1,76 @@ +/* + * 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.psi2ir + +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.constants.IntValue +import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator + +class IrExpressionGenerator( + override val context: IrGeneratorContext, + val containingFile: PsiSourceManager.PsiFileEntry +) : KtVisitor(), IrGenerator { + fun generateExpression(ktExpression: KtExpression) = ktExpression.irExpr() + + private fun KtElement.irExpr(): IrExpression = accept(this@IrExpressionGenerator, null) + private fun KtElement.loc() = this@IrExpressionGenerator.containingFile.getSourceLocationForElement(this) + private fun KtExpression.type() = getType(this) ?: TODO("no type for expression") + + override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpression = + IrDummyExpression(expression.loc(), expression.type()) + + override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrExpression { + val irBlock = IrBlockExpressionImpl(expression.loc(), expression.type()) + expression.statements.forEach { irBlock.addChildExpression(it.irExpr()) } + return irBlock + } + + override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression = + IrReturnExpressionImpl(expression.loc(), expression.type(), + expression.returnedExpression?.irExpr()) + + override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression { + val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) + ?: error("KtConstantExpression was not evaluated: ${expression.text}") + val constantValue = compileTimeConstant.toConstantValue(expression.type()) + val constantType = constantValue.type + + return when (constantValue) { + is StringValue -> + IrStringLiteralImpl(expression.loc(), constantType, constantValue.value) + is IntValue -> + IrIntLiteralImpl(expression.loc(), constantType, constantValue.value) + else -> + TODO("handle other literal types: ${constantValue.type}") + } + } + + override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrExpression { + if (expression.entries.size == 1 && expression.entries[0] is KtLiteralStringTemplateEntry) { + return expression.entries[0].irExpr() + } + + val irStringTemplate = IrStringTemplateExpressionImpl(expression.loc(), expression.type()) + expression.entries.forEach { irStringTemplate.addStringTemplateEntry(it.irExpr()) } + return irStringTemplate + } + + override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrExpression = + IrStringLiteralImpl(entry.loc(), context.builtIns.stringType, entry.text) +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt new file mode 100644 index 00000000000..b5781ed7590 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt @@ -0,0 +1,35 @@ +/* + * 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.psi2ir + +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.psi.KtFile + +class IrFileGenerator( + context: IrGeneratorContext, + val ktFile: KtFile, + override val irDeclaration: IrFile, + override val parent: IrModuleGenerator +) : IrDeclarationGeneratorBase(context, irDeclaration, parent, irDeclaration.fileEntry as PsiSourceManager.PsiFileEntry) { + fun generateFileContent() { + generateAnnotationEntries(ktFile.annotationEntries) + + for (topLevelDeclaration in ktFile.declarations) { + generateMemberDeclaration(topLevelDeclaration, irDeclaration) + } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt index 39c028326e8..8411e8006f0 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt @@ -16,118 +16,22 @@ package org.jetbrains.kotlin.psi2ir -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor -import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrDummyBody -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice interface IrGenerator { val context: IrGeneratorContext - - operator fun ReadOnlySlice.get(key: K): V? = - context.bindingContext[this, key] } +fun IrGenerator.getType(key: KtExpression): KotlinType? = + context.bindingContext.getType(key) -interface IrDeclarationGenerator : IrGenerator { - val irDeclaration: IrDeclaration - val parent: IrDeclarationGenerator? -} +fun IrGenerator.get(slice: ReadOnlySlice, key: K): V? = + context.bindingContext[slice, key] -class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator { - override val irDeclaration: IrModule get() = context.irModule - override val parent: IrDeclarationGenerator? get() = null +inline fun IrGenerator.getOrFail(slice: ReadOnlySlice, key: K, message: (K) -> String): V = + context.bindingContext[slice, key] ?: throw RuntimeException(message(key)) - fun generateModuleContent() { - for (ktFile in context.inputFiles) { - val packageFragmentDescriptor = BindingContext.FILE_TO_PACKAGE_FRAGMENT[ktFile] ?: TODO("Handle unresolved code") - val irFile = context.irElementFactory.createIrFile(ktFile, packageFragmentDescriptor) - irDeclaration.addFile(irFile) - val generator = IrFileGenerator(context, ktFile, irFile, this) - generator.generateFileContent() - } - } -} - -abstract class IrDeclarationGeneratorBase( - override val context: IrGeneratorContext, - override val irDeclaration: IrDeclaration, - override val parent: IrDeclarationGenerator, - val file: PsiSourceManager.PsiFileEntry -) : IrDeclarationGenerator { - fun generateAnnotationEntries(annotationEntries: List) { - // TODO create IrAnnotation's for each KtAnnotationEntry - } - - fun generateMemberDeclaration(ktDeclaration: KtDeclaration, containingDeclaration: IrCompoundDeclaration) { - when (ktDeclaration) { - is KtNamedFunction -> - generateFunctionDeclaration(ktDeclaration, containingDeclaration) - is KtProperty -> - generatePropertyDeclaration(ktDeclaration, containingDeclaration) - is KtClassOrObject -> - TODO("classOrObject") - is KtTypeAlias -> - TODO("typealias") - } - } - - fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction, containingDeclaration: IrCompoundDeclaration) { - val sourceLocation = file.getSourceLocationForElement(ktNamedFunction) - val functionDescriptor = BindingContext.FUNCTION[ktNamedFunction] ?: TODO("unresolved fun") - val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression")) - val irFunction = IrFunctionImpl(sourceLocation, containingDeclaration, functionDescriptor, body) - containingDeclaration.addChildDeclaration(irFunction) - } - - fun generatePropertyDeclaration(ktProperty: KtProperty, containingDeclaration: IrCompoundDeclaration) { - val sourceLocation = file.getSourceLocationForElement(ktProperty) - val variableDescriptor = BindingContext.VARIABLE[ktProperty] ?: TODO("unresolved property") - val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?") - if (ktProperty.hasDelegate()) TODO("handle delegated property") - val initializer = ktProperty.initializer?.let { generateExpressionBody(it) } - val irProperty = IrSimplePropertyImpl(sourceLocation, containingDeclaration, propertyDescriptor, initializer) - containingDeclaration.addChildDeclaration(irProperty) - - val irGetter: IrPropertyGetter? = ktProperty.getter?.let { ktGetter -> - val getterLocation = file.getSourceLocationForElement(ktGetter) - val accessorDescriptor = BindingContext.PROPERTY_ACCESSOR[ktGetter] ?: TODO("unresolved getter") - val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?") - val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter")) - IrPropertyGetterImpl(getterLocation, irProperty, getterDescriptor, getterBody) - } - val irSetter: IrPropertySetter? = ktProperty.setter?.let { ktSetter -> - val getterLocation = file.getSourceLocationForElement(ktSetter) - val accessorDescriptor = BindingContext.PROPERTY_ACCESSOR[ktSetter] ?: TODO("unresolved setter") - val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?") - val getterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter")) - IrPropertySetterImpl(getterLocation, irProperty, setterDescriptor, getterBody) - } - irProperty.initialize(irGetter, irSetter) - } - - fun generateExpressionBody(ktExpression: KtExpression): IrBody { - val sourceLocation = file.getSourceLocationForElement(ktExpression) - // TODO - return IrDummyBody(sourceLocation) - } -} - -class IrFileGenerator( - context: IrGeneratorContext, - val ktFile: KtFile, - override val irDeclaration: IrFile, - override val parent: IrModuleGenerator -) : IrDeclarationGeneratorBase(context, irDeclaration, parent, irDeclaration.fileEntry as PsiSourceManager.PsiFileEntry) { - fun generateFileContent() { - generateAnnotationEntries(ktFile.annotationEntries) - - for (topLevelDeclaration in ktFile.declarations) { - generateMemberDeclaration(topLevelDeclaration, irDeclaration) - } - } -} \ No newline at end of file +inline fun IrGenerator.getOrElse(slice: ReadOnlySlice, key: K, otherwise: (K) -> V): V = + context.bindingContext[slice, key] ?: otherwise(key) \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt index 278011c46a9..1181b51420b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGeneratorContext.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.psi2ir +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrModule import org.jetbrains.kotlin.psi.KtFile @@ -27,6 +28,7 @@ class IrGeneratorContext( val bindingContext: BindingContext ) { val moduleDescriptor: ModuleDescriptor get() = irModule.descriptor + val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns val sourceManager = PsiSourceManager() val irElementFactory = IrElementFactory(irModule, sourceManager) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt new file mode 100644 index 00000000000..c2d002531fa --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt @@ -0,0 +1,35 @@ +/* + * 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.psi2ir + +import org.jetbrains.kotlin.ir.declarations.IrModule +import org.jetbrains.kotlin.resolve.BindingContext + +class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator { + override val irDeclaration: IrModule get() = context.irModule + override val parent: IrDeclarationGenerator? get() = null + + fun generateModuleContent() { + for (ktFile in context.inputFiles) { + val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" } + val irFile = context.irElementFactory.createIrFile(ktFile, packageFragmentDescriptor) + irDeclaration.addFile(irFile) + val generator = IrFileGenerator(context, ktFile, irFile, this) + generator.generateFileContent() + } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt index 3423d4693a0..9b1f3c34b1a 100644 --- a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt +++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt @@ -86,9 +86,9 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() { val expectedTextFile: File? = expectedTextFileName?.let { val textFile = File(dir, expectedTextFileName) if (!textFile.exists()) { - TestCase.assertTrue("Can't create an IR expected text file: ${textFile.absolutePath}", textFile.createNewFile()) + TestCase.assertTrue("Can't create an IR expected text containingFile: ${textFile.absolutePath}", textFile.createNewFile()) PrintWriter(FileWriter(textFile)).use { - it.println("$expectedTextFileName: new IR expected text file for ${testFile.name}") + it.println("$expectedTextFileName: new IR expected text containingFile for ${testFile.name}") } } textFile diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBlockExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBlockExpression.kt new file mode 100644 index 00000000000..9ee0d9375c0 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBlockExpression.kt @@ -0,0 +1,46 @@ +/* + * 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.ir.expressions + +import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType +import java.util.* + + +interface IrBlockExpression : IrExpression { + val childExpressions: List + fun addChildExpression(childExpression: IrExpression) +} + +class IrBlockExpressionImpl( + sourceLocation: SourceLocation, + type: KotlinType +) : IrExpressionBase(sourceLocation, type), IrBlockExpression { + override val childExpressions: MutableList = ArrayList() + + override fun addChildExpression(childExpression: IrExpression) { + childExpressions.add(childExpression) + } + + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitBlockExpression(this, data) + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + childExpressions.forEach { it.accept(visitor, data) } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDummyBody.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDummyExpression.kt similarity index 86% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDummyBody.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDummyExpression.kt index f4c600e8e19..9b50d62b656 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDummyBody.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDummyExpression.kt @@ -19,8 +19,9 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.SourceLocation import org.jetbrains.kotlin.ir.declarations.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType -class IrDummyBody(override val sourceLocation: SourceLocation) : IrBody { +class IrDummyExpression(sourceLocation: SourceLocation, type: KotlinType) : IrExpressionBase(sourceLocation, type) { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitElement(this, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt index 38e6720b559..faf2044945c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt @@ -17,6 +17,17 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrElementBase +import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.declarations.IrBody +import org.jetbrains.kotlin.types.KotlinType -interface IrExpression : IrElement +interface IrExpression : IrElement, IrBody { + val type: KotlinType +} + +abstract class IrExpressionBase( + sourceLocation: SourceLocation, + override val type: KotlinType +) : IrElementBase(sourceLocation), IrExpression \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLiteral.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLiteral.kt new file mode 100644 index 00000000000..396f5bce4b0 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLiteral.kt @@ -0,0 +1,80 @@ +/* + * 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.ir.expressions + +import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrLiteral : IrExpression + +interface IrNullLiteral : IrLiteral + +interface IrTrueLiteral : IrLiteral + +interface IrFalseLiteral : IrLiteral + +interface IrIntLiteral : IrLiteral { + val value: Int +} + +interface IrLongLiteral : IrLiteral { + val value: Long +} + +interface IrFloatLiteral : IrLiteral { + val value: Float +} + +interface IrDoubleLiteral : IrLiteral { + val value: Double +} + +interface IrCharLiteral : IrLiteral { + val value: Char +} + +interface IrStringLiteral : IrLiteral { + val value: String +} + +abstract class IrLiteralBase( + sourceLocation: SourceLocation, + type: KotlinType +) : IrExpressionBase(sourceLocation, type), IrLiteral { + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + // No children + } +} + +class IrIntLiteralImpl( + sourceLocation: SourceLocation, + type: KotlinType, + override val value: Int +) : IrLiteralBase(sourceLocation, type), IrIntLiteral { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitIntLiteral(this, data) +} + +class IrStringLiteralImpl( + sourceLocation: SourceLocation, + type: KotlinType, + override val value: String +) : IrLiteralBase(sourceLocation, type), IrStringLiteral { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitStringLiteral(this, data) +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt new file mode 100644 index 00000000000..2e5ea436cc7 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt @@ -0,0 +1,39 @@ +/* + * 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.ir.expressions + +import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + + +interface IrReturnExpression : IrExpression { + val returnValueExpression: IrExpression? +} + +class IrReturnExpressionImpl( + sourceLocation: SourceLocation, + type: KotlinType, + override val returnValueExpression: IrExpression? +) : IrExpressionBase(sourceLocation, type), IrReturnExpression { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitReturnExpression(this, data) + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + returnValueExpression?.accept(visitor, data) + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStringTemplateExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStringTemplateExpression.kt new file mode 100644 index 00000000000..fb0d86de408 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStringTemplateExpression.kt @@ -0,0 +1,45 @@ +/* + * 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.ir.expressions + +import org.jetbrains.kotlin.ir.SourceLocation +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType +import java.util.* + +interface IrStringTemplateExpression : IrExpression { + val entries: List + fun addStringTemplateEntry(entry: IrExpression) +} + +class IrStringTemplateExpressionImpl( + sourceLocation: SourceLocation, + type: KotlinType +) : IrExpressionBase(sourceLocation, type), IrStringTemplateExpression { + override val entries: MutableList = ArrayList() + + override fun addStringTemplateEntry(entry: IrExpression) { + entries.add(entry) + } + + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitStringTemplate(this, data) + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + entries.forEach { it.accept(visitor, data) } + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/Dump.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt similarity index 85% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/Dump.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt index dc0f44ba62b..68cfce1de02 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/Dump.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.utils.Printer fun IrDeclaration.dump(): String { @@ -27,11 +27,11 @@ fun IrDeclaration.dump(): String { return sb.toString() } -class DumpIrTreeVisitor(out: Appendable): IrElementVisitorVoid { +class DumpIrTreeVisitor(out: Appendable): IrElementVisitor { val printer = Printer(out, " ") val elementRenderer = RenderIrElementVisitor() - override fun visitElement(element: IrElement) { + override fun visitElement(element: IrElement, data: Nothing?) { printer.println(element.accept(elementRenderer, null)) printer.pushIndent() element.acceptChildren(this, null) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/Render.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt similarity index 76% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/Render.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index 3555512abc9..9602042b0ac 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/Render.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.renderer.ClassifierNamePolicy import org.jetbrains.kotlin.renderer.DescriptorRenderer @@ -48,7 +48,19 @@ class RenderIrElementVisitor : IrElementVisitor { "IrPropertySetter ${declaration.renderDescriptor()}" override fun visitExpression(expression: IrExpression, data: Nothing?): String = - expression.javaClass.simpleName + "??? ${expression.javaClass.simpleName} type=${expression.renderType()}" + + override fun visitStringLiteral(expression: IrStringLiteral, data: Nothing?): String = + "IrStringLiteral ${expression.value}" + + override fun visitIntLiteral(expression: IrIntLiteral, data: Nothing?): String = + "IrIntLiteral type=${expression.renderType()} value=${expression.value}" + + override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?): String = + "IrBlockExpression type=${expression.renderType()}" + + override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String = + "IrReturnExpression type=${expression.renderType()}" companion object { private val DESCRIPTOR_RENDERER = DescriptorRenderer.withOptions { @@ -61,5 +73,6 @@ class RenderIrElementVisitor : IrElementVisitor { } private fun IrDeclaration.renderDescriptor(): String = DESCRIPTOR_RENDERER.render(descriptor) + private fun IrExpression.renderType(): String = DESCRIPTOR_RENDERER.renderType(type) } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt index 6a43328ff23..8100cd0a39e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.ir.visitors import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.* interface IrElementVisitor { fun visitElement(element: IrElement, data: D): R @@ -36,4 +36,19 @@ interface IrElementVisitor { fun visitDelegatedProperty(declaration: IrDelegatedProperty, data: D): R = visitProperty(declaration, data) fun visitExpression(expression: IrExpression, data: D): R = visitElement(expression, data) + + fun visitLiteral(expression: IrLiteral, data: D): R = visitExpression(expression, data) + fun visitNullLiteral(expression: IrNullLiteral, data: D): R = visitLiteral(expression, data) + fun visitTrueLiteral(expression: IrTrueLiteral, data: D): R = visitLiteral(expression, data) + fun visitFalseLiteral(expression: IrFalseLiteral, data: D): R = visitLiteral(expression, data) + fun visitIntLiteral(expression: IrIntLiteral, data: D): R = visitLiteral(expression, data) + fun visitLongLiteral(expression: IrLongLiteral, data: D): R = visitLiteral(expression, data) + fun visitFloatLiteral(expression: IrFloatLiteral, data: D): R = visitLiteral(expression, data) + fun visitDoubleLiteral(expression: IrDoubleLiteral, data: D): R = visitLiteral(expression, data) + fun visitCharLiteral(expression: IrCharLiteral, data: D): R = visitLiteral(expression, data) + fun visitStringLiteral(expression: IrStringLiteral, data: D): R = visitLiteral(expression, data) + + fun visitReturnExpression(expression: IrReturnExpression, data: D): R = visitExpression(expression, data) + fun visitBlockExpression(expression: IrBlockExpression, data: D): R = visitExpression(expression, data) + fun visitStringTemplate(expression: IrStringTemplateExpression, data: D) = visitExpression(expression, data) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt deleted file mode 100644 index 69b022df45f..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.ir.visitors - -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.* - -interface IrElementVisitorVoid : IrElementVisitor { - fun visitElement(element: IrElement) - fun visitDeclaration(declaration: IrDeclaration) = visitElement(declaration) - fun visitCompoundDeclaration(declaration: IrCompoundDeclaration) = visitDeclaration(declaration) - fun visitModule(declaration: IrModule) = visitCompoundDeclaration(declaration) - fun visitFile(declaration: IrFile) = visitCompoundDeclaration(declaration) - fun visitClass(declaration: IrClass) = visitCompoundDeclaration(declaration) - fun visitFunction(declaration: IrFunction) = visitDeclaration(declaration) - fun visitPropertyGetter(declaration: IrPropertyGetter) = visitFunction(declaration) - fun visitPropertySetter(declaration: IrPropertySetter) = visitFunction(declaration) - fun visitProperty(declaration: IrProperty) = visitDeclaration(declaration) - - // Delegating methods from IrDeclarationVisitor - override fun visitElement(element: IrElement, data: Nothing?) = visitElement(element) - override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?) = visitDeclaration(declaration) - override fun visitCompoundDeclaration(declaration: IrCompoundDeclaration, data: Nothing?) = visitCompoundDeclaration(declaration) - override fun visitModule(declaration: IrModule, data: Nothing?) = visitModule(declaration) - override fun visitFile(declaration: IrFile, data: Nothing?) = visitFile(declaration) - override fun visitClass(declaration: IrClass, data: Nothing?) = visitClass(declaration) - override fun visitFunction(declaration: IrFunction, data: Nothing?) = visitFunction(declaration) - override fun visitPropertyGetter(declaration: IrPropertyGetter, data: Nothing?) = visitPropertyGetter(declaration) - override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?) = visitPropertySetter(declaration) - override fun visitProperty(declaration: IrProperty, data: Nothing?) = visitProperty(declaration) -} \ No newline at end of file diff --git a/compiler/testData/ir/irText/boxOk.kt b/compiler/testData/ir/irText/boxOk.kt new file mode 100644 index 00000000000..e958c5c4d63 --- /dev/null +++ b/compiler/testData/ir/irText/boxOk.kt @@ -0,0 +1,3 @@ +fun box(): String = "OK" + +// IR_FILE_TXT boxOk.txt \ No newline at end of file diff --git a/compiler/testData/ir/irText/boxOk.txt b/compiler/testData/ir/irText/boxOk.txt new file mode 100644 index 00000000000..53e1687afda --- /dev/null +++ b/compiler/testData/ir/irText/boxOk.txt @@ -0,0 +1,3 @@ +IrFile /boxOk.kt + IrFunction public fun box(): kotlin.String + ??? IrDummyBody diff --git a/compiler/testData/ir/irText/smoke.kt b/compiler/testData/ir/irText/smoke.kt index 4ea9156c476..da6b7411cba 100644 --- a/compiler/testData/ir/irText/smoke.kt +++ b/compiler/testData/ir/irText/smoke.kt @@ -1,4 +1,4 @@ -fun testFun() {} +fun testFun(): String { return "OK" } val testSimpleVal = 1 val testValWithGetter: Int get() = 42 var testSimpleVar = 2 @@ -10,8 +10,8 @@ var testVarWithAccessors: Int // 1 IrProperty public val testSimpleVal // 1 IrProperty public val testValWithGetter // 2 IrPropertyGetter +// 1 IrPropertySetter // 1 IrProperty public var testSimpleVar // 1 IrProperty public var testVarWithAccessors -// 1 IrPropertyGetter // IR_FILE_TXT smoke.txt \ No newline at end of file diff --git a/compiler/testData/ir/irText/smoke.txt b/compiler/testData/ir/irText/smoke.txt index 71c5910fec4..5a952252daf 100644 --- a/compiler/testData/ir/irText/smoke.txt +++ b/compiler/testData/ir/irText/smoke.txt @@ -1,15 +1,21 @@ IrFile /smoke.kt - IrFunction public fun testFun(): kotlin.Unit - ??? IrDummyBody + IrFunction public fun testFun(): kotlin.String + IrBlockExpression type=kotlin.Nothing + IrReturnExpression type=kotlin.Nothing + IrStringLiteral OK IrProperty public val testSimpleVal: kotlin.Int = 1 - ??? IrDummyBody + IrReturnExpression type=kotlin.Int + IrIntLiteral type=kotlin.Int value=1 IrProperty public val testValWithGetter: kotlin.Int IrPropertyGetter public fun (): kotlin.Int - ??? IrDummyBody + IrReturnExpression type=kotlin.Int + IrIntLiteral type=kotlin.Int value=42 IrProperty public var testSimpleVar: kotlin.Int - ??? IrDummyBody + IrReturnExpression type=kotlin.Int + IrIntLiteral type=kotlin.Int value=2 IrProperty public var testVarWithAccessors: kotlin.Int IrPropertyGetter public fun (): kotlin.Int - ??? IrDummyBody + IrReturnExpression type=kotlin.Int + IrIntLiteral type=kotlin.Int value=42 IrPropertySetter public fun (/*0*/ v: kotlin.Int): kotlin.Unit - ??? IrDummyBody + IrBlockExpression type=kotlin.Unit