[JS IR BE] Arrays, varargs

This commit is contained in:
Anton Bannykh
2018-09-12 14:31:22 +03:00
parent e24f68c357
commit 2e709a81fa
470 changed files with 761 additions and 585 deletions
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.findSingleFunction
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) {
private val externalPackageFragmentSymbol = IrExternalPackageFragmentSymbolImpl(context.internalPackageFragmentDescriptor)
@@ -166,6 +168,52 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
val returnIfSuspended = getInternalFunction("returnIfSuspended")
val getContinuation = getInternalFunction("getContinuation")
// Arrays:
val array = context.symbolTable.referenceClass(irBuiltIns.builtIns.array)
val primitiveArrays = PrimitiveType.values().associate { context.symbolTable.referenceClass(irBuiltIns.builtIns.getPrimitiveArrayClassDescriptor(it)) to it }
val jsArray = getInternalFunction("arrayWithFun")
val jsFillArray = getInternalFunction("fillArrayFun")
val jsArrayLength = unOp("jsArrayLength")
val jsArrayGet = binOp("jsArrayGet")
val jsArraySet = tripleOp("jsArraySet")
val jsArrayIteratorFunction = getInternalFunction("arrayIterator")
val jsPrimitiveArrayIteratorFunctions =
PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCase()}ArrayIterator") }
val arrayLiteral = unOp("arrayLiteral").symbol
val primitiveToTypedArrayMap = EnumMap(mapOf(
PrimitiveType.BYTE to "Int8",
PrimitiveType.SHORT to "Int16",
PrimitiveType.INT to "Int32",
PrimitiveType.FLOAT to "Float32",
PrimitiveType.DOUBLE to "Float64"))
val primitiveToSizeConstructor =
PrimitiveType.values().associate { type ->
type to (primitiveToTypedArrayMap[type]?.let {
unOp("${it.toLowerCase()}Array").symbol
} ?: getInternalFunction("${type.typeName.asString().toLowerCase()}Array"))
}
val primitiveToLiteralConstructor =
PrimitiveType.values().associate { type ->
type to (primitiveToTypedArrayMap[type]?.let {
unOp("${it.toLowerCase()}ArrayOf").symbol
} ?: getInternalFunction("${type.typeName.asString().toLowerCase()}ArrayOf"))
}
val arrayConcat = getInternalWithoutPackage("arrayConcat")
val primitiveArrayConcat = getInternalWithoutPackage("primitiveArrayConcat")
val jsArraySlice = unOp("slice")
// Helpers:
private fun getInternalFunction(name: String) =
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.ir.backend.js.lower.*
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.SuspendFunctionsLowering
@@ -21,9 +22,19 @@ import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineFunctionsWith
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ReturnableBlockLowering
import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.name.FqName
@@ -31,17 +42,17 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
data class Result(val moduleDescriptor: ModuleDescriptor, val generatedCode: String)
data class Result(val moduleDescriptor: ModuleDescriptor, val generatedCode: String, val moduleFragment: IrModuleFragment)
fun compile(
project: Project,
files: List<KtFile>,
configuration: CompilerConfiguration,
export: FqName? = null,
dependencies: List<ModuleDescriptor> = listOf()
dependencies: List<Result> = listOf()
): Result {
val analysisResult =
TopDownAnalyzerFacadeForJS.analyzeFiles(files, project, configuration, dependencies.filterIsInstance(), emptyList())
TopDownAnalyzerFacadeForJS.analyzeFiles(files, project, configuration, dependencies.mapNotNull { it.moduleDescriptor as? ModuleDescriptorImpl }, emptyList())
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
@@ -50,6 +61,10 @@ fun compile(
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext)
val irDependencyModules = dependencies.map { it.moduleFragment.deepCopyWithSymbols() }
irDependencyModules.forEach { psi2IrContext.symbolTable.loadModule(it)}
val moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files)
val context = JsIrBackendContext(
@@ -70,21 +85,24 @@ fun compile(
MoveExternalDeclarationsToSeparatePlace().lower(moduleFragment.files)
moduleFragment.files.forEach(CoroutineIntrinsicLowering(context)::lower)
moduleFragment.files.forEach { ArrayInlineConstructorLowering(context).lower(it) }
val moduleFragmentCopy = moduleFragment.deepCopyWithSymbols()
context.performInlining(moduleFragment)
context.lower(moduleFragment)
context.lower(moduleFragment, irDependencyModules)
val program = moduleFragment.accept(IrModuleToJsTransformer(context), null)
return Result(analysisResult.moduleDescriptor, program.toString())
return Result(analysisResult.moduleDescriptor, program.toString(), moduleFragmentCopy)
}
private fun JsIrBackendContext.performInlining(moduleFragment: IrModuleFragment) {
FunctionInlining(this).inline(moduleFragment)
moduleFragment.replaceUnboundSymbols(this)
moduleFragment.patchDeclarationParents()
@@ -93,7 +111,8 @@ private fun JsIrBackendContext.performInlining(moduleFragment: IrModuleFragment)
}
}
private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment) {
private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment, dependencies: List<IrModuleFragment>) {
moduleFragment.files.forEach(VarargLowering(this)::lower)
moduleFragment.files.forEach(LateinitLowering(this, true)::lower)
moduleFragment.files.forEach(DefaultArgumentStubGenerator(this)::runOnFilePostfix)
moduleFragment.files.forEach(DefaultParameterInjector(this)::runOnFilePostfix)
@@ -114,7 +133,7 @@ private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment) {
moduleFragment.files.forEach(TypeOperatorLowering(this)::lower)
moduleFragment.files.forEach(BlockDecomposerLowering(this)::runOnFilePostfix)
val sctor = SecondaryCtorLowering(this)
moduleFragment.files.forEach(sctor.getConstructorProcessorLowering())
(moduleFragment.files + dependencies.flatMap { it.files }).forEach(sctor.getConstructorProcessorLowering())
moduleFragment.files.forEach(sctor.getConstructorRedirectorLowering())
val clble = CallableReferenceLowering(this)
moduleFragment.files.forEach(clble.getReferenceCollector())
@@ -0,0 +1,73 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
// Replace array inline constructors with stdlib function invocations
// Should be performed before inliner
class ArrayInlineConstructorLowering(val context: JsIrBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
irFile.transformChildrenVoid(ArrayConstructorTransformer(context))
}
}
private class ArrayConstructorTransformer(
val context: JsIrBackendContext
) : IrElementTransformerVoid() {
private val primitiveArrayInlineToSizeConstructorMap = context.intrinsics.primitiveArrays.keys.associate {
it.inlineConstructor to it.sizeConstructor
}
override fun visitCall(expression: IrCall): IrExpression {
expression.transformChildrenVoid(this)
if (expression.symbol == context.intrinsics.array.inlineConstructor) {
return irCall(expression, context.intrinsics.jsArray)
} else {
primitiveArrayInlineToSizeConstructorMap[expression.symbol]?.let { sizeConstructor ->
return IrCallImpl(
expression.startOffset,
expression.endOffset,
expression.type,
context.intrinsics.jsFillArray
).apply {
putValueArgument(0, IrCallImpl(
expression.startOffset,
expression.endOffset,
expression.type,
sizeConstructor
).apply {
putValueArgument(0, expression.getValueArgument(0))
})
putValueArgument(1, expression.getValueArgument(1))
}
}
}
return expression
}
}
// TODO it.isInline doesn't work =(
private val IrClassSymbol.inlineConstructor
get() = owner.declarations.filterIsInstance<IrConstructor>().first { it.valueParameters.size == 2 }.symbol
private val IrClassSymbol.sizeConstructor
get() = owner.declarations.filterIsInstance<IrConstructor>().first { it.valueParameters.size == 1 }.symbol
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOfClass
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.ir.irCall
@@ -19,8 +20,10 @@ 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.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
@@ -137,6 +140,27 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
add(irBuiltIns.lessOrEqualFunByOperandType, intrinsics.jsLtEq)
add(irBuiltIns.greaterFunByOperandType, intrinsics.jsGt)
add(irBuiltIns.greaterOrEqualFunByOperandType, intrinsics.jsGtEq)
// Arrays
add(context.intrinsics.array.sizeProperty, context.intrinsics.jsArrayLength, true)
add(context.intrinsics.array.getFunction, context.intrinsics.jsArrayGet, true)
add(context.intrinsics.array.setFunction, context.intrinsics.jsArraySet, true)
add(context.intrinsics.array.iterator, context.intrinsics.jsArrayIteratorFunction.owner, true)
for ((key, elementType) in context.intrinsics.primitiveArrays) {
add(key.sizeProperty, context.intrinsics.jsArrayLength, true)
add(key.getFunction, context.intrinsics.jsArrayGet, true)
add(key.setFunction, context.intrinsics.jsArraySet, true)
add(key.iterator, context.intrinsics.jsPrimitiveArrayIteratorFunctions[elementType]!!.owner, true)
// TODO irCall?
add(key.sizeConstructor) { call ->
IrCallImpl(call.startOffset, call.endOffset, call.type, context.intrinsics.primitiveToSizeConstructor[elementType]!!).apply {
putValueArgument(0, call.getValueArgument(0))
}
}
}
add(context.irBuiltIns.stringClass.lengthProperty, context.intrinsics.jsArrayLength, true)
}
memberToTransformer.run {
@@ -278,6 +302,32 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
put(IrStatementOrigin.PREFIX_DECR, context.intrinsics.jsPrefixDec)
put(IrStatementOrigin.POSTFIX_INCR, context.intrinsics.jsPostfixInc)
put(IrStatementOrigin.POSTFIX_DECR, context.intrinsics.jsPostfixDec)
put(IrStatementOrigin.GET_ARRAY_ELEMENT, context.intrinsics.jsArrayGet)
}
}
private fun lowerLongConst(value: Long, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET): IrExpression {
val high = (value shr 32).toInt()
val low = value.toInt()
return IrCallImpl(
startOffset,
endOffset,
irBuiltIns.longType,
context.intrinsics.longConstructor
).apply {
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, low))
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, high))
}
}
private fun lowerCharConst(value: Char, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET): IrExpression {
return IrCallImpl(
startOffset,
endOffset,
irBuiltIns.charType,
context.intrinsics.charConstructor
).apply {
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, value.toInt()))
}
}
@@ -287,27 +337,9 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
// TODO should this be a separate lowering?
override fun <T> visitConst(expression: IrConst<T>): IrExpression {
if (expression.kind is IrConstKind.Long) {
val value = IrConstKind.Long.valueOf(expression)
val high = (value shr 32).toInt()
val low = value.toInt()
return IrCallImpl(
expression.startOffset,
expression.endOffset,
irBuiltIns.longType,
context.intrinsics.longConstructor
).apply {
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, low))
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, high))
}
return lowerLongConst(IrConstKind.Long.valueOf(expression), expression.startOffset, expression.endOffset)
} else if (expression.kind is IrConstKind.Char) {
return IrCallImpl(
expression.startOffset,
expression.endOffset,
irBuiltIns.charType,
context.intrinsics.charConstructor
).apply {
putValueArgument(0, JsIrBuilder.buildInt(context.irBuiltIns.intType, IrConstKind.Char.valueOf(expression).toInt()))
}
return lowerCharConst(IrConstKind.Char.valueOf(expression), expression.startOffset, expression.endOffset)
}
return super.visitConst(expression)
}
@@ -434,9 +466,10 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
private fun withLongCoercion(intrinsic: IrSimpleFunction): (IrCall) -> IrExpression = { call ->
assert(call.valueArgumentsCount == 1)
val arg = call.getValueArgument(0)!!
val receiverType = call.dispatchReceiver!!.type
if (arg.type.isLong()) {
val receiverType = call.dispatchReceiver!!.type
when {
// Double OP Long => Double OP Long.toDouble()
receiverType.isDouble() -> {
@@ -475,7 +508,7 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
}
}
if (receiverType.isLong()) {
if (call.dispatchReceiver!!.type.isLong()) {
// LHS is Long => use as is
call
} else {
@@ -682,8 +715,8 @@ private fun SymbolToTransformer.add(from: IrFunctionSymbol, to: (IrCall) -> IrEx
put(from, to)
}
private fun SymbolToTransformer.add(from: IrFunctionSymbol, to: IrSimpleFunction) {
put(from, { call -> irCall(call, to.symbol) })
private fun SymbolToTransformer.add(from: IrFunctionSymbol, to: IrSimpleFunction, dispatchReceiverAsFirstArgument: Boolean = false) {
put(from, { call -> irCall(call, to.symbol, dispatchReceiverAsFirstArgument) })
}
private fun <K> MutableMap<K, (IrCall) -> IrExpression>.addWithPredicate(
@@ -717,3 +750,22 @@ private class SimpleMemberKey(val klass: IrType, val name: Name) {
return result
}
}
private val IrClassSymbol.sizeProperty
get() = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "size" }.getter!!.symbol
private val IrClassSymbol.getFunction
get() = owner.declarations.filterIsInstance<IrFunction>().first { it.name.asString() == "get" }.symbol
private val IrClassSymbol.setFunction
get() = owner.declarations.filterIsInstance<IrFunction>().first { it.name.asString() == "set" }.symbol
private val IrClassSymbol.iterator
get() = owner.declarations.filterIsInstance<IrFunction>().first { it.name.asString() == "iterator" }.symbol
private val IrClassSymbol.sizeConstructor
get() = owner.declarations.filterIsInstance<IrConstructor>().first { it.valueParameters.size == 1 }.symbol
private val IrClassSymbol.lengthProperty
get() = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "length" }.getter!!.symbol
@@ -0,0 +1,124 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
class VarargLowering(val context: JsIrBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
irFile.transformChildrenVoid(VarargTransformer(context))
}
}
private class VarargTransformer(
val context: JsIrBackendContext
) : IrElementTransformerVoid() {
private fun List<IrExpression>.toArrayLiteral(type: IrType, varargElementType: IrType): IrExpression {
val intrinsic = context.intrinsics.primitiveArrays[type.classifierOrNull]?.let { primitiveType ->
context.intrinsics.primitiveToLiteralConstructor[primitiveType]
} ?: context.intrinsics.arrayLiteral
val startOffset = firstOrNull()?.startOffset ?: UNDEFINED_OFFSET
val endOffset = lastOrNull()?.endOffset ?: UNDEFINED_OFFSET
val irVararg = IrVarargImpl(startOffset, endOffset, type, varargElementType, this)
return IrCallImpl(startOffset, endOffset, type, intrinsic).apply {
if (intrinsic.owner.typeParameters.isNotEmpty()) putTypeArgument(0, varargElementType)
putValueArgument(0, irVararg)
}
}
override fun visitVararg(expression: IrVararg): IrExpression {
expression.transformChildrenVoid(this)
val currentList = mutableListOf<IrExpression>()
val segments = mutableListOf<IrExpression>()
for (e in expression.elements) {
if (e is IrSpreadElement) {
if (!currentList.isEmpty()) {
segments.add(currentList.toArrayLiteral(expression.type, expression.varargElementType))
currentList.clear()
}
segments.add(e.expression)
} else {
// IrVarargElement is either IrSpreadElement or IrExpression
currentList.add(e as IrExpression)
}
}
if (!currentList.isEmpty()) {
segments.add(currentList.toArrayLiteral(expression.type, expression.varargElementType))
currentList.clear()
}
// empty vararg => empty array literal
if (segments.isEmpty()) {
return emptyList().toArrayLiteral(expression.type, expression.varargElementType)
}
// vararg with a single segment => no need to concatenate
if (segments.size == 1) {
return if (expression.elements.any { it is IrSpreadElement }) {
// Single spread operator => need to copy the array
IrCallImpl(
expression.startOffset,
expression.endOffset,
expression.type,
context.intrinsics.jsArraySlice.symbol
).apply {
putValueArgument(0, segments.first())
}
} else {
segments.first()
}
}
val arrayLiteral = segments.toArrayLiteral(IrSimpleTypeImpl(context.intrinsics.array, false, emptyList(), emptyList()), context.irBuiltIns.anyType)
val concatFun = if (expression.type.classifierOrNull in context.intrinsics.primitiveArrays.keys) {
context.intrinsics.primitiveArrayConcat
} else {
context.intrinsics.arrayConcat
}
return IrCallImpl(
expression.startOffset,
expression.endOffset,
expression.type,
concatFun
).apply {
putValueArgument(0, arrayLiteral)
}
}
override fun visitCall(expression: IrCall): IrExpression {
expression.transformChildrenVoid()
val size = expression.valueArgumentsCount
for (i in 0 until size) {
val argument = expression.getValueArgument(i)
val parameter = expression.symbol.owner.valueParameters[i]
if (argument == null && parameter.varargElementType != null) {
expression.putValueArgument(i, emptyList().toArrayLiteral(parameter.type, parameter.varargElementType!!))
}
}
return expression
}
}
@@ -68,6 +68,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
if (functionDeclaration == null) { // We failed to get the declaration.
val message = "Inliner failed to obtain function declaration: " +
functionDescriptor.fqNameSafe.toString()
getFunctionDeclaration(irCall)
context.reportWarning(message, currentFile, irCall) // Report warning.
return irCall
}
@@ -88,8 +89,10 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
val functionDescriptor = irCall.descriptor
val originalDescriptor = functionDescriptor.resolveFakeOverride().original
val functionDeclaration =
context.originalModuleIndex.functions[originalDescriptor] // ?: // If function is declared in the current module.
context.originalModuleIndex.functions[originalDescriptor] ?: context.symbolTable.referenceDeclaredFunction(originalDescriptor).owner
// ?: // If function is declared in the current module.
// TODO deserializer.deserializeInlineBody(originalDescriptor) // Function is declared in another module.
return functionDeclaration as IrFunction?
}
@@ -18,12 +18,13 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
class ModuleIndex(val module: IrModuleFragment) {
var currentFile: IrFile? = null
/**
* Contains all classes declared in [module]
*/
val classes: Map<ClassDescriptor, IrClass>
val classes = mutableMapOf<ClassDescriptor, IrClass>()
val enumEntries: Map<ClassDescriptor, IrEnumEntry>
val enumEntries = mutableMapOf<ClassDescriptor, IrEnumEntry>()
/**
* Contains all functions declared in [module]
@@ -32,9 +33,10 @@ class ModuleIndex(val module: IrModuleFragment) {
val declarationToFile = mutableMapOf<DeclarationDescriptor, String>()
init {
val map = mutableMapOf<ClassDescriptor, IrClass>()
enumEntries = mutableMapOf()
addModule(module)
}
fun addModule(module: IrModuleFragment) {
module.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
@@ -48,7 +50,7 @@ class ModuleIndex(val module: IrModuleFragment) {
override fun visitClass(declaration: IrClass) {
super.visitClass(declaration)
map[declaration.descriptor] = declaration
classes[declaration.descriptor] = declaration
}
override fun visitEnumEntry(declaration: IrEnumEntry) {
@@ -67,7 +69,5 @@ class ModuleIndex(val module: IrModuleFragment) {
declarationToFile[declaration.descriptor] = currentFile!!.name
}
})
classes = map
}
}
@@ -21,50 +21,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsExpression, JsGenerationContext> {
override fun visitVararg(expression: IrVararg, context: JsGenerationContext): JsExpression {
// TODO: perform the dark magic below in the separated lowering
if (expression.elements.size == 1) {
val element = expression.elements[0]
if (element is IrSpreadElement) {
// special case, invoke slice()
val expr = element.expression.accept(this, context)
return JsInvocation(JsNameRef(Namer.SLICE_FUNCTION, expr))
}
}
var arrayLiteralElements = mutableListOf<JsExpression>()
val concatArguments = mutableListOf<JsExpression>()
var qualifier: JsExpression? = null
expression.elements.forEach {
if (it is IrSpreadElement) {
val expr = it.expression.accept(this, context)
if (qualifier == null) {
if (arrayLiteralElements.isEmpty()) {
qualifier = JsNameRef(Namer.CONCAT_FUNCTION, expr)
} else {
val dispatch = JsArrayLiteral(arrayLiteralElements)
arrayLiteralElements = mutableListOf()
qualifier = JsNameRef(Namer.CONCAT_FUNCTION, dispatch)
concatArguments.add(expr)
}
} else {
if (arrayLiteralElements.isNotEmpty()) {
concatArguments.add(JsArrayLiteral(arrayLiteralElements))
arrayLiteralElements = mutableListOf()
}
concatArguments.add(expr)
}
} else {
arrayLiteralElements.add(it.accept(this, context))
}
}
return qualifier?.let {
if (arrayLiteralElements.isNotEmpty()) {
concatArguments.add(JsArrayLiteral(arrayLiteralElements))
}
return JsInvocation(it, concatArguments)
} ?: JsArrayLiteral(arrayLiteralElements)
assert(expression.elements.none { it is IrSpreadElement })
return JsArrayLiteral(expression.elements.map { it.accept(this, context) })
}
override fun visitExpressionBody(body: IrExpressionBody, context: JsGenerationContext): JsExpression =
@@ -136,6 +136,43 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
val continuation = context.continuation
JsInvocation(JsNameRef(getterName, continuation))
}
add(intrinsics.jsArrayLength) { call, context ->
val args = translateCallArguments(call, context)
JsNameRef("length", args[0])
}
add(intrinsics.jsArrayGet) { call, context ->
val args = translateCallArguments(call, context)
val array = args[0]
val index = args[1]
JsArrayAccess(array, index)
}
add(intrinsics.jsArraySet) { call, context ->
val args = translateCallArguments(call, context)
val array = args[0]
val index = args[1]
val value = args[2]
JsBinaryOperation(JsBinaryOperator.ASG, JsArrayAccess(array, index), value)
}
add(intrinsics.arrayLiteral) { call, context ->
translateCallArguments(call, context).single()
}
add(intrinsics.jsArraySlice) { call, context ->
JsInvocation(JsNameRef(Namer.SLICE_FUNCTION, translateCallArguments(call, context).single()))
}
for ((type, prefix) in intrinsics.primitiveToTypedArrayMap) {
add(intrinsics.primitiveToSizeConstructor[type]!!) { call, context ->
JsNew(JsNameRef("${prefix}Array"), translateCallArguments(call, context))
}
add(intrinsics.primitiveToLiteralConstructor[type]!!) { call, context ->
JsNew(JsNameRef("${prefix}Array"), translateCallArguments(call, context))
}
}
}
}
@@ -87,6 +87,18 @@ class IrSimpleBuiltinOperatorDescriptorImpl(
override fun getReturnType(): KotlinType = returnType
override fun getValueParameters(): List<ValueParameterDescriptor> = valueParameters
override fun equals(other: Any?): Boolean {
return this === other ||
other is IrSimpleBuiltinOperatorDescriptorImpl &&
name == other.name &&
valueParameters.map { it.type } == other.valueParameters.map { it.type } &&
containingDeclaration == other.containingDeclaration
}
override fun hashCode(): Int {
return (containingDeclaration.hashCode() * 31 + name.hashCode()) * 31 + valueParameters.map { it.type }.hashCode()
}
}
class IrBuiltinValueParameterDescriptorImpl(
@@ -118,4 +130,17 @@ class IrBuiltinValueParameterDescriptorImpl(
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
return visitor.visitValueParameterDescriptor(this, data)
}
override fun equals(other: Any?): Boolean {
return this === other ||
other is IrBuiltinValueParameterDescriptorImpl &&
name == other.name &&
index == other.index &&
type == other.type &&
containingDeclaration == other.containingDeclaration
}
override fun hashCode(): Int {
return (name.hashCode() * 31 + index) * 31 + type.hashCode()
}
}
@@ -45,4 +45,15 @@ class IrBuiltinsPackageFragmentDescriptorImpl(
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>) {
visitor.visitPackageFragmentDescriptor(this, null)
}
override fun equals(other: Any?): Boolean {
return this === other ||
other is IrBuiltinsPackageFragmentDescriptorImpl &&
fqName == other.fqName &&
containingModule == other.containingModule
}
override fun hashCode(): Int {
return containingModule.hashCode() * 31 + fqName.hashCode()
}
}
@@ -42,6 +42,13 @@ open class DeepCopyIrTreeWithSymbols(
private val typeRemapper: TypeRemapper
) : IrElementTransformerVoid() {
init {
// TODO refactor
(typeRemapper as? DeepCopyTypeRemapper)?.let {
it.deepCopy = this
}
}
private fun mapDeclarationOrigin(origin: IrDeclarationOrigin) = origin
private fun mapStatementOrigin(origin: IrStatementOrigin?) = origin
@@ -6,12 +6,20 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrTypeProjectionImpl
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
class DeepCopyTypeRemapper(
private val symbolRemapper: SymbolRemapper
) : TypeRemapper {
lateinit var deepCopy: DeepCopyIrTreeWithSymbols
override fun enterScope(irTypeParametersContainer: IrTypeParametersContainer) {
// TODO
}
@@ -20,6 +28,26 @@ class DeepCopyTypeRemapper(
// TODO
}
override fun remapType(type: IrType): IrType = type // TODO
// TODO This is a hack
override fun remapType(type: IrType): IrType {
if (type !is IrSimpleType) return type
val arguments = type.arguments.map {
if (it is IrTypeProjection) {
IrTypeProjectionImpl(this.remapType(it.type), it.variance)
} else {
it
}
}
val annotations = type.annotations.map { it.transform(deepCopy, null) as IrCall }
return IrSimpleTypeImpl(
type.originalKotlinType,
symbolRemapper.getReferencedClassifier(type.classifier),
type.hasQuestionMark,
arguments,
annotations)
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazySymbolTable
@@ -25,6 +26,9 @@ import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
interface ReferenceSymbolTable {
fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol
@@ -54,7 +58,7 @@ open class SymbolTable : ReferenceSymbolTable {
val unboundSymbols = linkedSetOf<S>()
abstract fun get(d: D): S?
protected abstract fun set(d: D, s: S)
abstract fun set(d: D, s: S)
inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
val existing = get(d)
@@ -92,6 +96,13 @@ open class SymbolTable : ReferenceSymbolTable {
override fun set(d: D, s: S) {
descriptorToSymbol[d] = s
}
fun copyTo(other: FlatSymbolTable<D, B, S>) {
for ((d, s) in descriptorToSymbol) {
other.descriptorToSymbol[d] = s
}
other.unboundSymbols.addAll(unboundSymbols)
}
}
private class ScopedSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>>
@@ -411,6 +422,51 @@ open class SymbolTable : ReferenceSymbolTable {
else ->
throw IllegalArgumentException("Unexpected value descriptor: $value")
}
fun loadModule(module: IrModuleFragment) {
module.acceptVoid(object: IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitClass(declaration: IrClass) {
// TODO should we check there are no conflicts?
classSymbolTable.descriptorToSymbol[declaration.descriptor] = declaration.symbol
super.visitClass(declaration)
}
override fun visitConstructor(declaration: IrConstructor) {
constructorSymbolTable.descriptorToSymbol[declaration.descriptor] = declaration.symbol
super.visitConstructor(declaration)
}
override fun visitEnumEntry(declaration: IrEnumEntry) {
enumEntrySymbolTable.descriptorToSymbol[declaration.descriptor] = declaration.symbol
super.visitEnumEntry(declaration)
}
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment) {
externalPackageFragmentTable.descriptorToSymbol[declaration.symbol.descriptor] = declaration.symbol
super.visitExternalPackageFragment(declaration)
}
override fun visitField(declaration: IrField) {
fieldSymbolTable.descriptorToSymbol[declaration.descriptor] = declaration.symbol
super.visitField(declaration)
}
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
simpleFunctionSymbolTable.descriptorToSymbol[declaration.descriptor] = declaration.symbol
super.visitSimpleFunction(declaration)
}
override fun visitTypeParameter(declaration: IrTypeParameter) {
// What about scoped type parameters?
globalTypeParameterSymbolTable.descriptorToSymbol[declaration.descriptor] = declaration.symbol
super.visitTypeParameter(declaration)
}
})
}
}
inline fun <T, D: DeclarationDescriptor> SymbolTable.withScope(owner: D, block: SymbolTable.(D) -> T): T {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Array<String>.get(index1: Int, index2: Int) = this[index1 + index2]
operator fun Array<String>.set(index1: Int, index2: Int, elem: String) {
this[index1 + index2] = elem
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Array<String>.get(index1: Int, index2: Int) = this[index1 + index2]
operator fun Array<String>.set(index1: Int, index2: Int, elem: String) {
this[index1 + index2] = elem
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
//test [], get and iterator calls
fun test(createIntNotLong: Boolean): String {
val a = if (createIntNotLong) IntArray(5) else LongArray(5)
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val s = IntArray(1)
s[0] = 5
@@ -1,5 +1,5 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR, JS_IR
// IGNORE_BACKEND: JVM_IR
inline class Z(val data: Int)
@@ -1,6 +1,6 @@
// !LANGUAGE: +InlineClasses
// WITH_UNSIGNED
// IGNORE_BACKEND: JVM_IR, JS_IR
// IGNORE_BACKEND: JVM_IR
inline class Data(val data: Array<UInt>)
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun ArrayList<String>.get(index1: Int, index2: Int) = this[index1 + index2]
operator fun ArrayList<String>.set(index1: Int, index2: Int, elem: String) {
this[index1 + index2] = elem
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun ArrayList<String>.get(index1: Int, index2: Int) = this[index1 + index2]
operator fun ArrayList<String>.set(index1: Int, index2: Int, elem: String) {
this[index1 + index2] = elem
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in BooleanArray(5)) {
if (x != false) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in ByteArray(5)) {
if (x != 0.toByte()) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in CharArray(5)) {
if (x != 0.toChar()) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in DoubleArray(5)) {
if (x != 0.toDouble()) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in FloatArray(5)) {
if (x != 0.toFloat()) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in IntArray(5)) {
if (x != 0) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in LongArray(5)) {
if (x != 0.toLong()) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
for (x in ShortArray(5)) {
if (x != 0.toShort()) return "Fail $x"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
abstract class Table<T>(
val content: Array<Array<T>>
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun test(y: Array<in Array<String>>) {
y[0] = kotlin.arrayOf("OK")
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val x : Array<Array<*>> = arrayOf(arrayOf(1))
val y : Array<in Array<String>> = x
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun box(): String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun box(): String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun box(): String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val x = Array<Int>(5, { it } ).iterator()
var i = 0
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = BooleanArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = ByteArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = ByteArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = CharArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = DoubleArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = FloatArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = IntArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = LongArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = LongArray(5)
val x = a.iterator()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = ShortArray(5)
val x = a.iterator()
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
var result = 0
fun <T> Iterator<T>.foreach(action: (T) -> Unit) {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
//KT-2997 Automatically cast error (Array)
fun foo(a: Any): Int {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box () : String {
val s = ArrayList<String>()
s.add("foo")
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun fill(dest : Array<in String>, v : String) {
dest[0] = v
}
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun String.get(vararg value: Any) : String {
return if (value[0] == 44 && value[1] == "example") "OK" else "fail"
}
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val array = intArrayOf(11, 12, 13)
val p = array.get(0)
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
package array_test
fun box() : String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun box() : String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun test(b: Boolean): String {
val a = if (b) IntArray(5) else LongArray(5)
if (a is IntArray) {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
val <T> Array<T>.length : Int get() = this.size
fun box() = if(arrayOfNulls<Int>(10).length == 10) "OK" else "fail"
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box() : String {
val data = Array<Array<Boolean>>(3) { Array<Boolean>(4, {false}) }
for(d in data) {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun IntArray.set(index: Long, elem: Int) { this[index.toInt()] = elem }
operator fun IntArray.get(index: Long) = this[index.toInt()]
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class C(val i: Int) {
operator fun component1() = i + 1
operator fun component2() = i + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class C(val i: Int) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class C(val i: Int) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class C(val i: Int) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class C(val i: Int) {
operator fun component1() = i + 1
operator fun component2() = i + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val array = arrayOf(doubleArrayOf(-1.0))
for (node in array) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val a = Array(2) { DoubleArray(3) }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val transform = transform(Array(1) { BooleanArray(1) })
if (!transform[0][0]) return "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Long.component1() = this + 1
operator fun Long.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
operator fun Long.component1() = this + 1
operator fun Long.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Long.component1() = this + 1
operator fun Long.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class M {
operator fun Long.component1() = this + 1
operator fun Long.component2() = this + 2
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
typealias ArrayS = Array<String>
fun testArray() {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class A() {
class B(val i: Int) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.*
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
interface ISized {
val size : Int
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
inline fun <T> put(
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
abstract class A {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: NATIVE
open class BaseStringList: ArrayList<String>() {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
interface A {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// KT-6042 java.lang.UnsupportedOperationException with ArrayList
// IGNORE_BACKEND: NATIVE
class A : ArrayList<String>()
@@ -1,5 +1,4 @@
// !LANGUAGE: +NewInference
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
class Foo
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// LANGUAGE_VERSION: 1.2
var result = ""
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
val Array<String>.firstElement: String get() = get(0)
fun box(): String {
@@ -1,5 +1,4 @@
// KT-25514 Support usage of function reference with vararg where function of array is expected in new inference
// IGNORE_BACKEND: JS_IR
fun foo(x: Int, vararg y: String): String = y[0]
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
interface A {
fun foo(): Any?
fun bar(): String
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
interface A {
fun foo(): Any?
}
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun <T> Array<T>.getLength(): Int {
return this.size
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
class Box<T>(val value: T)
fun <T> run(vararg z: T): Box<T> {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
fun box(): String {
val x: CharSequence = ""
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
class World() {
public val items: ArrayList<Item> = ArrayList<Item>()
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
public class StockMarketTableModel() {
public fun getColumnCount() : Int {

Some files were not shown because too many files have changed in this diff Show More