Search in sources :

Example 1 with FunctionSymbol

use of org.sonar.plugins.python.api.symbols.FunctionSymbol in project sonar-python by SonarSource.

the class TypeShedTest method return_type_hints.

@Test
public void return_type_hints() {
    Map<String, Symbol> symbols = symbolsForModule("typing");
    assertThat(((FunctionSymbolImpl) symbols.get("get_args")).annotatedReturnTypeName()).isEqualTo("tuple");
    symbols = symbolsForModule("flask_mail");
    ClassSymbol mail = (ClassSymbol) symbols.get("Mail");
    assertThat(((FunctionSymbol) mail.declaredMembers().stream().iterator().next()).annotatedReturnTypeName()).isNull();
}
Also used : FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) AmbiguousSymbol(org.sonar.plugins.python.api.symbols.AmbiguousSymbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) Symbol(org.sonar.plugins.python.api.symbols.Symbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) FunctionSymbolImpl(org.sonar.python.semantic.FunctionSymbolImpl) Test(org.junit.Test)

Example 2 with FunctionSymbol

use of org.sonar.plugins.python.api.symbols.FunctionSymbol in project sonar-python by SonarSource.

the class FunctionSymbolTest method instance_method.

@Test
public void instance_method() {
    FileInput fileInput = PythonTestUtils.parse("class A:", "  def foo(self): pass", "  def __new__(cls, a): pass", "  @staticmethod", "  def static_foo(): pass", "  @classmethod", "  def class_foo(): pass");
    ClassSymbol classSymbol = TreeUtils.getClassSymbolFromDef(((ClassDef) fileInput.statements().statements().get(0)));
    FunctionSymbol foo = (FunctionSymbol) classSymbol.resolveMember("foo").get();
    assertThat(foo.isInstanceMethod()).isTrue();
    FunctionSymbol static_foo = (FunctionSymbol) classSymbol.resolveMember("static_foo").get();
    assertThat(static_foo.isInstanceMethod()).isFalse();
    FunctionSymbol class_foo = (FunctionSymbol) classSymbol.resolveMember("class_foo").get();
    assertThat(class_foo.isInstanceMethod()).isFalse();
    FunctionSymbol newMethod = (FunctionSymbol) classSymbol.resolveMember("__new__").get();
    assertThat(newMethod.isInstanceMethod()).isFalse();
}
Also used : ClassDef(org.sonar.plugins.python.api.tree.ClassDef) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) FileInput(org.sonar.plugins.python.api.tree.FileInput) Test(org.junit.Test)

Example 3 with FunctionSymbol

use of org.sonar.plugins.python.api.symbols.FunctionSymbol in project sonar-python by SonarSource.

the class FunctionSymbolTest method arity.

