-
Notifications
You must be signed in to change notification settings - Fork 1.9k
C#: Only extract public and protected members from metadata. #18159
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
Conversation
662f21c to
129b85c
Compare
129b85c to
a09262b
Compare
I think this sounds overall like a (great) win, as DCA also confirms. The changes in results for |
|
I vaguely remember that we started extracting We needed these additional symbols when stubbing the .net framework, but I don't remember any longer for which API. The below might or might not be the case that caused the problem. I think when the below was extracted into a DB without It might not be a problem any longer for the stub generator, in which case the |
Thank you for the historical perspective! That makes sense. |
|
One additional thing to consider: not extracting private fields can have an impact on MaD rows that use |
|
The QA run on 5k repos shows The following looks very good: Faster extraction, faster trap import, faster query execution. Roughly 10% across the line and an 8% end-to-end performance improvement! Link to QA dashboard: https://github.com/github/codeql-qa-ops/issues/240#issuecomment-2513329387 |
That is a good point as well. It appears that all the models we only use effectively public fields on dotnet/runtime: This makes sense as the only manual models we have that uses |
hvitved
left a comment
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, very nice speedup, just a single question.
| } | ||
| if (symbol is IMethodSymbol method) | ||
| { | ||
| return method.ExplicitInterfaceImplementations.Any(m => m.ContainingType.DeclaredAccessibility == Accessibility.Public); |
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.
Should this be m => m.ContainingType.ShouldExtractSymbol() instead? Otherwise, I don't think we'll extract the implementation of M in
interface I {
void M();
}
public class C {
protected class Nested : I {
void I.M() {}
}
}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.
Yes, you are absolutely right!
| } | ||
| if (symbol is IPropertySymbol property) | ||
| { | ||
| return property.ExplicitInterfaceImplementations.Any(m => m.ContainingType.DeclaredAccessibility == Accessibility.Public); |
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.
Same
| } | ||
|
|
||
| if (Symbol.BaseType is not null) | ||
| if (Symbol.BaseType is not null && Symbol.BaseType.ShouldExtractSymbol()) |
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.
Is this change required? The base type cannot be less accessible than the currently processed type: https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs0060. Is there any case that we're extracting a type without its base type?
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.
At least one of the intermediate solutions that I made required this (even though as you state - this shouldn't be required). I will try to make the suggested modifications on the PR and see if we get any failures.
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.
You are right - this is not required.


In this PR we change how much information we extract from reference assemblies.
Prior to this PR all symbols (also private an internal) were extracted from the reference assemblies even though not all of them are accessible outside the assemblies (e.g. it is not possible to call a private method outside the assembly).
With this PR, we only extract public and protected members ("effectively" public members and types) from the reference assemblies.
There is one identified drawback with this approach, which was identified by DCA:
InternalsVisible(in this case internals from Microsoft.Management.Infrastructure are made accessible toSystem.Management.Automation, which is declared in the powershell project).Making solutions in production code using
InternalsVisiblein an anti-pattern (note that we only get an issue in case internals are in reference assemblies). Furthermore, the "increase" in the number of missing call targets and expressions with unknown types for the buildless extractions are negligible.The advantages are
DCA doesn't show any alert changes to the security related queries.
IMO the advantages outweigh the drawbacks.
@hvitved @tamasvajk : What do you think?