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");
}
}
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();
}
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;
}
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;
}
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);
});
}
Aggregations