@Test
public void arity() {
    FunctionSymbol functionSymbol = PythonTestUtils.functionSymbol("def fn(): pass");
    assertThat(functionSymbol.isAsynchronous()).isFalse();
    assertThat(functionSymbol.parameters()).isEmpty();
    functionSymbol = PythonTestUtils.functionSymbol("async def fn(p1, p2, p3): pass");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2", "p3");
    assertThat(functionSymbol.hasVariadicParameter()).isFalse();
    assertThat(functionSymbol.isInstanceMethod()).isFalse();
    assertThat(functionSymbol.isAsynchronous()).isTrue();
    assertThat(functionSymbol.hasDecorators()).isFalse();
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::hasDefaultValue).containsExactly(false, false, false);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, false, false);
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, *, p2): pass");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::hasDefaultValue).containsExactly(false, false);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, true);
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, /, p2): pass");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, false);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isPositionalOnly).containsExactly(true, false);
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, /, p2, *, p3): pass");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2", "p3");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, false, true);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isPositionalOnly).containsExactly(true, false, false);
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, /, p2, *p3, p4 = False): pass");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2", "p3", "p4");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, false, false, true);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isPositionalOnly).containsExactly(true, false, false, false);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isVariadic).containsExactly(false, false, true, false);
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, p2=42): pass");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::hasDefaultValue).containsExactly(false, true);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, false);
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, *, p2=42): pass");
    assertThat(functionSymbol.hasVariadicParameter()).isFalse();
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::name).containsExactly("p1", "p2");
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::hasDefaultValue).containsExactly(false, true);
    assertThat(functionSymbol.parameters()).extracting(FunctionSymbol.Parameter::isKeywordOnly).containsExactly(false, true);
    functionSymbol = PythonTestUtils.functionSymbol("def fn((p1,p2,p3)): pass");
    assertThat(functionSymbol.parameters()).hasSize(1);
    assertThat(functionSymbol.parameters().get(0).name()).isNull();
    assertThat(functionSymbol.parameters().get(0).hasDefaultValue()).isFalse();
    assertThat(functionSymbol.parameters().get(0).isKeywordOnly()).isFalse();
    assertThat(functionSymbol.parameters().get(0).isVariadic()).isFalse();
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1: int): pass");
    assertThat(functionSymbol.parameters().get(0).declaredType().canBeOrExtend("int")).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("def fn(**kwargs): pass");
    assertThat(functionSymbol.parameters()).hasSize(1);
    assertThat(functionSymbol.hasVariadicParameter()).isTrue();
    assertThat(functionSymbol.parameters().get(0).name()).isEqualTo("kwargs");
    assertThat(functionSymbol.parameters().get(0).hasDefaultValue()).isFalse();
    assertThat(functionSymbol.parameters().get(0).isKeywordOnly()).isFalse();
    assertThat(functionSymbol.parameters().get(0).isVariadic()).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("def fn(p1, *args): pass");
    assertThat(functionSymbol.hasVariadicParameter()).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("@something\ndef fn(p1, *args): pass");
    assertThat(functionSymbol.hasDecorators()).isTrue();
    List<String> decorators = functionSymbol.decorators();
    assertThat(decorators).hasSize(1);
    assertThat(decorators.get(0)).isEqualTo("something");
    functionSymbol = PythonTestUtils.functionSymbol("@something[\"else\"]\ndef fn(p1, *args): pass");
    assertThat(functionSymbol.hasDecorators()).isTrue();
    decorators = functionSymbol.decorators();
    assertThat(decorators).isEmpty();
    assertThat(functionSymbol.isInstanceMethod()).isFalse();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  def method(self, p1): pass");
    assertThat(functionSymbol.isInstanceMethod()).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  def method(*args, p1): pass");
    assertThat(functionSymbol.isInstanceMethod()).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  @staticmethod\n  def method((a, b), c): pass");
    assertThat(functionSymbol.isInstanceMethod()).isFalse();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  @staticmethod\n  def method(p1, p2): pass");
    assertThat(functionSymbol.isInstanceMethod()).isFalse();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  @classmethod\n  def method(self, p1): pass");
    assertThat(functionSymbol.isInstanceMethod()).isFalse();
    assertThat(functionSymbol.hasDecorators()).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  @dec\n  def method(self, p1): pass");
    assertThat(functionSymbol.isInstanceMethod()).isTrue();
    assertThat(functionSymbol.hasDecorators()).isTrue();
    functionSymbol = PythonTestUtils.functionSymbol("class A:\n  @some[\"thing\"]\n  def method(self, p1): pass");
    assertThat(functionSymbol.isInstanceMethod()).isTrue();
    assertThat(functionSymbol.hasDecorators()).isTrue();
}
Also used : FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) Test(org.junit.Test)

Example 4 with FunctionSymbol

use of org.sonar.plugins.python.api.symbols.FunctionSymbol in project sonar-python by SonarSource.

the class FunctionSymbolTest method locations.

