diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index 2284bdee2e9..37f65bfe7b6 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.psi2ir import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrModule -import org.jetbrains.kotlin.ir.declarations.IrModuleImpl import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.generators.IrGeneratorContext import org.jetbrains.kotlin.psi2ir.generators.IrModuleGenerator @@ -32,9 +31,8 @@ class Psi2IrTranslator(val configuration: Configuration = Configuration()) { ) fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: List, bindingContext: BindingContext): IrModule { - val irModule = IrModuleImpl(moduleDescriptor) - val irGeneratorContext = IrGeneratorContext(ktFiles, irModule, bindingContext) - IrModuleGenerator(irGeneratorContext).generateModuleContent() + val irGeneratorContext = IrGeneratorContext(moduleDescriptor, bindingContext) + val irModule = IrModuleGenerator(irGeneratorContext).generateModule(ktFiles) postprocess(irModule) return irModule } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt index e89a81f8ec7..918fd66723e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrCallGenerator.kt @@ -29,17 +29,19 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.* import org.jetbrains.kotlin.types.KotlinType import java.util.* -class IrCallGenerator( - private val irStatementGenerator: IrStatementGenerator -) : IrGenerator { - override val context: IrGeneratorContext get() = irStatementGenerator.context +class IrCallGenerator(val irStatementGenerator: IrStatementGenerator) : IrGenerator { + override val context: IrGeneratorContext get() = + irStatementGenerator.context + + private val temporaryVariableFactory: IrTemporaryVariableFactory get() = + irStatementGenerator.temporaryVariableFactory private val expressionValues = HashMap() private val receiverValues = HashMap() private val valueArgumentValues = HashMap() - fun createTemporary(ktExpression: KtExpression, irExpression: IrExpression): IrVariable { - val irTmpVar = irStatementGenerator.declarationFactory.createTemporaryVariable(irExpression) + fun createTemporary(ktExpression: KtExpression, irExpression: IrExpression, nameHint: String? = null): IrVariable { + val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, nameHint) putValue(ktExpression, IrTemporaryVariableValue(irTmpVar)) return irTmpVar } @@ -150,7 +152,7 @@ class IrCallGenerator( val temporariesForValueArguments = HashMap>() for (valueArgument in valueArgumentsInEvaluationOrder) { val irArgument = generateValueArgument(valueArgument, valueArgumentsToValueParameters[valueArgument]!!) ?: continue - val irTemporary = irStatementGenerator.declarationFactory.createTemporaryVariable(irArgument) + val irTemporary = temporaryVariableFactory.createTemporaryVariable(irArgument) temporariesForValueArguments[valueArgument] = Pair(irTemporary.descriptor, irArgument) irBlock.addStatement(irTemporary) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationFactory.kt deleted file mode 100644 index 4483d57a399..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationFactory.kt +++ /dev/null @@ -1,88 +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.psi2ir.generators - -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor -import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl -import org.jetbrains.kotlin.ir.expressions.IrBody -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFunction -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtPropertyAccessor -import org.jetbrains.kotlin.psi.psiUtil.endOffset -import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.types.KotlinType - -abstract class IrDeclarationFactoryBase { - fun createFunction(ktFunction: KtFunction, functionDescriptor: FunctionDescriptor, body: IrBody): IrFunction = - IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset, - IrDeclarationOriginKind.DEFINED, functionDescriptor, body) - - fun createSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor, valueInitializer: IrBody?): IrSimpleProperty = - IrSimplePropertyImpl(ktProperty.startOffset, ktProperty.endOffset, - IrDeclarationOriginKind.DEFINED, propertyDescriptor, valueInitializer) - - fun createPropertyGetter( - ktPropertyAccessor: KtPropertyAccessor, - irProperty: IrProperty, - getterDescriptor: PropertyGetterDescriptor, - getterBody: IrBody - ): IrPropertyGetter = - IrPropertyGetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset, - IrDeclarationOriginKind.DEFINED, getterDescriptor, getterBody) - .apply { irProperty.getter = this } - - fun createPropertySetter( - ktPropertyAccessor: KtPropertyAccessor, - irProperty: IrProperty, - setterDescriptor: PropertySetterDescriptor, - setterBody: IrBody - ) : IrPropertySetter = - IrPropertySetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset, - IrDeclarationOriginKind.DEFINED, setterDescriptor, setterBody) - .apply { irProperty.setter = this } -} - -class IrDeclarationFactory() : IrDeclarationFactoryBase() - -class IrLocalDeclarationsFactory(val scopeOwner: DeclarationDescriptor) : IrDeclarationFactoryBase() { - private var lastTemporaryIndex = 0 - private fun nextTemporaryIndex() = lastTemporaryIndex++ - - fun createDescriptorForTemporaryVariable(type: KotlinType): IrTemporaryVariableDescriptor = - IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier("tmp${nextTemporaryIndex()}"), type) - - fun createTemporaryVariable(irExpression: IrExpression): IrVariable = - IrVariableImpl(irExpression.startOffset, irExpression.endOffset, IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE, - createDescriptorForTemporaryVariable( - irExpression.type - ?: throw AssertionError("No type for $irExpression") - ), - irExpression) - - fun createLocalVariable(ktElement: KtElement, descriptor: VariableDescriptor): IrVariable = - IrVariableImpl(ktElement.startOffset, ktElement.endOffset, IrDeclarationOriginKind.DEFINED, - descriptor) - - fun createLocalVariable(ktElement: KtElement, descriptor: VariableDescriptor, initializer: IrExpression): IrVariable = - IrVariableImpl(ktElement.startOffset, ktElement.endOffset, IrDeclarationOriginKind.DEFINED, - descriptor, initializer) -} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt index d7bde6eeee6..3a1aef75301 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrDeclarationGenerator.kt @@ -17,76 +17,122 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrDummyDeclaration +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi2ir.toExpectedType import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.addToStdlib.singletonList -interface IrDeclarationGenerator : IrGenerator - -abstract class IrDeclarationGeneratorBase( - override val context: IrGeneratorContext, - val declarationFactory: IrDeclarationFactoryBase -) : IrDeclarationGenerator { - protected abstract fun D.register(): D - +class IrDeclarationGenerator(override val context: IrGeneratorContext) : IrGenerator { fun generateAnnotationEntries(annotationEntries: List) { // TODO create IrAnnotation's for each KtAnnotationEntry } - fun generateMemberDeclaration(ktDeclaration: KtDeclaration) { - // TODO visitor? - when (ktDeclaration) { - is KtNamedFunction -> generateFunctionDeclaration(ktDeclaration) - is KtProperty -> generatePropertyDeclaration(ktDeclaration) - is KtClassOrObject -> generateClassOrObjectDeclaration(ktDeclaration) - is KtTypeAlias -> generateTypeAliasDeclaration(ktDeclaration) - } - } + fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration = + when (ktDeclaration) { + is KtNamedFunction -> + generateFunctionDeclaration(ktDeclaration) + is KtProperty -> + generatePropertyDeclaration(ktDeclaration) + is KtClassOrObject -> + generateClassOrObjectDeclaration(ktDeclaration) + is KtTypeAlias -> + generateTypeAliasDeclaration(ktDeclaration) + else -> + IrDummyDeclaration( + ktDeclaration.startOffset, ktDeclaration.endOffset, + getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration) + ) + } - private fun generateClassOrObjectDeclaration(ktDeclaration: KtClassOrObject) { - IrDummyDeclaration( - ktDeclaration.startOffset, ktDeclaration.endOffset, - getOrFail(BindingContext.CLASS, ktDeclaration) - ).register() - } + fun generateClassOrObjectDeclaration(ktDeclaration: KtClassOrObject): IrDeclaration = + IrDummyDeclaration( + ktDeclaration.startOffset, ktDeclaration.endOffset, + getOrFail(BindingContext.CLASS, ktDeclaration) + ) - private fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias) { - IrDummyDeclaration( - ktDeclaration.startOffset, ktDeclaration.endOffset, - getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration) - ).register() - } + fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration = + IrDummyDeclaration( + ktDeclaration.startOffset, ktDeclaration.endOffset, + getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration) + ) - fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) { + fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction): IrFunction { val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) val body = generateFunctionBody(functionDescriptor, ktNamedFunction.bodyExpression ?: TODO("function without body expression")) - declarationFactory.createFunction(ktNamedFunction, functionDescriptor, body).register() + return createFunction(ktNamedFunction, functionDescriptor, body) } - fun generatePropertyDeclaration(ktProperty: KtProperty) { + fun generateLocalVariable(scopeOwner: DeclarationDescriptor, ktProperty: KtProperty): IrVariable { + if (ktProperty.delegateExpression != null) TODO("Local delegated property") + + val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) + + val irLocalVariable = IrVariableImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOriginKind.DEFINED, variableDescriptor) + + irLocalVariable.initializer = ktProperty.initializer?.let { + generateExpressionWithinContext(it, scopeOwner) + } + + return irLocalVariable + } + + fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty { val propertyDescriptor = getPropertyDescriptor(ktProperty) if (ktProperty.hasDelegate()) TODO("handle delegated property") val initializer = ktProperty.initializer?.let { generateInitializerBody(propertyDescriptor, it) } - val irProperty = declarationFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer).register() + val irProperty = createSimpleProperty(ktProperty, propertyDescriptor, initializer) + ktProperty.getter?.let { ktGetter -> val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?") val getterBody = generateFunctionBody(getterDescriptor, ktGetter.bodyExpression ?: TODO("default getter")) - declarationFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody).register() + createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody) } + ktProperty.setter?.let { ktSetter -> val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?") val setterBody = generateFunctionBody(setterDescriptor, ktSetter.bodyExpression ?: TODO("default setter")) - declarationFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody).register() + createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody) } + + return irProperty } + fun createFunction(ktFunction: KtFunction, functionDescriptor: FunctionDescriptor, body: IrBody): IrFunction = + IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset, + IrDeclarationOriginKind.DEFINED, functionDescriptor, body) + + fun createSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor, valueInitializer: IrBody?): IrSimpleProperty = + IrSimplePropertyImpl(ktProperty.startOffset, ktProperty.endOffset, + IrDeclarationOriginKind.DEFINED, propertyDescriptor, valueInitializer) + + fun createPropertyGetter( + ktPropertyAccessor: KtPropertyAccessor, + irProperty: IrProperty, + getterDescriptor: PropertyGetterDescriptor, + getterBody: IrBody + ): IrPropertyGetter = + IrPropertyGetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset, + IrDeclarationOriginKind.DEFINED, getterDescriptor, getterBody) + .apply { irProperty.getter = this } + + fun createPropertySetter( + ktPropertyAccessor: KtPropertyAccessor, + irProperty: IrProperty, + setterDescriptor: PropertySetterDescriptor, + setterBody: IrBody + ) : IrPropertySetter = + IrPropertySetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset, + IrDeclarationOriginKind.DEFINED, setterDescriptor, setterBody) + .apply { irProperty.setter = this } + private fun getPropertyDescriptor(ktProperty: KtProperty): PropertyDescriptor { val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?") @@ -94,7 +140,7 @@ abstract class IrDeclarationGeneratorBase( } private fun generateExpressionWithinContext(ktExpression: KtExpression, scopeOwner: DeclarationDescriptor): IrExpression = - IrStatementGenerator(context, scopeOwner, IrLocalDeclarationsFactory(scopeOwner)) + IrStatementGenerator(context, scopeOwner, IrTemporaryVariableFactory(scopeOwner)) .generateExpression(ktExpression) .toExpectedType(getExpectedTypeForLastInferredCall(ktExpression)) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrFileGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrFileGenerator.kt deleted file mode 100644 index 0031b340956..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrFileGenerator.kt +++ /dev/null @@ -1,40 +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.psi2ir.generators - -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrFileImpl -import org.jetbrains.kotlin.psi.KtFile - -class IrFileGenerator( - private val ktFile: KtFile, - private val irFile: IrFile, - context: IrGeneratorContext, - declarationFactory: IrDeclarationFactory -) : IrDeclarationGeneratorBase(context, declarationFactory) { - override fun D.register(): D = - apply { irFile.addDeclaration(this) } - - fun generateFileContent() { - generateAnnotationEntries(ktFile.annotationEntries) - - for (topLevelDeclaration in ktFile.declarations) { - generateMemberDeclaration(topLevelDeclaration) - } - } -} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt index de130152a88..0410e1647e9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrGeneratorContext.kt @@ -24,13 +24,11 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager import org.jetbrains.kotlin.resolve.BindingContext class IrGeneratorContext( - val inputFiles: List, - val irModule: IrModuleImpl, + val moduleDescriptor: ModuleDescriptor, val bindingContext: BindingContext ) { - val moduleDescriptor: ModuleDescriptor get() = irModule.descriptor - val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns - val sourceManager = PsiSourceManager() + + val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt index 65867e52474..9b5bed71396 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrModuleGenerator.kt @@ -16,21 +16,38 @@ package org.jetbrains.kotlin.psi2ir.generators -import org.jetbrains.kotlin.ir.declarations.IrFileImpl +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext -class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator { - fun generateModuleContent() { - for (ktFile in context.inputFiles) { - val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) +class IrModuleGenerator(override val context: IrGeneratorContext) : IrGenerator { + fun generateModule(ktFiles: List): IrModule { + val irDeclarationGenerator = IrDeclarationGenerator(context) + + val irModule = IrModuleImpl(context.moduleDescriptor) + for (ktFile in ktFiles) { val fileEntry = context.sourceManager.getOrCreateFileEntry(ktFile) + val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) val fileName = fileEntry.getRecognizableName() val irFile = IrFileImpl(fileEntry, fileName, packageFragmentDescriptor) context.sourceManager.putFileEntry(irFile, fileEntry) - context.irModule.addFile(irFile) - val irFileElementFactory = IrDeclarationFactory() - val generator = IrFileGenerator(ktFile, irFile, context, irFileElementFactory) - generator.generateFileContent() + + for (ktDeclaration in ktFile.declarations) { + val irDeclaration = irDeclarationGenerator.generateMemberDeclaration(ktDeclaration) + irFile.addDeclaration(irDeclaration) + if (irDeclaration is IrProperty) { + irDeclaration.getter?.let { + irFile.addDeclaration(it) + } + irDeclaration.setter?.let { + irFile.addDeclaration(it) + } + } + } + + irModule.addFile(irFile) } + return irModule } + } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt index 62c990b21e6..3e8040e6283 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrStatementGenerator.kt @@ -19,6 +19,8 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.assertCast +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginKind +import org.jetbrains.kotlin.ir.declarations.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -38,7 +40,7 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils class IrStatementGenerator( override val context: IrGeneratorContext, val scopeOwner: DeclarationDescriptor, - val declarationFactory: IrLocalDeclarationsFactory + val temporaryVariableFactory: IrTemporaryVariableFactory ) : KtVisitor(), IrGenerator { fun generateExpression(ktExpression: KtExpression): IrExpression = @@ -58,7 +60,7 @@ class IrStatementGenerator( val variableDescriptor = getOrFail(BindingContext.VARIABLE, property) - val irLocalVariable = declarationFactory.createLocalVariable(property, variableDescriptor) + val irLocalVariable = IrVariableImpl(property.startOffset, property.endOffset, IrDeclarationOriginKind.DEFINED, variableDescriptor) irLocalVariable.initializer = property.initializer?.let { it.genExpr().toExpectedType(variableDescriptor.type) } @@ -72,7 +74,7 @@ class IrStatementGenerator( val irBlock = IrBlockExpressionImpl(multiDeclaration.startOffset, multiDeclaration.endOffset, null, hasResult = false, isDesugared = true) val ktInitializer = multiDeclaration.initializer!! - val irTmpInitializer = declarationFactory.createTemporaryVariable(ktInitializer.genExpr()) + val irTmpInitializer = temporaryVariableFactory.createTemporaryVariable(ktInitializer.genExpr()) irBlock.addStatement(irTmpInitializer) val irCallGenerator = IrCallGenerator(this) @@ -82,7 +84,8 @@ class IrStatementGenerator( val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry) val componentVariable = getOrFail(BindingContext.VARIABLE, ktEntry) val irComponentCall = irCallGenerator.generateCall(ktEntry, componentResolvedCall, IrOperator.COMPONENT_N.withIndex(index + 1)) - val irComponentVar = declarationFactory.createLocalVariable(ktEntry, componentVariable, irComponentCall) + val irComponentVar = IrVariableImpl(ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOriginKind.DEFINED, + componentVariable, irComponentCall) irBlock.addStatement(irComponentVar) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrTemporaryVariableFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrTemporaryVariableFactory.kt new file mode 100644 index 00000000000..5420f7552de --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrTemporaryVariableFactory.kt @@ -0,0 +1,51 @@ +/* + * 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.generators + +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginKind +import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.declarations.IrVariableImpl +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.KotlinType + +class IrTemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) { + private var lastTemporaryIndex = 0 + private fun nextTemporaryIndex() = lastTemporaryIndex++ + + private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null): IrTemporaryVariableDescriptor = + IrTemporaryVariableDescriptorImpl( + scopeOwner, + Name.identifier( + if (nameHint != null) + "tmp${nextTemporaryIndex()}\$$nameHint" + else + "tmp${nextTemporaryIndex()}" + ), + type) + + fun createTemporaryVariable(irExpression: IrExpression, nameHint: String? = null): IrVariable = + IrVariableImpl(irExpression.startOffset, irExpression.endOffset, IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE, + createDescriptorForTemporaryVariable( + irExpression.type ?: throw AssertionError("No type for $irExpression"), + nameHint + ), + irExpression) +}