[JS IR BE] basic compiler
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
class JsIrBackendContext
|
||||
@@ -1,16 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* 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
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleTransformer
|
||||
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
|
||||
// Dummy compile function to work on the test infrastructure
|
||||
fun compile(
|
||||
files: List<KtFile>
|
||||
project: Project,
|
||||
files: List<KtFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
export: FqName
|
||||
): String {
|
||||
if (files.none { it.name == "nestedPackage.kt" }) return ""
|
||||
return "function box() { return \"OK\"; }"
|
||||
}
|
||||
val analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, project, configuration, emptyList(), emptyList())
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext)
|
||||
|
||||
val moduleFragment = Psi2IrTranslator().generateModule(analysisResult.moduleDescriptor, files, analysisResult.bindingContext)
|
||||
|
||||
val program = moduleFragment.accept(IrModuleTransformer(), null)
|
||||
|
||||
return program.toString()
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
|
||||
class IrDeclarationToJsTransformer : IrElementToJsNodeTransformer<JsStatement, Nothing?> {
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: Nothing?): JsStatement {
|
||||
return JsExpressionStatement(transformIrFunctionToJsFunction(declaration))
|
||||
}
|
||||
|
||||
private fun transformIrFunctionToJsFunction(declaration: IrSimpleFunction): JsFunction {
|
||||
val funName = declaration.name.asString()
|
||||
val body = declaration.body?.accept(IrElementToJsStatementTransformer(), null) as? JsBlock ?: JsBlock()
|
||||
val function = JsFunction(JsFunctionScope(JsDynamicScope, "scope for $funName"), body, "function $funName")
|
||||
|
||||
function.name = JsDynamicScope.declareName(funName)
|
||||
|
||||
fun JsFunction.addParameter(parameterName: String) {
|
||||
val parameter = function.scope.declareName(parameterName)
|
||||
parameters.add(JsParameter(parameter))
|
||||
}
|
||||
|
||||
declaration.extensionReceiverParameter?.let { function.addParameter("\$receiver") }
|
||||
declaration.valueParameters.forEach {
|
||||
function.addParameter(it.name.asString())
|
||||
}
|
||||
|
||||
return function
|
||||
}
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsStringLiteral
|
||||
|
||||
class IrElementToJsExpressionTransformer : IrElementToJsNodeTransformer<JsExpression, Nothing?> {
|
||||
override fun <T> visitConst(expression: IrConst<T>, data: Nothing?): JsExpression {
|
||||
return JsStringLiteral(expression.value.toString())
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.backend.js.TODO
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeAlias
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsEmpty
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNode
|
||||
|
||||
interface IrElementToJsNodeTransformer<out R : JsNode, in D> : IrElementVisitor<R, D> {
|
||||
override fun visitElement(element: IrElement, data: D): R {
|
||||
TODO(element)
|
||||
}
|
||||
|
||||
override fun visitTypeAlias(declaration: IrTypeAlias, data: D): R {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return JsEmpty as R
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBlock
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpressionStatement
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsReturn
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsStatement
|
||||
|
||||
class IrElementToJsStatementTransformer : IrElementToJsNodeTransformer<JsStatement, Nothing?> {
|
||||
override fun visitBlockBody(body: IrBlockBody, data: Nothing?): JsStatement {
|
||||
return JsBlock(body.statements.map { it.accept(this, data) })
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: IrExpression, data: Nothing?): JsStatement {
|
||||
return JsExpressionStatement(expression.accept(IrElementToJsExpressionTransformer(), data))
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: Nothing?): JsStatement {
|
||||
return JsReturn(expression.value.accept(IrElementToJsExpressionTransformer(), null))
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBlock
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsStatement
|
||||
|
||||
class IrFileTransformer : IrElementToJsNodeTransformer<JsStatement, Nothing?> {
|
||||
override fun visitFile(declaration: IrFile, data: Nothing?): JsStatement {
|
||||
val block = JsBlock()
|
||||
|
||||
declaration.declarations.forEach {
|
||||
block.statements.add(it.accept(IrDeclarationToJsTransformer(), null))
|
||||
}
|
||||
|
||||
return block
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNode
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
||||
|
||||
class IrModuleTransformer : IrElementToJsNodeTransformer<JsNode, Nothing?> {
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?): JsNode {
|
||||
val program = JsProgram()
|
||||
|
||||
declaration.files.forEach {
|
||||
program.globalBlock.statements.add(it.accept(IrFileTransformer(), null))
|
||||
}
|
||||
|
||||
return program
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
|
||||
fun TODO(element: IrElement): Nothing = TODO(element::class.java.simpleName + " is not supported yet here")
|
||||
@@ -8,5 +8,6 @@ package org.jetbrains.kotlin.test
|
||||
import java.io.File
|
||||
|
||||
val JS_IR_BACKEND_TEST_WHITELIST = listOf(
|
||||
"js/js.translator/testData/box/package/nestedPackage.kt"
|
||||
"js/js.translator/testData/box/package/nestedPackage.kt",
|
||||
"js/js.translator/testData/box/package/deeplyNestedPackage.kt"
|
||||
).map { File(it) }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.backend.js.compile
|
||||
import org.jetbrains.kotlin.js.config.JsConfig
|
||||
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||
import org.jetbrains.kotlin.js.facade.TranslationUnit
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
|
||||
abstract class BasicIrBoxTest(
|
||||
@@ -33,7 +34,14 @@ abstract class BasicIrBoxTest(
|
||||
testPackage: String?,
|
||||
testFunction: String
|
||||
) {
|
||||
val code = compile(units.map { (it as TranslationUnit.SourceFile).file })
|
||||
val code = compile(
|
||||
config.project,
|
||||
units.map { (it as TranslationUnit.SourceFile).file }
|
||||
// TODO: temporary ignore _commonFiles/asserts.kt since it depends on stdlib but we don't have any library support in JS IR BE yet
|
||||
// and probably it will be better to avoid using stdlib in testData as much as possible.
|
||||
.filter { !it.virtualFilePath.endsWith("js/js.translator/testData/_commonFiles/asserts.kt") },
|
||||
config.configuration,
|
||||
FqName((testPackage?.let { it + "." } ?: "") + testFunction))
|
||||
|
||||
outputFile.parentFile.mkdirs()
|
||||
outputFile.writeText(code)
|
||||
|
||||
+1
-7
@@ -13731,13 +13731,7 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
@TestMetadata("deeplyNestedPackage.kt")
|
||||
public void testDeeplyNestedPackage() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/package/deeplyNestedPackage.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive or add it to white list for that.");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("deeplyNestedPackageFunctionCalled.kt")
|
||||
|
||||
Reference in New Issue
Block a user