Search in sources :

Example 1 with UnpackingExpression

use of org.sonar.plugins.python.api.tree.UnpackingExpression in project sonar-python by SonarSource.

the class DuplicateArgumentCheck method extractKeysFromDictionary.

private static Set<String> extractKeysFromDictionary(UnpackingExpression unpackingExpression) {
    if (unpackingExpression.expression().is(Tree.Kind.DICTIONARY_LITERAL)) {
        return keysInDictionaryLiteral((DictionaryLiteral) unpackingExpression.expression());
    } else if (unpackingExpression.expression().is(Tree.Kind.CALL_EXPR)) {
        return keysFromDictionaryCreation((CallExpression) unpackingExpression.expression());
    } else if (unpackingExpression.expression().is(Tree.Kind.NAME)) {
        Name name = (Name) unpackingExpression.expression();
        Symbol symbol = name.symbol();
        if (symbol == null || symbol.usages().stream().anyMatch(u -> TreeUtils.firstAncestorOfKind(u.tree(), Tree.Kind.DEL_STMT) != null)) {
            return Collections.emptySet();
        }
        Expression expression = Expressions.singleAssignedValue(name);
        if (expression != null && expression.is(Tree.Kind.CALL_EXPR)) {
            return keysFromDictionaryCreation((CallExpression) expression);
        }
        return expression != null && expression.is(Tree.Kind.DICTIONARY_LITERAL) ? keysInDictionaryLiteral((DictionaryLiteral) expression) : Collections.emptySet();
    }
    return Collections.emptySet();
}
Also used : PythonFile(org.sonar.plugins.python.api.PythonFile) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) PythonSubscriptionCheck(org.sonar.plugins.python.api.PythonSubscriptionCheck) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TreeUtils(org.sonar.python.tree.TreeUtils) UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) Name(org.sonar.plugins.python.api.tree.Name) Map(java.util.Map) QualifiedExpression(org.sonar.plugins.python.api.tree.QualifiedExpression) TokenLocation(org.sonar.python.TokenLocation) PythonPunctuator(org.sonar.python.api.PythonPunctuator) Expression(org.sonar.plugins.python.api.tree.Expression) Path(java.nio.file.Path) Nullable(javax.annotation.Nullable) SymbolUtils(org.sonar.python.semantic.SymbolUtils) KeyValuePair(org.sonar.plugins.python.api.tree.KeyValuePair) SymbolUtils.pathOf(org.sonar.python.semantic.SymbolUtils.pathOf) Set(java.util.Set) StringLiteral(org.sonar.plugins.python.api.tree.StringLiteral) SubscriptionContext(org.sonar.plugins.python.api.SubscriptionContext) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Collectors(java.util.stream.Collectors) FunctionSymbolImpl(org.sonar.python.semantic.FunctionSymbolImpl) List(java.util.List) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) Argument(org.sonar.plugins.python.api.tree.Argument) Optional(java.util.Optional) Tree(org.sonar.plugins.python.api.tree.Tree) Rule(org.sonar.check.Rule) LocationInFile(org.sonar.plugins.python.api.LocationInFile) DictionaryLiteral(org.sonar.plugins.python.api.tree.DictionaryLiteral) Collections(java.util.Collections) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) Symbol(org.sonar.plugins.python.api.symbols.Symbol) DictionaryLiteral(org.sonar.plugins.python.api.tree.DictionaryLiteral) UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) QualifiedExpression(org.sonar.plugins.python.api.tree.QualifiedExpression) Expression(org.sonar.plugins.python.api.tree.Expression) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) Symbol(org.sonar.plugins.python.api.symbols.Symbol) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) Name(org.sonar.plugins.python.api.tree.Name)

Example 2 with UnpackingExpression

use of org.sonar.plugins.python.api.tree.UnpackingExpression in project sonar-python by SonarSource.

the class DuplicateArgumentCheck method checkFunctionCall.

