use of org.sonar.plugins.python.api.tree.StringLiteral in project sonar-python by SonarSource.
the class UselessStatementCheck method checkStringLiteral.
private void checkStringLiteral(SubscriptionContext ctx) {
StringLiteral stringLiteral = (StringLiteral) ctx.syntaxNode();
if (!reportOnStrings || isDocString(stringLiteral)) {
return;
}
checkNode(ctx);
}
use of org.sonar.plugins.python.api.tree.StringLiteral in project sonar-python by SonarSource.
the class StringFormatMisuseCheck method checkStrFormatStyle.
@Override
protected void checkStrFormatStyle(SubscriptionContext ctx, CallExpression callExpression, Expression qualifier, StringLiteral literal) {
// Check the arguments for out of scope cases before we try to parse the string
if (callExpression.arguments().stream().anyMatch(argument -> !argument.is(Tree.Kind.REGULAR_ARGUMENT))) {
return;
}
Optional<StringFormat> format = StringFormat.createFromStrFormatStyle(syntaxIssueReporter(ctx, qualifier, literal), literal.trimmedQuotesValue());
if (!format.isPresent()) {
return;
}
List<RegularArgument> arguments = callExpression.arguments().stream().map(RegularArgument.class::cast).collect(Collectors.toList());
OptionalInt firstKwIdx = IntStream.range(0, arguments.size()).filter(idx -> arguments.get(idx).keywordArgument() != null).findFirst();
// Check the keyword arguments - build a set of all provided keyword arguments and check if all named fields have
// a match in this set.
Set<String> kwArguments = new HashSet<>();
if (firstKwIdx.isPresent()) {
arguments.subList(firstKwIdx.getAsInt(), arguments.size()).forEach(argument -> kwArguments.add(argument.keywordArgument().name()));
}
format.get().replacementFields().stream().filter(field -> field.isNamed() && !kwArguments.contains(field.name())).forEach(field -> reportIssue(ctx, qualifier, literal, String.format("Provide a value for field \"%s\".", field.name())));
// Produce a list of unmatched positional indices and re-use it for the issue message.
// We basically want to see if there is a position in the field list that is larger than the number of
// the positional arguments provided.
int firstIdx = firstKwIdx.orElse(arguments.size());
String unmatchedPositionals = format.get().replacementFields().stream().filter(field -> field.isPositional() && field.position() >= firstIdx).map(field -> String.valueOf(field.position())).distinct().collect(Collectors.joining(", "));
if (!unmatchedPositionals.isEmpty()) {
reportIssue(ctx, qualifier, literal, String.format("Provide a value for field(s) with index %s.", unmatchedPositionals));
}
}
use of org.sonar.plugins.python.api.tree.StringLiteral in project sonar-python by SonarSource.
the class OverwrittenCollectionEntryCheck method key.
@CheckForNull
private static String key(Tree tree) {
if (tree.is(Kind.TOKEN)) {
return ((Token) tree).value();
} else if (tree.is(Kind.NUMERIC_LITERAL)) {
return ((NumericLiteral) tree).valueAsString();
} else if (tree.is(Kind.STRING_LITERAL)) {
return Expressions.unescape((StringLiteral) tree);
} else if (tree.is(Kind.NAME)) {
return ((Name) tree).name();
} else if (tree.is(Kind.SLICE_ITEM)) {
SliceItem sliceItem = (SliceItem) tree;
List<String> keyParts = Stream.of(sliceItem.lowerBound(), sliceItem.upperBound(), sliceItem.stride()).map(e -> e == null ? "" : key(e)).collect(Collectors.toList());
return keyParts.contains(null) ? null : String.join(":", keyParts);
} else if (tree.is(Kind.UNARY_MINUS)) {
String nested = key(((UnaryExpression) tree).expression());
return nested == null ? null : ("-" + nested);
}
return null;
}
use of org.sonar.plugins.python.api.tree.StringLiteral in project sonar-python by SonarSource.
the class InvalidOpenModeCheck method initialize.
@Override
public void initialize(Context context) {
context.registerSyntaxNodeConsumer(Tree.Kind.CALL_EXPR, ctx -> {
CallExpression callExpression = (CallExpression) ctx.syntaxNode();
Symbol calleeSymbol = callExpression.calleeSymbol();
if (calleeSymbol == null || !"open".equals(calleeSymbol.fullyQualifiedName())) {
return;
}
List<Argument> arguments = callExpression.arguments();
RegularArgument modeArgument = TreeUtils.nthArgumentOrKeyword(1, "mode", arguments);
if (modeArgument == null) {
return;
}
Expression modeExpression = modeArgument.expression();
if (modeExpression.is(Tree.Kind.STRING_LITERAL)) {
checkOpenMode(ctx, modeExpression, (StringLiteral) modeExpression);
} else if (modeExpression.is(Tree.Kind.NAME)) {
Tree assignedValue = Expressions.singleAssignedValue((Name) modeExpression);
if (assignedValue != null && assignedValue.is(Tree.Kind.STRING_LITERAL)) {
checkOpenMode(ctx, modeExpression, (StringLiteral) assignedValue);
}
}
});
}
use of org.sonar.plugins.python.api.tree.StringLiteral in project sonar-python by SonarSource.
the class ImplicitStringConcatenationCheck method initialize.
@Override
public void initialize(Context context) {
context.registerSyntaxNodeConsumer(Tree.Kind.STRING_LITERAL, ctx -> {
StringLiteral stringLiteral = (StringLiteral) ctx.syntaxNode();
if (stringLiteral.parent().is(Tree.Kind.MODULO, Tree.Kind.QUALIFIED_EXPR)) {
// if string formatting is used, explicit string concatenation with "+" might fail
return;
}
if (stringLiteral.stringElements().size() == 1) {
return;
}
checkStringLiteral(stringLiteral, ctx);
});
}
Aggregations