Search in sources :

Example 6 with ClassSymbol

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

the class InstanceAndClassMethodsAtLeastOnePositionalCheck method handleFunctionDef.

private static void handleFunctionDef(SubscriptionContext ctx, ClassDef classDef, FunctionDef functionDef) {
    List<Parameter> parameters = TreeUtils.positionalParameters(functionDef);
    if (!parameters.isEmpty()) {
        return;
    }
    ClassSymbol classSymbol = TreeUtils.getClassSymbolFromDef(classDef);
    if (classSymbol == null || classSymbol.isOrExtends("zope.interface.Interface")) {
        return;
    }
    FunctionSymbol functionSymbol = TreeUtils.getFunctionSymbolFromDef(functionDef);
    if (functionSymbol == null || functionSymbol.usages().stream().anyMatch(usage -> isUsageInClassBody(usage, classDef))) {
        return;
    }
    List<String> decoratorNames = functionDef.decorators().stream().map(decorator -> TreeUtils.decoratorNameFromExpression(decorator.expression())).filter(Objects::nonNull).collect(Collectors.toList());
    if (decoratorNames.contains("staticmethod")) {
        return;
    }
    String name = functionSymbol.name();
    if (KNOWN_CLASS_METHODS.contains(name) || decoratorNames.contains("classmethod")) {
        ctx.addIssue(functionDef.defKeyword(), functionDef.rightPar(), "Add a class parameter");
    } else {
        ctx.addIssue(functionDef.defKeyword(), functionDef.rightPar(), "Add a \"self\" or class parameter");
    }
}
Also used : Arrays(java.util.Arrays) Usage(org.sonar.plugins.python.api.symbols.Usage) PythonSubscriptionCheck(org.sonar.plugins.python.api.PythonSubscriptionCheck) SubscriptionContext(org.sonar.plugins.python.api.SubscriptionContext) FunctionDef(org.sonar.plugins.python.api.tree.FunctionDef) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Collectors(java.util.stream.Collectors) ClassDef(org.sonar.plugins.python.api.tree.ClassDef) TreeUtils(org.sonar.python.tree.TreeUtils) Objects(java.util.Objects) List(java.util.List) Name(org.sonar.plugins.python.api.tree.Name) Tree(org.sonar.plugins.python.api.tree.Tree) Rule(org.sonar.check.Rule) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) Parameter(org.sonar.plugins.python.api.tree.Parameter) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Parameter(org.sonar.plugins.python.api.tree.Parameter)

Example 7 with ClassSymbol

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

the class ClassSymbolImpl method resolveMember.

