Make parser recognize AliasAssign#441
Conversation
|
Test suite is failing with "All tests have passed". |
src/dparse/parser.d
Outdated
| /** | ||
| * Parses an AliasAssign. | ||
| * | ||
| * $(GRAMMAR $(RULEDEF aliasDeclaration): |
There was a problem hiding this comment.
| * $(GRAMMAR $(RULEDEF aliasDeclaration): | |
| * $(GRAMMAR $(RULEDEF aliasAssign): |
WebFreak001
left a comment
There was a problem hiding this comment.
thanks for the PR! Got some points that should be changed
src/dparse/parser.d
Outdated
| mixin(traceEnterAndExit!(__FUNCTION__)); | ||
| auto startIndex = index; | ||
| auto node = allocator.make!AliasAssign; | ||
| node.initializer = parseAliasInitializer(); |
There was a problem hiding this comment.
AliasInitializer allows adding template parameters, are these really supported by alias assign? (as this is a public function that may be called freely - and for good code style)
There was a problem hiding this comment.
Nope. I can implement it properly, but I thought I would just reuse as much code as possible to make the diff smaller.
| * ;) | ||
| */ | ||
| Declaration parseDeclaration(bool strict = false, bool mustBeDeclaration = false) | ||
| Declaration parseDeclaration(bool strict = false, bool mustBeDeclaration = false, bool inTemplateDeclaration = false) |
There was a problem hiding this comment.
are alias assignments only strictly allowed in templates?
Additionally you are missing this parameter in a lot of sub-calls here.
Example that would break as far as I can see:
// parseConditionalDeclaration
static if (true)
{
A = B;
}There was a problem hiding this comment.
If I see a static if (true) in there at release I'm gonna burn down Adam's shed
There was a problem hiding this comment.
As far as I could tell from the implementation [1], AliasAssign is allowed only inside template A(..){...} declarations.
I understand your point, however, it is not possible to deduce whether the static if is at function level or at template level during parsing. In dmd, this is checked during semantic analysis, so I assume that the solution for libdparse is to create an AliasAssignDeclaration every time we encounter an assignment that occurs in non-function contexts. ParseDeclaration seems to be called at function scope level also. Any ideas on how I could differentiate between assignments at function level and assignments non-function levels?
There was a problem hiding this comment.
I think you want to nest the inTemplateDeclaration parameter into all calls that should keep it, ie. here the parseConditionalDeclaration function and all the other parse*Declaration functions you want to support.
I personally think it would be more pretty doing this with some kind of parse state struct that is passed as argument in all related functions though if this is expected to expand in the future to more edge cases.
There was a problem hiding this comment.
I'm not sure this will work. Consider this case:
template X(T)
{
alias X = int;
static if (cond)
X = float; // this one is currently accepted by dmd
void fun()
{
X = T; // while this one is not because the assignment
// does not have the same parent as the declaration of X
}
}This is not going to get solved by passing the inTemplate boolean. Or maybe it could work, but that would mean inserting a primitive form of semantic analysis. Right now, libdparse issues an error when
assignments occur in non-function contexts. If we want to keep things in parser territory, we need to relax that condition and to create AliasAssignDeclarations if an assignment occurs in non-function context. Of course that will allow for code that is not an alias assignment to pass parsing, but that is fine.
There was a problem hiding this comment.
the parseFunctionDeclaration body would reset back the boolean value that you are in a template, (implicitly by simply not passing it down as parameter or for a struct explicitly) you will want to do that with anything adding scope.
There was a problem hiding this comment.
hmm, I'll try that out. Thanks for your assistance!
src/dparse/parser.d
Outdated
| * Parses an AliasAssign. | ||
| * | ||
| * $(GRAMMAR $(RULEDEF aliasAssign): | ||
| * $(RULE aliasInitializer) |
There was a problem hiding this comment.
this documentation says it would be syntactically valid to use templateParameters in an assignment. As it's never the case that it would actually be valid code I think it would be better to define a proper grammar here.
|
@WebFreak001 @maxhaton I gave it another pass. Kindly asking for a review |
WebFreak001
left a comment
There was a problem hiding this comment.
looks good, just 2 minor things
I think the state passing through parameters is functional and works well with the stack without much overhead, but it might get hard to maintain in case more stuff like this gets added. What does @Hackerpilot think about this? Maybe some explicit push/pop functionality could be considered too? (I think the current way would be the most elegant solution once we have named parameters and not need to write down all the defaults)
src/dparse/parser.d
Outdated
| mixin(tokenCheck!(`node.identifier`, "identifier")); | ||
| mixin(tokenCheck!"="); | ||
| mixin (parseNodeQ!(`node.type`, `Type`)); | ||
| node.tokens = tokens[startIndex .. index]; |
There was a problem hiding this comment.
this line is not needed / covered by attachCommentFromSemicolon
| node.tokens = tokens[startIndex .. index]; |
src/dparse/parser.d
Outdated
| comment = null; | ||
| mixin(tokenCheck!(`node.identifier`, "identifier")); | ||
| mixin(tokenCheck!"="); | ||
| mixin (parseNodeQ!(`node.type`, `Type`)); |
There was a problem hiding this comment.
and just a style thing because otherwise the PR LGTM :p
| mixin (parseNodeQ!(`node.type`, `Type`)); | |
| mixin(parseNodeQ!(`node.type`, `Type`)); |
|
@RazvanN7 Don't have time to consider this thoroughly but looks good to me for now. Thanks. |
|
@WebFreak001 I agree that keeping all the state in one place is easier to maintain, however, at this point that might be an overkill. Anyway, I would rather merge this ASAP to unblock the phobos PRs and refactor later if needed. |
|
travis fail unrelated |
|
can't merge because travis is a required check |
|
There seems to be a dependency error on stdx.allocator: How do we get passed that? Did I mention that this PR is needed to unblock phobos :-" ? |
|
Ok, so the problem seems to be that libdparse is using an ancient version of stdx.allocator (2.77.5), whereas newer versions don't even contain the assert that is tripping. How do we fix this? Should travis-ci be upgraded somehow or does it suffice to simply change the tag in Edit: Hmm, do I have to specifically mention all recursive dependencies? It looks like the problem is that meson does not know how to pull mir-core (that the newer version of stdx.allocator requires). |
39cf5ed to
8878047
Compare
|
@WebFreak001 I have disabled the meson build as it seemed redundant. Once the dependency issues for meson are fixed, the tests can be un-commented. Is that acceptable? |
Codecov Report
@@ Coverage Diff @@
## master #441 +/- ##
==========================================
+ Coverage 81.86% 82.12% +0.25%
==========================================
Files 11 11
Lines 8454 8463 +9
==========================================
+ Hits 6921 6950 +29
+ Misses 1533 1513 -20
Continue to review full report at Codecov.
|
|
Is this good to go? |
As per: dlang/dmd#11846
A few notes:
AliasAssignthat is viewed as a declaration so that it could appear in the same context as declarations. This might be a bit hacky, but it seemed like the easiest way to implement this.AliasAssignclass is just a wrapper forAliasInitializer. I considered using anAliasInitializeras that would make the diff smaller, however, that comes with 2 drawbacks: comments cannot be attached toAliasInitializers and it usesAliasInitializerfor a purposes that it wasn't designed for. If the maintainers come to the conclusion that it is better to useAliasInitializer, I am open to amend the PR.parseDeclaration, so that is signaled to the declaration.This is currently blocking some PRs in phobos, so if you merge, please also release a new tag so that we can unblock those PRs.
Cheers,
RazvanN