private static void checkFunctionCall(CallExpression callExpression, FunctionSymbol functionSymbol, int firstParameterOffset, SubscriptionContext ctx) {
    Map<String, List<Tree>> passedParameters = new HashMap<>();
    List<FunctionSymbol.Parameter> parameters = functionSymbol.parameters();
    List<Argument> arguments = callExpression.arguments();
    for (int i = 0; i < arguments.size(); i++) {
        Argument argument = arguments.get(i);
        if (argument.is(Tree.Kind.REGULAR_ARGUMENT)) {
            RegularArgument regularArgument = (RegularArgument) argument;
            int parameterIndex = i + firstParameterOffset;
            boolean shouldAbortCheck = checkRegularArgument(regularArgument, parameters, parameterIndex, passedParameters);
            if (shouldAbortCheck) {
                return;
            }
        } else {
            UnpackingExpression unpackingExpression = (UnpackingExpression) argument;
            boolean isDictionary = unpackingExpression.starToken().type().equals(PythonPunctuator.MUL_MUL);
            if (isDictionary) {
                checkDictionary(unpackingExpression, passedParameters);
            } else {
                // No issue raised for unpacked positional arguments
                return;
            }
        }
    }
    reportIssues(passedParameters, functionSymbol, ctx);
}
Also used : UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) Argument(org.sonar.plugins.python.api.tree.Argument) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument)

Example 3 with UnpackingExpression

use of org.sonar.plugins.python.api.tree.UnpackingExpression in project sonar-python by SonarSource.

the class IterationOnNonIterable method checkUnpackingExpression.

private void checkUnpackingExpression(SubscriptionContext ctx) {
    UnpackingExpression unpackingExpression = (UnpackingExpression) ctx.syntaxNode();
    if (unpackingExpression.starToken().type().equals(PythonPunctuator.MUL_MUL)) {
        return;
    }
    Expression expression = unpackingExpression.expression();
    Map<LocationInFile, String> secondaries = new HashMap<>();
    if (!isValidIterable(expression, secondaries)) {
        reportIssue(ctx, expression, secondaries, message(expression, false));
    }
}
Also used : UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) Expression(org.sonar.plugins.python.api.tree.Expression) YieldExpression(org.sonar.plugins.python.api.tree.YieldExpression) HashMap(java.util.HashMap) LocationInFile(org.sonar.plugins.python.api.LocationInFile)

Example 4 with UnpackingExpression

use of org.sonar.plugins.python.api.tree.UnpackingExpression in project sonar-python by SonarSource.

the class PythonTreeMakerTest method dictionary_literal.

@Test
public void dictionary_literal() {
    setRootRule(PythonGrammar.ATOM);
    DictionaryLiteral tree = (DictionaryLiteral) parse("{'key': 'value'}", treeMaker::expression);
    assertThat(tree.firstToken().value()).isEqualTo("{");
    assertThat(tree.lastToken().value()).isEqualTo("}");
    assertThat(tree.getKind()).isEqualTo(Tree.Kind.DICTIONARY_LITERAL);
    assertThat(tree.elements()).hasSize(1);
    KeyValuePair keyValuePair = (KeyValuePair) tree.elements().iterator().next();
    assertThat(keyValuePair.getKind()).isEqualTo(Tree.Kind.KEY_VALUE_PAIR);
    assertThat(keyValuePair.key().getKind()).isEqualTo(Tree.Kind.STRING_LITERAL);
    assertThat(keyValuePair.colon().value()).isEqualTo(":");
    assertThat(keyValuePair.value().getKind()).isEqualTo(Tree.Kind.STRING_LITERAL);
    assertThat(tree.children()).hasSize(3).containsExactly(tree.lCurlyBrace(), tree.elements().get(0), tree.rCurlyBrace());
    tree = (DictionaryLiteral) parse("{'key': 'value', 'key2': 'value2'}", treeMaker::expression);
    assertThat(tree.elements()).hasSize(2);
    assertThat(tree.children()).hasSize(5).containsExactly(tree.lCurlyBrace(), tree.elements().get(0), tree.commas().get(0), tree.elements().get(1), tree.rCurlyBrace());
    tree = (DictionaryLiteral) parse("{** var}", treeMaker::expression);
    assertThat(tree.elements()).hasSize(1);
    UnpackingExpression dictUnpacking = (UnpackingExpression) tree.elements().iterator().next();
    assertThat(dictUnpacking.expression().getKind()).isEqualTo(Tree.Kind.NAME);
    assertThat(dictUnpacking.starToken().value()).isEqualTo("**");
    tree = (DictionaryLiteral) parse("{** var, key: value}", treeMaker::expression);
    assertThat(tree.elements()).hasSize(2);
}
Also used : DictionaryLiteral(org.sonar.plugins.python.api.tree.DictionaryLiteral) UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) KeyValuePair(org.sonar.plugins.python.api.tree.KeyValuePair) Test(org.junit.Test) RuleTest(org.sonar.python.parser.RuleTest)

