From 5323fe920da6c35960c89cee83561a1017d9feda Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Wed, 10 Dec 2014 13:01:31 +0300 Subject: [PATCH] JS parser: save token positions --- .../google/gwt/dev/js/rhino/CodePosition.kt | 26 +++++++++++++++++ .../google/gwt/dev/js/rhino/TokenStream.java | 29 +++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 js/js.parser/src/com/google/gwt/dev/js/rhino/CodePosition.kt diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/CodePosition.kt b/js/js.parser/src/com/google/gwt/dev/js/rhino/CodePosition.kt new file mode 100644 index 00000000000..31536c633e0 --- /dev/null +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/CodePosition.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2014 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 com.google.gwt.dev.js.rhino + +class CodePosition(val line: Int, val offset: Int) : Comparable { + override fun compareTo(other: CodePosition): Int = + when { + line < other.line -> -1 + line > other.line -> 1 + else -> offset.compareTo(other.offset) + } +} diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java index afe17122231..c721f605b90 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/TokenStream.java @@ -637,6 +637,8 @@ public class TokenStream { this.pushbackToken = EOF; this.sourceName = sourceName; flags = 0; + secondToLastPosition = new CodePosition(lineno, 0); + lastPosition = new CodePosition(lineno, 0); } /* return and pop the token from the stream if it matches... @@ -761,6 +763,8 @@ public class TokenStream { do { c = getTokenHelper(); } while (c == RETRY_TOKEN); + + updatePosition(); return c; } @@ -1594,17 +1598,35 @@ public class TokenStream { stringBuffer[stringBufferTop++] = (char)c; } + /** + * Positions hold offset of an corresponding token's end. + * So lastPosition holds an offset of char that is next to last token. + * + * Use secondToLastPosition for error reporting outside of TokenStream, because + * usually we want to report beginning of erroneous token, + * which is end of second to last read token. + */ public void reportSyntaxError(String messageProperty, Object[] args) { String message = Context.getMessage(messageProperty, args); + Context.reportError(message, getSourceName(), secondToLastPosition.getLine(), getLine(), secondToLastPosition.getOffset()); + } - Context.reportError(message, getSourceName(), - getLineno(), getLine(), getOffset()); } private void reportSyntaxWarning(String messageProperty, Object[] args) { String message = Context.getMessage(messageProperty, args); Context.reportWarning(message, getSourceName(), getLineno(), getLine(), getOffset()); + + /** + * Updates last two known positions (for error reporting). + */ + private void updatePosition() { + CodePosition currentPosition = new CodePosition(getLineno(), getOffset()); + if (currentPosition.compareTo(lastPosition) > 0) { + secondToLastPosition = lastPosition; + lastPosition = currentPosition; + } } public String getSourceName() { return sourceName; } @@ -1632,6 +1654,9 @@ public class TokenStream { private int pushbackToken; private int tokenno; + CodePosition secondToLastPosition; + CodePosition lastPosition; + private int op; // Set this to an inital non-null value so that the Parser has