All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.js.parser.parserUtils.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2015 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.js.parser

import com.google.gwt.dev.js.JsAstMapper
import com.google.gwt.dev.js.rhino.*
import org.jetbrains.kotlin.js.backend.ast.JsFunction
import org.jetbrains.kotlin.js.backend.ast.JsFunctionScope
import org.jetbrains.kotlin.js.backend.ast.JsScope
import org.jetbrains.kotlin.js.backend.ast.JsStatement
import java.io.Reader
import java.io.StringReader
import java.util.*

fun parse(code: String, reporter: ErrorReporter, scope: JsScope, fileName: String): List {
    val insideFunction = scope is JsFunctionScope
    val node = parse(code, CodePosition(0, 0), 0, reporter, insideFunction, Parser::parse)
    return node.toJsAst(scope, fileName) {
        mapStatements(it)
    }
}

fun parseFunction(code: String, fileName: String, position: CodePosition, offset: Int, reporter: ErrorReporter, scope: JsScope): JsFunction =
        parse(code, position, offset, reporter, insideFunction = false) {
            addObserver(FunctionParsingObserver())
            primaryExpr(it)
        }.toJsAst(scope, fileName, JsAstMapper::mapFunction)

private class FunctionParsingObserver : Observer {
    var functionsStarted = 0

    override fun update(o: Observable?, arg: Any?) {
        when (arg) {
            is ParserEvents.OnFunctionParsingStart -> {
                functionsStarted++
            }
            is ParserEvents.OnFunctionParsingEnd -> {
                functionsStarted--

                if (functionsStarted == 0) {
                    arg.tokenStream.ungetToken(TokenStream.EOF)
                }
            }
        }
    }
}

inline
private fun parse(
        code: String,
        startPosition: CodePosition,
        offset: Int,
        reporter: ErrorReporter,
        insideFunction: Boolean,
        parseAction: Parser.(TokenStream)->Any
): Node {
    Context.enter().errorReporter = reporter

    try {
        val ts = TokenStream(StringReader(code, offset), "", startPosition)
        val parser = Parser(IRFactory(ts), insideFunction)
        return parser.parseAction(ts) as Node
    } finally {
        Context.exit()
    }
}

inline
private fun  Node.toJsAst(scope: JsScope, fileName: String, mapAction: JsAstMapper.(Node)->T): T =
        JsAstMapper(scope, fileName).mapAction(this)

private fun StringReader(string: String, offset: Int): Reader {
    val reader = StringReader(string)
    reader.skip(offset.toLong())
    return reader
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy