-
Notifications
You must be signed in to change notification settings - Fork 199
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
[Swift] Add first piece of rule reduction #2692
Conversation
var symbol = "_$ThisIsJustGarbage"; | ||
var demangler = new Swift5Demangler (symbol); | ||
var result = demangler.Run (); | ||
var err = result as ReductionError; |
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 is expected to happen if we would instead do result as ProtocolWitnessTableReduction
? I
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 would think that in non-test code you would always switch on the type or check for a null result after the cast. result as ProtocolWitnessTableReduction
should return null
if result
is of the ReductionError
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.
It would absolutely return null. The test is there to ensure that a symbol that is obviously not a Swift mangled symbol will correctly generate an error. Anything other cast will fail.
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.
Thanks a lot for the great descriptions, it helps a lot in understanding the PR.
Good point on future work to make the BuildMatchRules
static #2691 (maybe we could include it as part of this PR already but unsure if there are some hidden obstacles that would make it too complex)
/// </summary> | ||
internal class MatchRule { | ||
/// <summary> | ||
/// The name of this rule - usefule for debugging |
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 name of this rule - usefule for debugging | |
/// The name of this rule - useful for debugging |
/// <exception cref="InvalidOperationException"></exception> | ||
bool ContentMatches(Node n) | ||
{ | ||
// Only care about the content type not its value |
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.
Shouldn't we rename it to ContentTypeMatches
if we only care about the content type?
/// - One or more NodeKinds to match | ||
/// If a match occurs, a reducer function can be run on the node. | ||
/// </summary> | ||
internal class MatchRule { |
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.
Do you think it would be beneficial to ask someone from the Roslyn team to review this (and maybe the previously introduced Parser)?
I think this is an area commonly found in the frontend of compilers and they may have some interesting insights for us if we plan to grow this further.
/// Creates a simple string representation of this rule | ||
/// </summary> | ||
/// <returns></returns> | ||
public override string ToString() => Name; |
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.
Wouold it help to have a DebuggerDisplayAttribute that surfaces this value?
/// </summary> | ||
string ExpectedButGot (string expected, string butGot) | ||
{ | ||
return $"Demangling {mangledName}: expected {expected} but got {butGot}"; |
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.
Where do these strings surface? Should they be localized?
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.
Eventually, they should be localized. I'm not concerned with that right now. However, putting the very common "Expected but got" pattern in one place makes that easier down the road.
/// Returns a string representation of the function | ||
/// </summary> | ||
/// <returns></returns> | ||
public override string ToString () => $"{Provenance}.{Name}{ParameterList} -> {Return}"; |
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.
Again, any usefulness in having a DebuggerDisplayAttribute?
var symbol = "_$ThisIsJustGarbage"; | ||
var demangler = new Swift5Demangler (symbol); | ||
var result = demangler.Run (); | ||
var err = result as ReductionError; |
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 would think that in non-test code you would always switch on the type or check for a null result after the cast. result as ProtocolWitnessTableReduction
should return null
if result
is of the ReductionError
type
/// <summary> | ||
/// Represents the origin of a particular function | ||
/// </summary> | ||
public class Provenance { |
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.
Isn't this the same property as public required BaseDecl? ParentDecl { get; 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.
BaseDecl, IIRC is a C# representation not a Swift declaration. Further, extensions make this more complicated because you can have multiple extension on the same type from difference modules.
/// Represents a Swift function signature and its provenance. | ||
/// </summary> | ||
[DebuggerDisplay("{ToString()}")] | ||
public class SwiftFunction { |
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 can't we utilize MethodDecl and it's members instead?
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.
See above. This is strictly Swift not C#.
This PR adds demangling tree reduction to the project.
What does this mean?
When a symbol is demangled there is an intermediate state where there is a tree of Node which represent the semantic meaning of the symbol. In order for this to be useful to us, we need to reduce a tree of Node to a more directly accessible set of types.
To do this, there are 3 main pieces:
MatchRule
This PR partially addresses issue 2664.
What happens: given a
Swift5Demangler
instance, callingRun
with a symbol returns anIReduction
that represents the result of the reduction. Right now, we're only ever instantiating either aProtocolWitnessTableReduction
,TypeSpec
or aReductionError
, but I created placeholder for functions which will help enable dispatch thunks later.Inner types will not work yet - issue opened here.
The reduction rules are non-static and the collection gets rebuilt for every symbol. This is known.
There is a name argument in the rule which is not used (yet). I'm trying to decide still if we're going to need it.
MatchRule is very flexible - it can do the simplest matching on a single
Node.Kind
but it can also match on multiples as well. It can match on child nodes too. Overall, this is a simplified version of a regular expression in a way. Nothing in the current code requires it, but we will need it for more complicated reductions later (thunks, for example).Where this is going: we should be able to get all the protocol witness table symbols from a file with a single expression:
Similar expressions could be used to get all the dispatch thunks etc.