Example 5 with UnpackingExpression

use of org.sonar.plugins.python.api.tree.UnpackingExpression in project sonar-python by SonarSource.

the class PythonTreeMakerTest method argument.

@Test
public void argument() {
    setRootRule(PythonGrammar.ARGUMENT);
    RegularArgument argumentTree = (RegularArgument) parse("foo", treeMaker::argument);
    assertThat(argumentTree.equalToken()).isNull();
    assertThat(argumentTree.keywordArgument()).isNull();
    Name name = (Name) argumentTree.expression();
    assertThat(name.name()).isEqualTo("foo");
    assertThat(argumentTree.children()).hasSize(1);
    UnpackingExpression iterableUnpacking = (UnpackingExpression) parse("*foo", treeMaker::argument);
    name = (Name) iterableUnpacking.expression();
    assertThat(name.name()).isEqualTo("foo");
    assertThat(iterableUnpacking.children()).hasSize(2);
    UnpackingExpression dictionaryUnpacking = (UnpackingExpression) parse("**foo", treeMaker::argument);
    name = (Name) dictionaryUnpacking.expression();
    assertThat(name.name()).isEqualTo("foo");
    assertThat(dictionaryUnpacking.starToken()).isNotNull();
    assertThat(dictionaryUnpacking.children()).hasSize(2);
    argumentTree = (RegularArgument) parse("bar=foo", treeMaker::argument);
    assertThat(argumentTree.equalToken()).isNotNull();
    Name keywordArgument = argumentTree.keywordArgument();
    assertThat(keywordArgument.name()).isEqualTo("bar");
    name = (Name) argumentTree.expression();
    assertThat(name.name()).isEqualTo("foo");
    assertThat(argumentTree.children()).hasSize(3).containsExactly(argumentTree.keywordArgument(), argumentTree.equalToken(), argumentTree.expression());
}
Also used : UnpackingExpression(org.sonar.plugins.python.api.tree.UnpackingExpression) RegularArgument(org.sonar.plugins.python.api.tree.RegularArgument) AliasedName(org.sonar.plugins.python.api.tree.AliasedName) Name(org.sonar.plugins.python.api.tree.Name) ImportName(org.sonar.plugins.python.api.tree.ImportName) Test(org.junit.Test) RuleTest(org.sonar.python.parser.RuleTest)

Aggregations

UnpackingExpression (org.sonar.plugins.python.api.tree.UnpackingExpression)7 RegularArgument (org.sonar.plugins.python.api.tree.RegularArgument)4 HashMap (java.util.HashMap)3 Test (org.junit.Test)3 Argument (org.sonar.plugins.python.api.tree.Argument)3 Expression (org.sonar.plugins.python.api.tree.Expression)3 RuleTest (org.sonar.python.parser.RuleTest)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 LocationInFile (org.sonar.plugins.python.api.LocationInFile)2 Symbol (org.sonar.plugins.python.api.symbols.Symbol)2 CallExpression (org.sonar.plugins.python.api.tree.CallExpression)2 DictionaryLiteral (org.sonar.plugins.python.api.tree.DictionaryLiteral)2 KeyValuePair (org.sonar.plugins.python.api.tree.KeyValuePair)2 Name (org.sonar.plugins.python.api.tree.Name)2 Path (java.nio.file.Path)1 Collections (java.util.Collections)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Set (java.util.Set)1