JS: use one tag for inlining
This commit is contained in:
@@ -17,68 +17,25 @@ package com.google.gwt.dev.js;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.backend.js.ast.JsLiteral.JsBooleanLiteral;
|
||||
import com.google.dart.compiler.common.SourceInfo;
|
||||
import com.google.gwt.dev.js.parserExceptions.JsParserException;
|
||||
import com.google.gwt.dev.js.rhino.*;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.dart.compiler.util.AstUtil.toFunctionScope;
|
||||
|
||||
/**
|
||||
* Parses JavaScript source.
|
||||
*/
|
||||
public class JsAstMapper {
|
||||
|
||||
private final JsProgram program;
|
||||
private final ScopeContext scopeContext;
|
||||
|
||||
public static List<JsStatement> parse(
|
||||
SourceInfo rootSourceInfo,
|
||||
JsScope scope, Reader r,
|
||||
ErrorReporter errorReporter,
|
||||
boolean insideFunction
|
||||
) throws IOException, JsParserException {
|
||||
return new JsAstMapper(scope).parseImpl(rootSourceInfo, r, errorReporter, insideFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* since source maps are not mapped to kotlin source maps
|
||||
*/
|
||||
private static final String SOURCE_NAME_STUB = "jsCode";
|
||||
|
||||
private JsAstMapper(@NotNull JsScope scope) {
|
||||
public JsAstMapper(@NotNull JsScope scope) {
|
||||
scopeContext = new ScopeContext(scope);
|
||||
program = scope.getProgram();
|
||||
}
|
||||
|
||||
List<JsStatement> parseImpl(
|
||||
final SourceInfo rootSourceInfo,
|
||||
Reader r,
|
||||
ErrorReporter errorReporter,
|
||||
boolean insideFunction
|
||||
) throws JsParserException, IOException {
|
||||
// Create a custom error handler so that we can throw our own exceptions.
|
||||
Context.enter().setErrorReporter(errorReporter);
|
||||
try {
|
||||
// Parse using the Rhino parser.
|
||||
//
|
||||
TokenStream ts = new TokenStream(r, SOURCE_NAME_STUB, rootSourceInfo.getLine());
|
||||
Parser parser = new Parser(new IRFactory(ts), insideFunction);
|
||||
Node topNode = (Node) parser.parse(ts);
|
||||
return mapStatements(topNode);
|
||||
}
|
||||
finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
private static JsParserException createParserException(String msg, Node offender) {
|
||||
CodePosition position = new CodePosition(offender.getLineno(), 0);
|
||||
return new JsParserException("Parser encountered internal error: " + msg, position);
|
||||
@@ -594,8 +551,9 @@ public class JsAstMapper {
|
||||
}
|
||||
}
|
||||
|
||||
private JsExpression mapFunction(Node fnNode) throws JsParserException {
|
||||
|
||||
public JsFunction mapFunction(Node fnNode) throws JsParserException {
|
||||
int nodeType = fnNode.getType();
|
||||
assert nodeType == TokenStream.FUNCTION: "Expected function node, got: " + TokenStream.tokenToName(nodeType);
|
||||
Node fromFnNameNode = fnNode.getFirstChild();
|
||||
Node fromParamNode = fnNode.getFirstChild().getNext().getFirstChild();
|
||||
Node fromBodyNode = fnNode.getFirstChild().getNext().getNext();
|
||||
@@ -954,7 +912,7 @@ public class JsAstMapper {
|
||||
}
|
||||
}
|
||||
|
||||
private List<JsStatement> mapStatements(Node nodeStmts)
|
||||
public List<JsStatement> mapStatements(Node nodeStmts)
|
||||
throws JsParserException {
|
||||
List<JsStatement> stmts = new ArrayList<JsStatement>();
|
||||
mapStatements(stmts, nodeStmts);
|
||||
|
||||
@@ -37,7 +37,10 @@
|
||||
|
||||
package com.google.gwt.dev.js.rhino;
|
||||
|
||||
import org.jetbrains.kotlin.js.parser.ParserEvents;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Observable;
|
||||
|
||||
/**
|
||||
* This class implements the JavaScript parser.
|
||||
@@ -48,7 +51,7 @@ import java.io.IOException;
|
||||
* @see TokenStream
|
||||
*/
|
||||
|
||||
public class Parser {
|
||||
public class Parser extends Observable {
|
||||
public Parser(IRFactory nf, boolean insideFunction) {
|
||||
this.nf = nf;
|
||||
this.insideFunction = insideFunction;
|
||||
@@ -165,8 +168,8 @@ public class Parser {
|
||||
return pn;
|
||||
}
|
||||
|
||||
private Object function(TokenStream ts, boolean isExpr) throws IOException,
|
||||
JavaScriptException {
|
||||
private Object function(TokenStream ts, boolean isExpr) throws IOException, JavaScriptException {
|
||||
notifyObservers(new ParserEvents.OnFunctionParsingStart());
|
||||
int baseLineno = ts.getLineno(); // line number where source starts
|
||||
|
||||
String name;
|
||||
@@ -243,6 +246,7 @@ public class Parser {
|
||||
wellTerminated(ts, ts.FUNCTION);
|
||||
}
|
||||
|
||||
notifyObservers(new ParserEvents.OnFunctionParsingEnd(ts));
|
||||
return pn;
|
||||
}
|
||||
|
||||
@@ -1021,7 +1025,7 @@ public class Parser {
|
||||
return pn;
|
||||
}
|
||||
|
||||
private Object primaryExpr(TokenStream ts) throws IOException,
|
||||
public Object primaryExpr(TokenStream ts) throws IOException,
|
||||
JavaScriptException {
|
||||
int tt;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.rhino.*
|
||||
|
||||
public object ParserEvents {
|
||||
|
||||
public class OnFunctionParsingStart
|
||||
|
||||
public class OnFunctionParsingEnd(public val tokenStream: TokenStream)
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.dart.compiler.common.*
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import com.google.gwt.dev.js.*
|
||||
import com.google.gwt.dev.js.rhino.*
|
||||
|
||||
import com.intellij.util.*
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
|
||||
private val FAKE_SOURCE_INFO = SourceInfoImpl(null, 0, 0, 0, 0)
|
||||
|
||||
public fun parse(code: String, reporter: ErrorReporter, insideFunction: Boolean): List<JsStatement> =
|
||||
parse(code, 0, reporter, insideFunction, Parser::parse).toJsAst(JsAstMapper::mapStatements)
|
||||
|
||||
public fun parseFunction(code: String, offset: Int, reporter: ErrorReporter): JsFunction =
|
||||
parse(code, offset, reporter, insideFunction = false) {
|
||||
addObserver(FunctionParsingObserver())
|
||||
primaryExpr(it)
|
||||
}.toJsAst(JsAstMapper::mapFunction)
|
||||
|
||||
private class FunctionParsingObserver : Observer {
|
||||
var functionsStarted = 0
|
||||
|
||||
override fun update(o: Observable?, arg: Any?): Unit =
|
||||
when (arg) {
|
||||
is ParserEvents.OnFunctionParsingStart -> {
|
||||
functionsStarted++
|
||||
}
|
||||
is ParserEvents.OnFunctionParsingEnd -> {
|
||||
functionsStarted--
|
||||
|
||||
if (functionsStarted == 0) {
|
||||
arg.tokenStream.ungetToken(TokenStream.EOF)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
private fun parse(
|
||||
code: String,
|
||||
offset: Int,
|
||||
reporter: ErrorReporter,
|
||||
insideFunction: Boolean,
|
||||
parseAction: Parser.(TokenStream)->Any
|
||||
): Node {
|
||||
Context.enter().setErrorReporter(reporter)
|
||||
|
||||
try {
|
||||
val ts = TokenStream(StringReader(code, offset), "<parser>", FAKE_SOURCE_INFO.getLine())
|
||||
val parser = Parser(IRFactory(ts), insideFunction)
|
||||
return parser.parseAction(ts) as Node
|
||||
} finally {
|
||||
Context.exit()
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
private fun Node.toJsAst<T>(mapAction: JsAstMapper.(Node)->T): T =
|
||||
JsAstMapper(RootScope()).mapAction(this)
|
||||
|
||||
private fun StringReader(string: String, offset: Int): Reader {
|
||||
val reader = StringReader(string)
|
||||
reader.skip(offset.toLong())
|
||||
return reader
|
||||
}
|
||||
|
||||
private fun RootScope(): JsScope {
|
||||
return JsRootScope(JsProgram("<parser>"))
|
||||
}
|
||||
Reference in New Issue
Block a user