diff options
Diffstat (limited to 'src/jdk/nashorn/internal/parser/AbstractParser.java')
-rw-r--r-- | src/jdk/nashorn/internal/parser/AbstractParser.java | 66 |
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; |