aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/parser/AbstractParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/parser/AbstractParser.java')
-rw-r--r--src/jdk/nashorn/internal/parser/AbstractParser.java66
1 files changed, 50 insertions, 16 deletions
diff --git a/src/jdk/nashorn/internal/parser/AbstractParser.java b/src/jdk/nashorn/internal/parser/AbstractParser.java
index d4a42ba4..3eb45cfb 100644
--- a/src/jdk/nashorn/internal/parser/AbstractParser.java
+++ b/src/jdk/nashorn/internal/parser/AbstractParser.java
@@ -30,7 +30,8 @@ import static jdk.nashorn.internal.parser.TokenType.DIRECTIVE_COMMENT;
import static jdk.nashorn.internal.parser.TokenType.EOF;
import static jdk.nashorn.internal.parser.TokenType.EOL;
import static jdk.nashorn.internal.parser.TokenType.IDENT;
-
+import java.util.HashMap;
+import java.util.Map;
import jdk.nashorn.internal.ir.IdentNode;
import jdk.nashorn.internal.ir.LiteralNode;
import jdk.nashorn.internal.parser.Lexer.LexerToken;
@@ -58,6 +59,9 @@ public abstract class AbstractParser {
/** Index of current token. */
protected int k;
+ /** Previous token - accessible to sub classes */
+ protected long previousToken;
+
/** Descriptor of current token. */
protected long token;
@@ -85,17 +89,20 @@ public abstract class AbstractParser {
/** Is this parser running under strict mode? */
protected boolean isStrictMode;
- /** //@ sourceURL or //# sourceURL */
- protected String sourceURL;
+ /** What should line numbers be counted from? */
+ protected final int lineOffset;
+
+ private final Map<String, String> canonicalNames = new HashMap<>();
/**
* Construct a parser.
*
- * @param source Source to parse.
- * @param errors Error reporting manager.
- * @param strict True if we are in strict mode
+ * @param source Source to parse.
+ * @param errors Error reporting manager.
+ * @param strict True if we are in strict mode
+ * @param lineOffset Offset from which lines should be counted
*/
- protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict) {
+ protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict, final int lineOffset) {
this.source = source;
this.errors = errors;
this.k = -1;
@@ -103,6 +110,7 @@ public abstract class AbstractParser {
this.type = EOL;
this.last = EOL;
this.isStrictMode = strict;
+ this.lineOffset = lineOffset;
}
/**
@@ -174,7 +182,7 @@ public abstract class AbstractParser {
// currently only @sourceURL=foo supported
private void checkDirectiveComment() {
// if already set, ignore this one
- if (sourceURL != null) {
+ if (source.getExplicitURL() != null) {
return;
}
@@ -182,7 +190,7 @@ public abstract class AbstractParser {
final int len = comment.length();
// 4 characters for directive comment marker //@\s or //#\s
if (len > 4 && comment.substring(4).startsWith(SOURCE_URL_PREFIX)) {
- sourceURL = comment.substring(4 + SOURCE_URL_PREFIX.length());
+ source.setExplicitURL(comment.substring(4 + SOURCE_URL_PREFIX.length()));
}
}
@@ -199,6 +207,7 @@ public abstract class AbstractParser {
// Set up next token.
k++;
final long lastToken = token;
+ previousToken = token;
token = getToken(k);
type = Token.descType(token);
@@ -208,7 +217,7 @@ public abstract class AbstractParser {
}
if (type == EOL) {
- line = Token.descLength(token);
+ line = Token.descLength(token);
linePosition = Token.descPosition(token);
} else {
start = Token.descPosition(token);
@@ -316,18 +325,28 @@ public abstract class AbstractParser {
}
/**
- * Check next token and advance.
+ * Check current token and advance to the next token.
*
* @param expected Expected tokenType.
*
* @throws ParserException on unexpected token type
*/
protected final void expect(final TokenType expected) throws ParserException {
+ expectDontAdvance(expected);
+ next();
+ }
+
+ /**
+ * Check current token, but don't advance to the next token.
+ *
+ * @param expected Expected tokenType.
+ *
+ * @throws ParserException on unexpected token type
+ */
+ protected final void expectDontAdvance(final TokenType expected) throws ParserException {
if (type != expected) {
throw error(expectMessage(expected));
}
-
- next();
}
/**
@@ -403,7 +422,7 @@ public abstract class AbstractParser {
next();
// Create IDENT node.
- return new IdentNode(identToken, finish, ident).setIsFutureStrictName();
+ return createIdentNode(identToken, finish, ident).setIsFutureStrictName();
}
// Get IDENT.
@@ -412,7 +431,22 @@ public abstract class AbstractParser {
return null;
}
// Create IDENT node.
- return new IdentNode(identToken, finish, ident);
+ return createIdentNode(identToken, finish, ident);
+ }
+
+ /**
+ * Creates a new {@link IdentNode} as if invoked with a {@link IdentNode#IdentNode(long, int, String)
+ * constructor} but making sure that the {@code name} is deduplicated within this parse job.
+ * @param identToken the token for the new {@code IdentNode}
+ * @param identFinish the finish for the new {@code IdentNode}
+ * @param name the name for the new {@code IdentNode}. It will be de-duplicated.
+ * @return a newly constructed {@code IdentNode} with the specified token, finish, and name; the name will
+ * be deduplicated.
+ */
+ protected IdentNode createIdentNode(final long identToken, final int identFinish, final String name) {
+ final String existingName = canonicalNames.putIfAbsent(name, name);
+ final String canonicalName = existingName != null ? existingName : name;
+ return new IdentNode(identToken, identFinish, canonicalName);
}
/**
@@ -447,7 +481,7 @@ public abstract class AbstractParser {
final String ident = (String)getValue(identToken);
next();
// Create IDENT node.
- return new IdentNode(identToken, finish, ident);
+ return createIdentNode(identToken, finish, ident);
} else {
expect(IDENT);
return null;