package depends.extractor.golang; import org.antlr.v4.runtime.*; import java.util.List; /** * All parser methods that used in grammar (p, prev, notLineTerminator, etc.) * should start with lower case char similar to parser rules. */ public abstract class GoParserBase extends Parser { protected GoParserBase(TokenStream input) { super(input); } /** * Returns {@code true} iff on the current index of the parser's * token stream a token exists on the {@code HIDDEN} channel which * either is a line terminator, or is a multi line comment that * contains a line terminator. * * @return {@code true} iff on the current index of the parser's * token stream a token exists on the {@code HIDDEN} channel which * either is a line terminator, or is a multi line comment that * contains a line terminator. */ protected boolean lineTerminatorAhead() { // Get the token ahead of the current index. int possibleIndexEosToken = this.getCurrentToken().getTokenIndex() - 1; if (possibleIndexEosToken == -1) { return true; } Token ahead = _input.get(possibleIndexEosToken); if (ahead.getChannel() != Lexer.HIDDEN) { // We're only interested in tokens on the HIDDEN channel. return false; } if (ahead.getType() == GoLexer.TERMINATOR) { // There is definitely a line terminator ahead. return true; } if (ahead.getType() == GoLexer.WS) { // Get the token ahead of the current whitespaces. possibleIndexEosToken = this.getCurrentToken().getTokenIndex() - 2; ahead = _input.get(possibleIndexEosToken); } // Get the token's text and type. String text = ahead.getText(); int type = ahead.getType(); // Check if the token is, or contains a line terminator. return (type == GoLexer.COMMENT && (text.contains("\r") || text.contains("\n"))) || (type == GoLexer.TERMINATOR); } /** * Returns {@code true} if no line terminator exists between the specified * token offset and the prior one on the {@code HIDDEN} channel. * * @return {@code true} if no line terminator exists between the specified * token offset and the prior one on the {@code HIDDEN} channel. */ protected boolean noTerminatorBetween(int tokenOffset) { BufferedTokenStream stream = (BufferedTokenStream)_input; List tokens = stream.getHiddenTokensToLeft(stream.LT(tokenOffset).getTokenIndex()); if (tokens == null) { return true; } for (Token token : tokens) { if (token.getText().contains("\n")) return false; } return true; } /** * Returns {@code true} if no line terminator exists after any encounterd * parameters beyond the specified token offset and the next on the * {@code HIDDEN} channel. * * @return {@code true} if no line terminator exists after any encounterd * parameters beyond the specified token offset and the next on the * {@code HIDDEN} channel. */ protected boolean noTerminatorAfterParams(int tokenOffset) { BufferedTokenStream stream = (BufferedTokenStream)_input; int leftParams = 1; int rightParams = 0; int valueType; if (stream.LT(tokenOffset).getType() == GoLexer.L_PAREN) { // Scan past parameters while (leftParams != rightParams) { tokenOffset++; valueType = stream.LT(tokenOffset).getType(); if (valueType == GoLexer.L_PAREN){ leftParams++; } else if (valueType == GoLexer.R_PAREN) { rightParams++; } } tokenOffset++; return noTerminatorBetween(tokenOffset); } return true; } protected boolean checkPreviousTokenText(String text) { BufferedTokenStream stream = (BufferedTokenStream)_input; String prevTokenText = stream.LT(1).getText(); if (prevTokenText == null) return false; return prevTokenText.equals(text); } }