Skip to content

Commit

Permalink
SONARPY-2290 Support decorators for FunctionType to descriptors conve…
Browse files Browse the repository at this point in the history
…rter
  • Loading branch information
maksim-grebeniuk-sonarsource committed Nov 4, 2024
1 parent a5e22df commit 44d3051
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ public PythonType convert(ConversionContext ctx, FunctionDescriptor from) {

var decorators = from.decorators()
.stream()
.map(decoratorName -> Stream.of(ctx.moduleFqn(), decoratorName)
.filter(Predicate.not(String::isEmpty))
.collect(Collectors.joining(".")))
.map(ctx.lazyTypesContext()::getOrCreateLazyType)
.map(TypeWrapper::of)
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -36,6 +37,7 @@
import org.sonar.python.types.v2.FunctionType;
import org.sonar.python.types.v2.ParameterV2;
import org.sonar.python.types.v2.PythonType;
import org.sonar.python.types.v2.TypeWrapper;
import org.sonar.python.types.v2.UnionType;
import org.sonar.python.types.v2.UnknownType;

Expand Down Expand Up @@ -87,11 +89,18 @@ private static Descriptor convert(String moduleFqn, String parentFqn, String sym
.map(parameter -> convert(moduleFqn, parameter))
.toList();

var decorators = type.decorators()
.stream()
.map(TypeWrapper::type)
.map(decorator -> typeFqn(moduleFqn, decorator))
.filter(Objects::nonNull)
.toList();

return new FunctionDescriptor(symbolName, symbolFqn(parentFqn, symbolName),
parameters,
type.isAsynchronous(),
type.isInstanceMethod(),
List.of(),
decorators,
type.hasDecorators(),
type.definitionLocation().orElse(null),
null,
Expand Down Expand Up @@ -165,8 +174,8 @@ private static FunctionDescriptor.Parameter convert(String moduleFqn, ParameterV
private static String typeFqn(String moduleFqn, PythonType type) {
if (type instanceof UnknownType.UnresolvedImportType importType) {
return importType.importPath();
} else if (type instanceof ClassType classType) {
return moduleFqn + "." + classType.name();
} else if (type instanceof ClassType || type instanceof FunctionType) {
return moduleFqn + "." + type.name();
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ void resolveStubsWithImportedModuleVariableDescriptor() {
}

@Test
@Disabled("SONARPY-2290")
void importFunctionWithDecorators() {
var projectLevelSymbolTable = new ProjectLevelSymbolTable();
var libTree = parseWithoutSymbols(
Expand All @@ -294,7 +293,6 @@ def foo(): ...
}

@Test
@Disabled("SONARPY-2290")
void importFunctionWithImportedDecorators() {
var projectLevelSymbolTable = new ProjectLevelSymbolTable();
var libTree = parseWithoutSymbols(
Expand All @@ -305,9 +303,9 @@ def lib_decorator(): ...
projectLevelSymbolTable.addModule(libTree, "", pythonFile("lib.py"));
var lib2Tree = parseWithoutSymbols(
"""
import lib
import lib as l
@lib.lib_decorator
@l.lib_decorator
def foo(): ...
"""
);
Expand All @@ -322,7 +320,7 @@ def foo(): ...
);
var fooType = (FunctionType) ((ExpressionStatement) fileInput.statements().statements().get(1)).expressions().get(0).typeV2();
var typeWrapper = (LazyTypeWrapper) fooType.decorators().get(0);
assertThat(typeWrapper.hasImportPath("lib2.lib.lib_decorator")).isTrue();
assertThat(typeWrapper.hasImportPath("lib.lib_decorator")).isTrue();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ void declared_return_type() {

@Test
void decorators() {
// TODO: SONARPY-1772 Handle decorators
FunctionType functionType = functionType("@something\ndef fn(p1, *args): pass");
assertThat(functionType.hasDecorators()).isTrue();

Expand Down

0 comments on commit 44d3051

Please sign in to comment.