boolean (@NotNull Lexer lexer, @NotNull ParserDefinition parserDefinition, @NotNull TokenSet noWSRequireBeforeTokenSet, @NotNull TokenSet noWSRequireAfterTokenSet, @NotNull TokenSet stringLiteralElements) { int offsetIgnoringComments = 0; int offsetIgnoringCommentsAndStrings = 0; int unneededWhitespaceCount = 0; String lastTokenText = null; IElementType lastTokenType = null; TokenSet whitespaceTokens = parserDefinition.getWhitespaceTokens(); TokenSet commentTokens = parserDefinition.getCommentTokens(); boolean lastWhiteSpaceWasHandled = false; for (IElementType tokenType = lexer.getTokenType(); tokenType != null; lexer.advance(), tokenType = lexer.getTokenType()) { if (commentTokens.contains(tokenType)) { lastTokenType = tokenType; lastTokenText = lexer.getTokenText(); continue; } int tokenLength = lexer.getTokenEnd() - lexer.getTokenStart(); if (isNewLine(lexer, tokenLength) && commentTokens.contains(lastTokenType) && !noWSRequireAfterTokenSet.contains(lastTokenType)) { // do not count new line after line comment token since it's required and it's part of comment continue; } offsetIgnoringComments += tokenLength; if (!stringLiteralElements.contains(tokenType)) { offsetIgnoringCommentsAndStrings += tokenLength; } if (whitespaceTokens.contains(tokenType)) { lastWhiteSpaceWasHandled = false; if (tokenLength > 1 && !commentTokens.contains(lastTokenType)) { lexer.advance(); if (lexer.getTokenType() == null) { // it was last token break; } else { return false; } } if (isNewLine(lexer, tokenLength) && StringUtil.equals(lastTokenText, "\n") || tokenLength > 0 && noWSRequireAfterTokenSet.contains(lastTokenType)) { unneededWhitespaceCount++; lastWhiteSpaceWasHandled = true; } } else { if (!lastWhiteSpaceWasHandled && whitespaceTokens.contains(lastTokenType) && StringUtil.isNotEmpty(lastTokenText) && noWSRequireBeforeTokenSet.contains(tokenType)) { unneededWhitespaceCount++; } } if (stringLiteralElements.contains(tokenType)) { lastTokenType = tokenType; lastTokenText = lexer.getTokenText(); continue; } if (offsetIgnoringComments >= MAX_OFFSET) { break; } lastTokenType = tokenType; lastTokenText = lexer.getTokenText(); } return offsetIgnoringComments >= MIN_SIZE && (unneededWhitespaceCount + 0.0d) / offsetIgnoringCommentsAndStrings < MAX_UNNEEDED_OFFSET_PERCENTAGE; }