From d44da8e4d4068064be292e6589b657fe9575bef2 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Fri, 6 Mar 2015 15:05:04 +0300 Subject: [PATCH] JS: parse function from js file --- js/js.inliner/js.inliner.iml | 1 + .../kotlin/js/inline/FunctionReader.kt | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/js/js.inliner/js.inliner.iml b/js/js.inliner/js.inliner.iml index 76d6e58eb55..190520eb877 100644 --- a/js/js.inliner/js.inliner.iml +++ b/js/js.inliner/js.inliner.iml @@ -12,5 +12,6 @@ + \ No newline at end of file diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt index 19dc2edb738..43a25af1f57 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt @@ -16,8 +16,16 @@ package org.jetbrains.kotlin.js.inline +import com.google.dart.compiler.backend.js.ast.* +import com.google.dart.compiler.common.SourceInfoImpl +import com.google.gwt.dev.js.JsParser +import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.js.config.LibrarySourcesConfig +import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.TranslationContext +import org.jetbrains.kotlin.js.translate.expression.InlineMetadata +import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.* import org.jetbrains.kotlin.utils.* import java.io.* @@ -52,5 +60,51 @@ public class FunctionReader(private val context: TranslationContext) { } } } + + private fun readFunction(descriptor: CallableDescriptor): JsFunction? { + if (descriptor !in this) return null + val moduleName = getExternalModuleName(descriptor) + val file = requireNotNull(moduleJsDefinition[moduleName], "Module $moduleName file have not been read") + val function = readFunctionFromSource(descriptor, file) + return function + } + + private fun readFunctionFromSource(descriptor: CallableDescriptor, source: String): JsFunction? { + val startTag = Namer.getInlineStartTag(descriptor) + val endTag = Namer.getInlineEndTag(descriptor) + + val startIndex = source.indexOf(startTag) + if (startIndex < 0) return null + + val endIndex = source.indexOf(endTag, startIndex) + if (endIndex < 0) return null + + val metadataString = source.substring(startIndex - 1, endIndex + endTag.length() + 1) + val statements = parseJavaScript(metadataString) + val statement = statements.firstOrNull() + + if (statement !is JsExpressionStatement) throw IllegalStateException("Expected JsExpressionStatement, got: $statement") + val expression = statement.getExpression() + + val metadata = InlineMetadata.decompose(expression) + if (metadata == null) { + throw IllegalStateException("Could not get inline metadata from expression: $expression") + } + + val function = metadata.function + return function + } + + private fun parseJavaScript(source: String): List { + try { + val info = SourceInfoImpl(null, 0, 0, 0, 0) + val scope = JsRootScope(context.program()) + val reader = StringReader(source) + return JsParser.parse(info, scope, reader, ThrowExceptionOnErrorReporter, /* insideFunction= */ false) + } + catch (e: Exception) { + throw RuntimeException(e) + } + } }