28
28
import org .sonar .plugins .python .api .tree .AnyParameter ;
29
29
import org .sonar .plugins .python .api .tree .FunctionDef ;
30
30
import org .sonar .plugins .python .api .tree .Name ;
31
+ import org .sonar .plugins .python .api .tree .Parameter ;
31
32
import org .sonar .plugins .python .api .tree .ParameterList ;
32
33
import org .sonar .plugins .python .api .tree .Token ;
33
34
import org .sonar .plugins .python .api .tree .Tree ;
@@ -58,7 +59,7 @@ public class FunctionTypeBuilder implements TypeBuilder<FunctionType> {
58
59
private static final String CLASS_METHOD_DECORATOR = "classmethod" ;
59
60
private static final String STATIC_METHOD_DECORATOR = "staticmethod" ;
60
61
61
- public FunctionTypeBuilder fromFunctionDef (FunctionDef functionDef , @ Nullable String fileId ) {
62
+ public FunctionTypeBuilder fromFunctionDef (FunctionDef functionDef , @ Nullable String fileId , ProjectLevelTypeTable projectLevelTypeTable ) {
62
63
this .name = functionDef .name ().name ();
63
64
this .attributes = new ArrayList <>();
64
65
this .parameters = new ArrayList <>();
@@ -67,7 +68,7 @@ public FunctionTypeBuilder fromFunctionDef(FunctionDef functionDef, @Nullable St
67
68
isInstanceMethod = isInstanceMethod (functionDef );
68
69
ParameterList parameterList = functionDef .parameters ();
69
70
if (parameterList != null ) {
70
- createParameterNames (parameterList .all (), fileId );
71
+ createParameterNames (parameterList .all (), fileId , projectLevelTypeTable );
71
72
}
72
73
return this ;
73
74
}
@@ -143,30 +144,30 @@ public FunctionTypeBuilder withOwner(PythonType owner) {
143
144
return this ;
144
145
}
145
146
146
- private void createParameterNames (List <AnyParameter > parameterTrees , @ Nullable String fileId ) {
147
+ private void createParameterNames (List <AnyParameter > parameterTrees , @ Nullable String fileId , ProjectLevelTypeTable projectLevelTypeTable ) {
147
148
ParameterState parameterState = new ParameterState ();
148
149
parameterState .positionalOnly = parameterTrees .stream ().anyMatch (param -> Optional .of (param )
149
150
.filter (p -> p .is (Tree .Kind .PARAMETER ))
150
- .map (p -> ((org . sonar . plugins . python . api . tree . Parameter ) p ).starToken ())
151
+ .map (p -> ((Parameter ) p ).starToken ())
151
152
.map (Token ::value )
152
153
.filter ("/" ::equals )
153
154
.isPresent ()
154
155
);
155
156
for (AnyParameter anyParameter : parameterTrees ) {
156
157
if (anyParameter .is (Tree .Kind .PARAMETER )) {
157
- addParameter ((org . sonar . plugins . python . api . tree . Parameter ) anyParameter , fileId , parameterState );
158
+ addParameter ((Parameter ) anyParameter , fileId , parameterState , projectLevelTypeTable );
158
159
} else {
159
160
parameters .add (new ParameterV2 (null , new SimpleTypeWrapper (PythonType .UNKNOWN ), false ,
160
161
parameterState .keywordOnly , parameterState .positionalOnly , false , false , locationInFile (anyParameter , fileId )));
161
162
}
162
163
}
163
164
}
164
165
165
- private void addParameter (org . sonar . plugins . python . api . tree . Parameter parameter , @ Nullable String fileId , ParameterState parameterState ) {
166
+ private void addParameter (Parameter parameter , @ Nullable String fileId , ParameterState parameterState , ProjectLevelTypeTable projectLevelTypeTable ) {
166
167
Name parameterName = parameter .name ();
167
168
Token starToken = parameter .starToken ();
168
169
if (parameterName != null ) {
169
- ParameterType parameterType = getParameterType (parameter );
170
+ ParameterType parameterType = getParameterType (parameter , projectLevelTypeTable );
170
171
this .parameters .add (new ParameterV2 (parameterName .name (), new LazyTypeWrapper (parameterType .pythonType ()), parameter .defaultValue () != null ,
171
172
parameterState .keywordOnly , parameterState .positionalOnly , parameterType .isKeywordVariadic (), parameterType .isPositionalVariadic (), locationInFile (parameter , fileId )));
172
173
if (starToken != null ) {
@@ -185,26 +186,28 @@ private void addParameter(org.sonar.plugins.python.api.tree.Parameter parameter,
185
186
}
186
187
}
187
188
188
- private ParameterType getParameterType (org . sonar . plugins . python . api . tree . Parameter parameter ) {
189
+ private ParameterType getParameterType (Parameter parameter , ProjectLevelTypeTable projectLevelTypeTable ) {
189
190
boolean isPositionalVariadic = false ;
190
191
boolean isKeywordVariadic = false ;
191
192
Token starToken = parameter .starToken ();
193
+ var parameterType = Optional .ofNullable (parameter .name ()).map (Name ::typeV2 ).orElse (PythonType .UNKNOWN );
192
194
if (starToken != null ) {
193
195
// https://docs.python.org/3/reference/compound_stmts.html#function-definitions
194
196
hasVariadicParameter = true ;
195
197
if ("*" .equals (starToken .value ())) {
196
198
// if the form “*identifier” is present, it is initialized to a tuple receiving any excess positional parameters
197
199
isPositionalVariadic = true ;
198
200
// Should set PythonType to TUPLE
201
+ parameterType = projectLevelTypeTable .getBuiltinsModule ().resolveMember ("tuple" ).orElse (PythonType .UNKNOWN );
199
202
}
200
203
if ("**" .equals (starToken .value ())) {
201
204
// If the form “**identifier” is present, it is initialized to a new ordered mapping receiving any excess keyword arguments
202
205
isKeywordVariadic = true ;
203
206
// Should set PythonType to DICT
207
+ parameterType = projectLevelTypeTable .getBuiltinsModule ().resolveMember ("dict" ).orElse (PythonType .UNKNOWN );
204
208
}
205
209
}
206
- // TODO: SONARPY-1773 handle parameter declared types
207
- return new ParameterType (PythonType .UNKNOWN , isKeywordVariadic , isPositionalVariadic );
210
+ return new ParameterType (parameterType , isKeywordVariadic , isPositionalVariadic );
208
211
}
209
212
210
213
public static class ParameterState {
0 commit comments