@Override
public Optional<Symbol> resolveMember(String memberName) {
    for (Symbol symbol : allSuperClasses(false)) {
        if (symbol.kind() == Kind.CLASS) {
            ClassSymbolImpl classSymbol = (ClassSymbolImpl) symbol;
            Symbol matchingMember = classSymbol.membersByName().get(memberName);
            if (matchingMember != null) {
                return Optional.of(matchingMember);
            }
        }
    }
    return Optional.empty();
}
Also used : AmbiguousSymbol(org.sonar.plugins.python.api.symbols.AmbiguousSymbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Symbol(org.sonar.plugins.python.api.symbols.Symbol)

Example 8 with ClassSymbol

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

the class ClassSymbolImpl method canHaveMember.

@Override
public boolean canHaveMember(String memberName) {
    if (hasUnresolvedTypeHierarchy() || hasSuperClassWithUnknownMetaClass()) {
        return true;
    }
    for (Symbol symbol : allSuperClasses(true)) {
        if (symbol.kind() == Kind.CLASS) {
            ClassSymbolImpl classSymbol = (ClassSymbolImpl) symbol;
            Symbol matchingMember = classSymbol.membersByName().get(memberName);
            if (matchingMember != null) {
                return true;
            }
        }
    }
    return false;
}
Also used : AmbiguousSymbol(org.sonar.plugins.python.api.symbols.AmbiguousSymbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Symbol(org.sonar.plugins.python.api.symbols.Symbol)

Example 9 with ClassSymbol

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

the class SymbolTableBuilder method getAlternativeDefinitions.

private Set<Symbol> getAlternativeDefinitions(Symbol symbol, List<Usage> bindingUsages) {
    Set<Symbol> alternativeDefinitions = new HashSet<>();
    for (Usage bindingUsage : bindingUsages) {
        switch(bindingUsage.kind()) {
            case FUNC_DECLARATION:
                FunctionDef functionDef = (FunctionDef) bindingUsage.tree().parent();
                FunctionSymbolImpl functionSymbol = new FunctionSymbolImpl(functionDef, symbol.fullyQualifiedName(), pythonFile);
                ((FunctionDefImpl) functionDef).setFunctionSymbol(functionSymbol);
                alternativeDefinitions.add(functionSymbol);
                break;
            case CLASS_DECLARATION:
                ClassDef classDef = (ClassDef) bindingUsage.tree().parent();
                ClassSymbolImpl classSymbol = new ClassSymbolImpl(classDef, symbol.fullyQualifiedName(), pythonFile);
                resolveTypeHierarchy(classDef, classSymbol, pythonFile, scopesByRootTree.get(fileInput).symbolsByName);
                Scope classScope = scopesByRootTree.get(classDef);
                classSymbol.addMembers(getClassMembers(classScope.symbolsByName, classScope.instanceAttributesByName));
                alternativeDefinitions.add(classSymbol);
                break;
            default:
                SymbolImpl alternativeSymbol = new SymbolImpl(symbol.name(), symbol.fullyQualifiedName());
                alternativeDefinitions.add(alternativeSymbol);
        }
    }
    return alternativeDefinitions;
}
Also used : Usage(org.sonar.plugins.python.api.symbols.Usage) ClassDef(org.sonar.plugins.python.api.tree.ClassDef) HasSymbol(org.sonar.plugins.python.api.tree.HasSymbol) AmbiguousSymbol(org.sonar.plugins.python.api.symbols.AmbiguousSymbol) FunctionSymbol(org.sonar.plugins.python.api.symbols.FunctionSymbol) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Symbol(org.sonar.plugins.python.api.symbols.Symbol) FunctionDefImpl(org.sonar.python.tree.FunctionDefImpl) FunctionDef(org.sonar.plugins.python.api.tree.FunctionDef) HashSet(java.util.HashSet)

Example 10 with ClassSymbol

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

the class DuplicatedMethodFieldNamesCheck method initialize.

@Override
public void initialize(Context context) {
    context.registerSyntaxNodeConsumer(Tree.Kind.CLASSDEF, ctx -> {
        ClassDef classDef = (ClassDef) ctx.syntaxNode();
        ClassSymbol classSymbol = TreeUtils.getClassSymbolFromDef(classDef);
        if (classSymbol == null) {
            return;
        }
        MethodVisitor methodVisitor = new MethodVisitor();
        classDef.body().accept(methodVisitor);
        List<Tree> fieldNames = classSymbol.declaredMembers().stream().filter(s -> s.kind() == Symbol.Kind.OTHER).map(s -> s.usages().stream().findFirst()).filter(Optional::isPresent).map(usage -> usage.get().tree()).collect(Collectors.toList());
        lookForDuplications(ctx, fieldNames, methodVisitor.methodNames);
    });
}
Also used : PythonSubscriptionCheck(org.sonar.plugins.python.api.PythonSubscriptionCheck) SubscriptionContext(org.sonar.plugins.python.api.SubscriptionContext) FunctionDef(org.sonar.plugins.python.api.tree.FunctionDef) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Collectors(java.util.stream.Collectors) ClassDef(org.sonar.plugins.python.api.tree.ClassDef) ArrayList(java.util.ArrayList) TreeUtils(org.sonar.python.tree.TreeUtils) List(java.util.List) Optional(java.util.Optional) Tree(org.sonar.plugins.python.api.tree.Tree) Rule(org.sonar.check.Rule) BaseTreeVisitor(org.sonar.plugins.python.api.tree.BaseTreeVisitor) Comparator(java.util.Comparator) LinkedList(java.util.LinkedList) Symbol(org.sonar.plugins.python.api.symbols.Symbol) ClassDef(org.sonar.plugins.python.api.tree.ClassDef) Optional(java.util.Optional) ClassSymbol(org.sonar.plugins.python.api.symbols.ClassSymbol) Tree(org.sonar.plugins.python.api.tree.Tree)

Aggregations

ClassSymbol (org.sonar.plugins.python.api.symbols.ClassSymbol)87 Test (org.junit.Test)64 Symbol (org.sonar.plugins.python.api.symbols.Symbol)55 AmbiguousSymbol (org.sonar.plugins.python.api.symbols.AmbiguousSymbol)48 FileInput (org.sonar.plugins.python.api.tree.FileInput)36 FunctionSymbol (org.sonar.plugins.python.api.symbols.FunctionSymbol)29 ClassDef (org.sonar.plugins.python.api.tree.ClassDef)29 ClassSymbolImpl (org.sonar.python.semantic.ClassSymbolImpl)13 HashMap (java.util.HashMap)11 HashSet (java.util.HashSet)11 Set (java.util.Set)11 List (java.util.List)10 Map (java.util.Map)10 Collectors (java.util.stream.Collectors)10 SymbolImpl (org.sonar.python.semantic.SymbolImpl)9 Collections (java.util.Collections)7 HasSymbol (org.sonar.plugins.python.api.tree.HasSymbol)7 InferredType (org.sonar.plugins.python.api.types.InferredType)7 Arrays (java.util.Arrays)6 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)6