@Test
public void locations() {
    PythonFile foo = PythonTestUtils.pythonFile("foo");
    FunctionSymbol functionSymbol = PythonTestUtils.functionSymbol(foo, "def foo(param1, param2): ...");
    assertThat(functionSymbol.parameters().get(0).location()).isEqualToComparingFieldByField(new LocationInFile(pathOf(foo).toString(), 1, 8, 1, 14));
    assertThat(functionSymbol.parameters().get(1).location()).isEqualToComparingFieldByField(new LocationInFile(pathOf(foo).toString(), 1, 16, 1, 22));
    assertThat(functionSymbol.definitionLocation()).isEqualToComparingFieldByField(new LocationInFile(pathOf(foo).toString(), 1, 4, 1, 7));
    functionSymbol = PythonTestUtils.functionSymbol(foo, "def foo(*param1): ...");
    assertThat(functionSymbol.parameters().get(0).location()).isEqualToComparingFieldByField(new LocationInFile(pathOf(foo).toString(), 1, 8, 1, 15));
    functionSymbol = PythonTestUtils.functionSymbol(foo, "def foo((a, b)): ...");
    assertThat(functionSymbol.parameters().get(0).location()).isEqualToComparingFieldByField(new LocationInFile(pathOf(foo).toString(), 1, 8, 1, 14));
    FileInput fileInput = parse(new SymbolTableBuilder(foo), "all([1,2,3])");
    CallExpression callExpression = (CallExpression) PythonTestUtils.getAllDescendant(fileInput, t -> t.is(Tree.Kind.CALL_EXPR)).get(0);
    FunctionSymbol builtinFunctionSymbol = (FunctionSymbol) callExpression.calleeSymbol();
    assertThat(builtinFunctionSymbol.definitionLocation()).isNull();
    assertThat(builtinFunctionSymbol.parameters().get(0).location()).isNull();
}
Also used : FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) LocationInFile(org.sonar.plugins.python.api.LocationInFile) FileInput(org.sonar.plugins.python.api.tree.FileInput) PythonFile(org.sonar.plugins.python.api.PythonFile) CallExpression(org.sonar.plugins.python.api.tree.CallExpression) Test(org.junit.Test)

Example 5 with FunctionSymbol

use of org.sonar.plugins.python.api.symbols.FunctionSymbol in project sonar-python by SonarSource.

the class ClassSymbolImplTest method from_protobuf_instance_method.

@Test
public void from_protobuf_instance_method() throws TextFormat.ParseException {
    String protobuf = "name: \"A\"\n" + "fully_qualified_name: \"mod.A\"\n" + "super_classes: \"builtins.object\"\n" + "methods {\n" + "  name: \"foo\"\n" + "  fully_qualified_name: \"mod.A.foo\"\n" + "  parameters {\n" + "    name: \"self\"\n" + "    kind: POSITIONAL_OR_KEYWORD\n" + "  }\n" + "  has_decorators: true\n" + "}";
    ClassSymbolImpl classSymbol = new ClassSymbolImpl(classSymbol(protobuf), "mod");
    FunctionSymbol foo = (FunctionSymbol) classSymbol.declaredMembers().iterator().next();
    assertThat(foo.isInstanceMethod()).isTrue();
}
Also used : FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) Test(org.junit.Test)

Aggregations

FunctionSymbol (org.sonar.plugins.python.api.symbols.FunctionSymbol)30 Symbol (org.sonar.plugins.python.api.symbols.Symbol)16 ClassSymbol (org.sonar.plugins.python.api.symbols.ClassSymbol)15 Test (org.junit.Test)13 CallExpression (org.sonar.plugins.python.api.tree.CallExpression)10 FunctionDef (org.sonar.plugins.python.api.tree.FunctionDef)8 FileInput (org.sonar.plugins.python.api.tree.FileInput)7 List (java.util.List)6 AmbiguousSymbol (org.sonar.plugins.python.api.symbols.AmbiguousSymbol)6 ClassDef (org.sonar.plugins.python.api.tree.ClassDef)6 HasSymbol (org.sonar.plugins.python.api.tree.HasSymbol)6 Tree (org.sonar.plugins.python.api.tree.Tree)6 TreeUtils (org.sonar.python.tree.TreeUtils)6 Rule (org.sonar.check.Rule)5 PythonSubscriptionCheck (org.sonar.plugins.python.api.PythonSubscriptionCheck)5 Argument (org.sonar.plugins.python.api.tree.Argument)5 Name (org.sonar.plugins.python.api.tree.Name)5 RegularArgument (org.sonar.plugins.python.api.tree.RegularArgument)5 Optional (java.util.Optional)4 Collectors (java.util.stream.Collectors)4