Search in sources :

Example 1 with StringLiteral

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);
}
Also used : StringLiteral(org.sonar.plugins.python.api.tree.StringLiteral)

Example 2 with StringLiteral

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));
    }
}
Also used : IntStream(java.util.stream.IntStream) BinaryExpression(org.sonar.plugins.python.api.tree.BinaryExpression) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) Set(java.util.Set) StringLiteral(org.sonar.plugins.python.api.tree.StringLiteral) SubscriptionContext(org.sonar.plugins.python.api.SubscriptionContext) OptionalInt(java.util.OptionalInt) Collectors(java.util.stream.Collectors) HashSet(java.util.HashSet) BuiltinTypes(org.sonar.plugins.python.api.types.BuiltinTypes) List(java.util.List) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) Optional(java.util.Optional) Expression(org.sonar.plugins.python.api.tree.Expression) Tree(org.sonar.plugins.python.api.tree.Tree) Rule(org.sonar.check.Rule) DictionaryLiteral(org.sonar.plugins.python.api.tree.DictionaryLiteral) Tuple(org.sonar.plugins.python.api.tree.Tuple) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) OptionalInt(java.util.OptionalInt) HashSet(java.util.HashSet)

Example 3 with StringLiteral

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;
}
Also used : NumericLiteral(org.sonar.plugins.python.api.tree.NumericLiteral) PythonSubscriptionCheck(org.sonar.plugins.python.api.PythonSubscriptionCheck) HasSymbol(org.sonar.plugins.python.api.tree.HasSymbol) HashMap(java.util.HashMap) AssignmentStatement(org.sonar.plugins.python.api.tree.AssignmentStatement) ArrayList(java.util.ArrayList) TreeUtils(org.sonar.python.tree.TreeUtils) Kind(org.sonar.plugins.python.api.tree.Tree.Kind) IssueLocation(org.sonar.plugins.python.api.IssueLocation) Name(org.sonar.plugins.python.api.tree.Name) Map(java.util.Map) Statement(org.sonar.plugins.python.api.tree.Statement) Expression(org.sonar.plugins.python.api.tree.Expression) Nullable(javax.annotation.Nullable) StatementList(org.sonar.plugins.python.api.tree.StatementList) SliceItem(org.sonar.plugins.python.api.tree.SliceItem) StringLiteral(org.sonar.plugins.python.api.tree.StringLiteral) Token(org.sonar.plugins.python.api.tree.Token) SubscriptionContext(org.sonar.plugins.python.api.SubscriptionContext) Collectors(java.util.stream.Collectors) UnaryExpression(org.sonar.plugins.python.api.tree.UnaryExpression) AbstractMap(java.util.AbstractMap) List(java.util.List) Stream(java.util.stream.Stream) SliceExpression(org.sonar.plugins.python.api.tree.SliceExpression) SubscriptionExpression(org.sonar.plugins.python.api.tree.SubscriptionExpression) Tree(org.sonar.plugins.python.api.tree.Tree) Rule(org.sonar.check.Rule) CheckForNull(javax.annotation.CheckForNull) Symbol(org.sonar.plugins.python.api.symbols.Symbol) Token(org.sonar.plugins.python.api.tree.Token) SliceItem(org.sonar.plugins.python.api.tree.SliceItem) UnaryExpression(org.sonar.plugins.python.api.tree.UnaryExpression) CheckForNull(javax.annotation.CheckForNull)

Example 4 with StringLiteral

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);
            }
        }
    });
}
Also used : RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) Argument(org.sonar.plugins.python.api.tree.Argument) StringLiteral(org.sonar.plugins.python.api.tree.StringLiteral) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) Expression(org.sonar.plugins.python.api.tree.Expression) Symbol(org.sonar.plugins.python.api.symbols.Symbol) Tree(org.sonar.plugins.python.api.tree.Tree) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) Name(org.sonar.plugins.python.api.tree.Name)

Example 5 with StringLiteral

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);
    });
}
Also used : StringLiteral(org.sonar.plugins.python.api.tree.StringLiteral)

Aggregations

StringLiteral (org.sonar.plugins.python.api.tree.StringLiteral)26 Expression (org.sonar.plugins.python.api.tree.Expression)15 CallExpression (org.sonar.plugins.python.api.tree.CallExpression)14 BinaryExpression (org.sonar.plugins.python.api.tree.BinaryExpression)12 QualifiedExpression (org.sonar.plugins.python.api.tree.QualifiedExpression)9 List (java.util.List)8 SubscriptionExpression (org.sonar.plugins.python.api.tree.SubscriptionExpression)8 AssignmentExpression (org.sonar.plugins.python.api.tree.AssignmentExpression)7 SliceExpression (org.sonar.plugins.python.api.tree.SliceExpression)7 Tree (org.sonar.plugins.python.api.tree.Tree)7 Symbol (org.sonar.plugins.python.api.symbols.Symbol)6 AwaitExpression (org.sonar.plugins.python.api.tree.AwaitExpression)6 ComprehensionExpression (org.sonar.plugins.python.api.tree.ComprehensionExpression)6 ConditionalExpression (org.sonar.plugins.python.api.tree.ConditionalExpression)6 DictCompExpression (org.sonar.plugins.python.api.tree.DictCompExpression)6 EllipsisExpression (org.sonar.plugins.python.api.tree.EllipsisExpression)6 FormattedExpression (org.sonar.plugins.python.api.tree.FormattedExpression)6 InExpression (org.sonar.plugins.python.api.tree.InExpression)6 IsExpression (org.sonar.plugins.python.api.tree.IsExpression)6 LambdaExpression (org.sonar.plugins.python.api.tree.LambdaExpression)6