-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Added “SemanticModel.WithSuppressAccessChecks” extension method. #26
Conversation
@@ -63,6 +63,16 @@ public SyntaxTree SyntaxTree | |||
protected abstract SyntaxTree SyntaxTreeCore { get; } | |||
|
|||
/// <summary> | |||
/// Returns true if this is a SemanticModel that ignores accessibility rules when answering semantic questions. | |||
/// </summary> | |||
public bool IsSuppressingAccessChecks { get; protected set; } |
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.
The setter should be internal.
/// <summary> | ||
/// Creates a SemanticModel that ignores accessibility rules when answering semantic questions. | ||
/// </summary> | ||
public abstract SemanticModel WithSuppressAccessChecks(); |
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'd much rather expose this as a new optional parameter added to the existing Compilation.GetSemanticModel overloads which takes a Boolean flag for whether accessibility checks should be suppressed for the purpose of lookup which defaults to false. I suggest bool suppressAccessChecks = false.
Thanks a lot for the feedback, @AnthonyDGreen. That's indeed a much cleaner solution. Fixed. |
Note that this fixes #378 |
@tmat, @KevinH-MS, @cston, @ManishJayaswal, does this aid or address any debugging/REPL scenarios that also require bypassing access checks in the SemanticModel? |
A debugging scenario is freer with accessibility than the REPL scenarios we've discussed. One REPL scenario discussed was to have an option that allowed the REPL or script code to access internals as if internals-visible-to had been set. Note, a REPL might eventually be used in a debugging scenario, so this could come in to play for that. Note, these REPL scenarios require more than just a binder modification, they need a runtime change. |
@OmerRaviv Can you please "sign" a contributor's agreement starting at https://cla.dotnetfoundation.org/ |
@gafter I've signed the dotnetfoundation CLA on the 18th of January using the email address that's associated with my GitHub account, omerraviv@gmail.com, and got the approval the next day. |
@@ -2747,6 +2748,13 @@ internal Conversion ClassifyConversionForCast(int position, ExpressionSyntax exp | |||
/// <param name="typeParameter"></param> | |||
public abstract ITypeParameterSymbol GetDeclaredSymbol(TypeParameterSyntax typeParameter, CancellationToken cancellationToken = default(CancellationToken)); | |||
|
|||
protected BinderFlags GetSemanticModelBinderFlags() |
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.
This should be internal, not protected, as it should not be part of the publicly visible API.
This pull request failed its automatic merge and test. Please re-merge with the latest and resubmit the pull request. |
Calling GetSemanticModel with suppressAccessChecks=true creates a SemanticModel that ignores accessibility rules when answering semantic questions. This allows consumers to ask semantic questions using the same semantic rules as the ones used in debugger’s Expression Evaluator, where accessibility rules do not matter. Added unit tests for C# and VB.NET to cover both regular and speculative analysis.
256fc68
to
f91f779
Compare
@@ -51,6 +51,7 @@ internal abstract class CSharpSemanticModel : SemanticModel | |||
/// </summary> | |||
internal abstract CSharpSyntaxNode Root { get; } | |||
|
|||
|
|||
// Is this node one that could be successfully interrogated by GetSymbolInfo/GetTypeInfo/GetMemberGroup/GetConstantValue? |
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.
Nit: double blank line.
@tmat Since it's just a public API on Compilation, we could have completion use this during debug time. Does this automatically work with Speculative SemanticModels? |
@@ -63,6 +63,14 @@ public SyntaxTree SyntaxTree | |||
protected abstract SyntaxTree SyntaxTreeCore { get; } | |||
|
|||
/// <summary> | |||
/// Returns true if this is a SemanticModel that ignores accessibility rules when answering semantic questions. | |||
/// </summary> | |||
public virtual bool HasAccessChecksSuppressed |
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.
Can we name this SuppressAccessChecks
?
The pattern of SuppressY
is used a number of times in our code base both internally and publically. The pattern of HasYSuppressed
does not appear anywhere I could find though we do have a few occurrences of IsYSuppressed
but they are all methods and internal.
That pattern seems to be more consistent with other public, and even internal, APIs that we expose.
@gafter what do you think?
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.
What about IgnoresAccessibility?
👍 I had one bit of feedback about the choice of API name here. I think Other than that though it looks great! |
SuppressAccessChecks sounds a bit more like a command than a test. @AnthonyDGreen what do you think? |
Merging a couple of comment threads here. The two alternate proposals for name are:
I am fine with either. Both have precedent within the Roslyn code base and fit into existing patterns which was my primary concern. Small nit is I would use |
@rchande Yes, this automatically supports Speculative SemanticModels, see unit tests for proof :) @jaredpar @gafter @AnthonyDGreen I don't really have an opinion regarding naming either way, please let me know once you've reached consensus and I'll change it. |
@jaredpar, I don't think we have that many Boolean flags in the API but in the past I've used "the if test". How does checking the flag look in an if: if (semanticModel.HasAccessChecksSuppressed) { .. }
if (semanticModel.IgnoresAccessibility) { ... }
if (semanticModel.SuppressAccessChecks) { ... } I think either of the first two read better in that context. This is also what leads me to prefer 'ignores' over 'ignore'. We had a similar discussiong when we named ControlFlowAnalysis/DataFlowAnalysis.Succeeded vs Success. If we're applying this inconsistently we should review the various cases holistically. @terrajobst for weigh in on naming. |
@AnthonyDGreen the choice of |
I can't find examples where we use the "singular" except in the imperative sense (of instructing the API to ignore something), such as LookupOptions.IgnoreAccessibility. This property test the setting. |
Here are the cases I could find. Singular:
Plural:
|
The only ones of those that are public are options (commands) to ignore something. |
Internal or not I think we should be consistent. JaredPar from a phone From: Neal Gafter notifications@github.com The only ones of those that are public are options (commands) to ignore something. — |
They're in different contexts. One is a flag on SemanticModel describing a property of the semantic model. The Ignores isn't plural, it's third person singular. I ignore, you ignore, he/she/it ignores. This is the same pattern we use for SemanticModel.IsSpeculativeSemanticModel method (or Object.Equals). I am, you are, he/she/it is. This is a different grammatical context than the parameter which one passes in to GetSemanticModel to cause accessibility to be ignored - ignoreAccessibility. That's describing an action that should be taken (sort of a second person command) and options follow that same convention. The problem is that depending on where the code is written a piece of data will need to be specified or described in different persons. To the person acquiring the SemanticModel it's 2nd - ignoreAccessibility, within the SemanticModel it would be 1st - IgnoreAccessibility, and outside of the SemanticModel it will be in the 3rd - IgnoresAccessibility. Things get even muddier when properties are read-write because getting is usually in the 3rd and setting is usually in the 2nd. We can't even just standardize on one because - Object.Equals is 3rd person, and IsSpeculativeSemanticModel is 3rd person. I'm not even sure what the latter would be in the 1st or 2nd persons - BeSpeculative, Speculate, AmSpeculative, or just Speculative? So which name is used where depends heavily on who the primary consumer is. The parameters and options are primarily commands for someone else (e.g. the Compilation, the parser) and should be written in the 2nd person, and the properties on SemanticModel are primarily attributes that should be written in the 3rd person. I agree that the internal cases should be made consistent if they are in a context where that reasoning applies. |
I am going to accept this pull request as-is and then submit a separate change to rename the public member. Please say something now if that sounds like a bad plan. |
Thanks fine by me. |
Added “SemanticModel.WithSuppressAccessChecks” extension method.
Sorry to be super later but hey -- better late than never :-)
I'm with Jared. Consistency is key. As far as imperative vs. descriptive style goes: we have both. It usually depends on context. In general, it's good to design booleans to make them read nice in if (semanticModel.HasAccessChecksSuppressed) { .. }
if (semanticModel.IgnoresAccessibility) { ... }
if (semanticModel.SuppressAccessChecks) { ... } |
The
WithSupressAccessChecks
method creates a SemanticModel that ignores accessibility rules when answering semantic questions.This allows consumers to ask semantic questions using the same semantic rules as the ones used in debugger’s Expression Evaluator, where accessibility rules do not matter. This API is an absolute necessity for 3rd parties (such as OzCode) who want to create debugger-related productivity tools on top of Roslyn.
Added unit tests for C# and VB.NET to cover both regular and speculative analysis.
fixes #378