-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SONARPY-2303 Stop running V1 type inference during the indexing phase #2131
Conversation
20f960f
to
8db40ed
Compare
0be3f9a
to
6e6e789
Compare
6152f29
to
cd4f1a6
Compare
4ca0b3f
to
1759e47
Compare
7fe14fd
to
b6d1e22
Compare
Quality Gate failedFailed conditions See analysis details on SonarQube Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
24cf2b8
to
344bd13
Compare
d3b2340
to
b880c3a
Compare
@@ -59,7 +64,7 @@ public CacheContext cacheContext() { | |||
|
|||
@Beta | |||
public Collection<Symbol> stubFilesSymbols() { | |||
return TypeShed.stubFilesSymbols(); | |||
return projectLevelSymbolTable.typeShedDescriptorsProvider().stubFilesSymbols(projectLevelSymbolTable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I notice it's a bit weird to pass the projectLevelSymbolTable
to the typeShedDescriptorsProvider
when it is itself a part of the projectLevelSymbolTable
. However, given it is code meant to disappear after we finish the removal of the V1 engine, I think it's okay to keep as it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not delegate this method inside the ProjectLevelSymbolTable
to hide it behind the scenes?
* Returns stub symbols to be used by SonarSecurity. | ||
* Ambiguous symbols that only contain class symbols are disambiguated with latest Python version. | ||
*/ | ||
public Collection<Symbol> stubFilesSymbols(ProjectLevelSymbolTable projectLevelSymbolTable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the Descriptors
provider should not operate with the Symbol
model, it should just provide descriptors. The conversion from the descriptor to the symbol model is on the projectLevelSymbolTable
side
default: | ||
throw new IllegalStateException(String.format("Error while creating a Symbol from a Descriptor: Unexpected descriptor kind: %s", descriptor.kind())); | ||
} | ||
} | ||
|
||
private static Descriptor recreateDescriptorFromAlias(AliasDescriptor aliasDescriptor) { | ||
return switch (aliasDescriptor.originalDescriptor().kind()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if replace this kind
switch-case
with just instanceof
if-else
- it will allow to get rid of unsafe class casts in the recreateFunctionDescriptor
and the recreateClassDescriptor
methods like:
private static Descriptor recreateDescriptorFromAlias(AliasDescriptor aliasDescriptor) {
if (aliasDescriptor.originalDescriptor() instanceof FunctionDescriptor functionDescriptor) {
return recreateFunctionDescriptor(aliasDescriptor, functionDescriptor);
} else if (aliasDescriptor.originalDescriptor() instanceof ClassDescriptor classDescriptor) {
return recreateClassDescriptor(aliasDescriptor, classDescriptor);
}
throw new IllegalStateException(String.format("Error while recreating a descriptor from an alias: Unexpected alias kind: %s", aliasDescriptor.kind()));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Great job!!
Thanks for rewriting the git history; it was appreciated for the review.
I left mainly questions but no show-stopper.
I put it back in progress for you to answer them.
var typesBySymbol = typeInferenceV2.inferTypes(fileInput); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
importsByModule.put(fullyQualifiedModuleName, typeInferenceV2.importedModulesFQN()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
python-frontend/src/main/java/org/sonar/python/semantic/v2/BasicTypeTable.java
Show resolved
Hide resolved
...c/main/java/org/sonar/python/semantic/v2/converter/AliasDescriptorToPythonTypeConverter.java
Show resolved
Hide resolved
public Collection<Symbol> stubFilesSymbols(ProjectLevelSymbolTable projectLevelSymbolTable) { | ||
if (cachedSymbols != null) { | ||
return cachedSymbols; | ||
} | ||
Collection<Descriptor> allDescriptors = new ArrayList<>(stubFilesDescriptors()); | ||
allDescriptors.addAll(builtinDescriptors().values()); | ||
record Pair(Symbol symbol, Descriptor descriptor){} | ||
|
||
Map<String, Pair> symbolsByFqn = new HashMap<>(); | ||
cachedSymbols = new HashSet<>(); | ||
|
||
for (Descriptor descriptor : allDescriptors) { | ||
if (descriptor.fullyQualifiedName() != null) { | ||
Pair pair = symbolsByFqn.computeIfAbsent(descriptor.fullyQualifiedName(), k -> | ||
new Pair(DescriptorUtils.symbolFromDescriptor(descriptor, projectLevelSymbolTable, null, new HashMap<>(), new HashMap<>()), descriptor)); | ||
cachedSymbols.add(pair.symbol()); | ||
} | ||
} | ||
return cachedSymbols; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you have to introduce a record here?
public Collection<Symbol> stubFilesSymbols(ProjectLevelSymbolTable projectLevelSymbolTable) { | |
if (cachedSymbols != null) { | |
return cachedSymbols; | |
} | |
Collection<Descriptor> allDescriptors = new ArrayList<>(stubFilesDescriptors()); | |
allDescriptors.addAll(builtinDescriptors().values()); | |
record Pair(Symbol symbol, Descriptor descriptor){} | |
Map<String, Pair> symbolsByFqn = new HashMap<>(); | |
cachedSymbols = new HashSet<>(); | |
for (Descriptor descriptor : allDescriptors) { | |
if (descriptor.fullyQualifiedName() != null) { | |
Pair pair = symbolsByFqn.computeIfAbsent(descriptor.fullyQualifiedName(), k -> | |
new Pair(DescriptorUtils.symbolFromDescriptor(descriptor, projectLevelSymbolTable, null, new HashMap<>(), new HashMap<>()), descriptor)); | |
cachedSymbols.add(pair.symbol()); | |
} | |
} | |
return cachedSymbols; | |
} | |
public Collection<Symbol> stubFilesSymbols(ProjectLevelSymbolTable projectLevelSymbolTable) { | |
if (cachedSymbols != null) { | |
return cachedSymbols; | |
} | |
Collection<Descriptor> allDescriptors = new ArrayList<>(stubFilesDescriptors()); | |
allDescriptors.addAll(builtinDescriptors().values()); | |
Map<String, Symbol> symbolsByFqn = new HashMap<>(); | |
cachedSymbols = new HashSet<>(); | |
for (Descriptor descriptor : allDescriptors) { | |
if (descriptor.fullyQualifiedName() != null) { | |
Symbol symbol = symbolsByFqn.computeIfAbsent(descriptor.fullyQualifiedName(), k -> DescriptorUtils.symbolFromDescriptor(descriptor, projectLevelSymbolTable, null, new HashMap<>(), new HashMap<>())); | |
cachedSymbols.add(symbol); | |
} | |
} | |
return cachedSymbols; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really remember why I needed that in a previous iteration...but certainly I don't anymore, good catch!
sonar-python-plugin/src/main/java/org/sonar/plugins/python/indexer/SonarQubePythonIndexer.java
Show resolved
Hide resolved
python-frontend/src/main/java/org/sonar/python/semantic/ProjectLevelSymbolTable.java
Show resolved
Hide resolved
default: | ||
throw new IllegalStateException(String.format("Error while creating a Symbol from a Descriptor: Unexpected descriptor kind: %s", descriptor.kind())); | ||
} | ||
} | ||
|
||
private static Descriptor recreateDescriptorFromAlias(AliasDescriptor aliasDescriptor) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are no unit tests for this function, especially in the case that the original descriptor is not a class or a function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And actually there was a bug in the logger, as I was logging the type of the AliasDescriptor
instead of the original descriptor, good catch!
6ccfe06
to
ee46413
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Well done 💪 🚀
335718a
to
d01706f
Compare
d01706f
to
bfa085c
Compare
Quality Gate passedIssues Measures |
SONARPY-2303