use of org.sonar.plugins.python.api.tree.DictionaryLiteral 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();
}
use of org.sonar.plugins.python.api.tree.DictionaryLiteral in project sonar-python by SonarSource.
the class StringFormatCorrectnessCheck method checkPrintfStyle.
@Override
protected void checkPrintfStyle(SubscriptionContext ctx, BinaryExpression modulo, StringLiteral literal) {
Optional<StringFormat> formatOptional = StringFormat.createFromPrintfStyle(IGNORE_SYNTAX_ERRORS, literal.trimmedQuotesValue());
if (!formatOptional.isPresent()) {
// The string format contains invalid syntax.
return;
}
StringFormat format = formatOptional.get();
if (!isInterestingDictLiteral(modulo.rightOperand())) {
return;
}
DictionaryLiteral dict = (DictionaryLiteral) modulo.rightOperand();
List<String> allNames = format.replacementFields().stream().filter(StringFormat.ReplacementField::isNamed).map(StringFormat.ReplacementField::name).collect(Collectors.toList());
dict.elements().stream().map(KeyValuePair.class::cast).map(kv -> (StringLiteral) kv.key()).filter(key -> !allNames.contains(key.trimmedQuotesValue())).forEach(key -> ctx.addIssue(key, "Remove this unused argument or add a replacement field."));
}
use of org.sonar.plugins.python.api.tree.DictionaryLiteral in project sonar-python by SonarSource.
the class DictionaryDuplicateKeyCheck method initialize.
@Override
public void initialize(Context context) {
context.registerSyntaxNodeConsumer(Tree.Kind.DICTIONARY_LITERAL, ctx -> {
DictionaryLiteral dictionaryLiteral = (DictionaryLiteral) ctx.syntaxNode();
Set<Integer> issueIndexes = new HashSet<>();
if (dictionaryLiteral.elements().size() > SIZE_THRESHOLD) {
return;
}
for (int i = 0; i < dictionaryLiteral.elements().size(); i++) {
if (!dictionaryLiteral.elements().get(i).is(Tree.Kind.KEY_VALUE_PAIR) || issueIndexes.contains(i)) {
continue;
}
Expression key = ((KeyValuePair) dictionaryLiteral.elements().get(i)).key();
List<Tree> duplicateKeys = findIdenticalKeys(i, dictionaryLiteral.elements(), issueIndexes);
if (!duplicateKeys.isEmpty()) {
PreciseIssue issue = ctx.addIssue(key, "Change or remove duplicates of this key.");
duplicateKeys.forEach(d -> issue.secondary(d, "Duplicate key"));
}
}
});
}
use of org.sonar.plugins.python.api.tree.DictionaryLiteral 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);
}
use of org.sonar.plugins.python.api.tree.DictionaryLiteral in project sonar-python by SonarSource.
the class HttpOnlyCookieCheck method dictionarySessionCookieHttponlyCheck.
private void dictionarySessionCookieHttponlyCheck(SubscriptionContext ctx) {
DictionaryLiteral dict = (DictionaryLiteral) ctx.syntaxNode();
Optional<Expression> falsySetting = searchForFalsySessionCookieHttponlyInDictionary(dict);
falsySetting.ifPresent(expression -> ctx.addIssue(expression, message()));
}
Aggregations