com.github.sbaudoin.sonar.plugins.shellcheck.measures.LineCountParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonar-shellcheck-plugin Show documentation
Show all versions of sonar-shellcheck-plugin Show documentation
ShellCheck plugin for SonarQube
/**
* Copyright (c) 2018-2019, Sylvain Baudoin
*
* 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.github.sbaudoin.sonar.plugins.shellcheck.measures;
import com.github.sbaudoin.sonar.plugins.shellcheck.highlighting.ShellLocation;
import com.github.sbaudoin.sonar.plugins.shellcheck.lexer.BashLexer;
import com.github.sbaudoin.sonar.plugins.shellcheck.lexer.TokenType;
import org.apache.commons.lang.StringUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Counting lines, comment lines and blank lines in Shell scripts
*/
public final class LineCountParser {
private int lineNumber;
private Set commentLines;
private Set linesOfCodeLines;
private LineCountData data;
/**
* Constructor. The passed string is parsed and an instance of {@code LineCountData} is created and ready for
* retrieval with the method {@linkplain #getLineCountData()}
*
* @param contents the Shell script to be parsed
* @throws IOException if there is a problem reading the contents
* @see #getLineCountData()
*/
public LineCountParser(String contents) throws IOException {
commentLines = new HashSet<>();
linesOfCodeLines = new HashSet<>();
lineNumber = 0;
// Get heredoc lines: these are lines to be ignored while looking for comments
List hdLines = new ArrayList<>();
BashLexer lexer = new BashLexer(new StringReader(contents));
while (lexer.next() != null) {
if (lexer.getToken().type == TokenType.HEREDOC_CONTENT) {
ShellLocation start = new ShellLocation(contents, lexer.getToken());
for (int line = start.line() ; line < start.shift(lexer.getToken().length).line() ; line++) {
hdLines.add(line);
}
}
}
BufferedReader reader = new BufferedReader(new StringReader(contents));
String line;
while ((line = reader.readLine()) != null) {
if (!hdLines.contains(lineNumber) && isCommentLine(line)) {
commentLines.add(lineNumber);
} else if (!isBlankLine(line)) {
linesOfCodeLines.add(lineNumber);
}
lineNumber++;
}
this.data = new LineCountData(
lineNumber,
linesOfCodeLines,
commentLines);
}
/**
* Returns the {@code LineCountData} describing the passed Shell script
*
* @return the {@code LineCountData} describing the passed Shell script
*/
public LineCountData getLineCountData() {
return data;
}
/**
* Tells if the passed line of code is a comment line, i.e. a line with only a non-empty comment
*
* @param line a line of code
* @return {@code true} if the passed string represents a line of comment. Inline comments return {@code false}.
*/
private boolean isCommentLine(String line) {
return line.trim().matches("^[ \\t]*#[ \\t]*\\S.*");
}
/**
* Tells if the passed line is blank, i.e. it contains nothing but whitespaces
*
* @param line a line of code
* @return {@code true} if the line if blank, {@code false} if not
*/
private boolean isBlankLine(String line) {
return StringUtils.isBlank(line);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy