Implement #warning and #error #14048
Conversation
@swift-ci please smoke test |
This currently doesn't handle directives in the middle of switch statements, a la: switch 4 {
#warning "boo"
default: break
} |
Finally... @harlanhaskins |
@swift-ci please smoke test |
@swift-ci please smoke test |
Printer << tok::pound_warning; | ||
} | ||
|
||
Printer << '"' << PDD->getMessage()->getValue() << '"'; |
harlanhaskins
Feb 2, 2018
Author
Collaborator
Before I forget, I need to add parens to this.
Before I forget, I need to add parens to this.
@swift-ci please smoke test |
@@ -188,6 +188,11 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*, | |||
return false; | |||
} | |||
|
|||
bool visitPoundDiagnosticDecl(PoundDiagnosticDecl *PDD) { | |||
// By default, ignore #erorr/#warning. |
skagedal
Feb 2, 2018
Typo on "erorr" :)
Typo on "erorr" :)
harlanhaskins
Feb 2, 2018
Author
Collaborator
Thanks!
Thanks!
|
||
auto string = parseExprStringLiteral(); | ||
if (string.isNull()) | ||
return makeParserError(); |
jrose-apple
Feb 2, 2018
Contributor
Suggestion: continue looking for a close-paren if it occurs before the end of the line.
Suggestion: continue looking for a close-paren if it occurs before the end of the line.
harlanhaskins
Feb 2, 2018
Author
Collaborator
👍
I originally tried checking for #warning “Foo”
and FixIt-ing in the surrounding parens. Should I continue with that?
I originally tried checking for #warning “Foo”
and FixIt-ing in the surrounding parens. Should I continue with that?
jrose-apple
Feb 2, 2018
Contributor
That's also good, but I'm mostly thinking about #warning(Foo)
and worse #warning(Foo is bad, yanno?)
, where the fix is probably to add quotes.
That's also good, but I'm mostly thinking about #warning(Foo)
and worse #warning(Foo is bad, yanno?)
, where the fix is probably to add quotes.
harlanhaskins
Feb 2, 2018
Author
Collaborator
Also a good idea!
Also a good idea!
@@ -1098,6 +1098,17 @@ namespace { | |||
PrintWithColorRAII(OS, ParenthesisColor) << ')'; | |||
} | |||
|
|||
void visitPoundDiagnosticDecl(PoundDiagnosticDecl *PDD) { | |||
const char *name = PDD->isError() ? | |||
"pound_error_decl" : "pound_warning_decl"; |
jrose-apple
Feb 2, 2018
Contributor
Nitpick: seems like having a common pound_diagnostic_decl
as the kind and then printing an attribute for error vs. warning would be more inline with the other AST nodes.
Nitpick: seems like having a common pound_diagnostic_decl
as the kind and then printing an attribute for error vs. warning would be more inline with the other AST nodes.
harlanhaskins
Feb 2, 2018
Author
Collaborator
👍
@@ -7143,6 +7144,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> { | |||
TC.checkDeclAttributes(ICD); | |||
} | |||
|
|||
void visitPoundDiagnosticDecl(PoundDiagnosticDecl *PDD) { | |||
if (PDD->hasBeenEmitted()) { return; } | |||
PDD->markEmitted(); |
jrose-apple
Feb 2, 2018
Contributor
I suspect this can never happen more than once per phase, so you may be able to get rid of hasBeenEmitted
.
I suspect this can never happen more than once per phase, so you may be able to get rid of hasBeenEmitted
.
harlanhaskins
Feb 2, 2018
Author
Collaborator
I’ll try it and see what happens!
I’ll try it and see what happens!
harlanhaskins
Feb 2, 2018
Author
Collaborator
Turns out it does happen twice. ☹️
Turns out it does happen twice.
switch 34 { | ||
#warning("warnings can be nested in switch statements") // expected-warning {{warnings can be nested in switch statements}} | ||
#if true | ||
#error("errors can be nested in if-configs inside switch statements too") // expected-error {{errors can be nested in if-configs inside switch statements too}} |
jrose-apple
Feb 2, 2018
Contributor
There's a slightly different test where the #error
is immediately after a case.
There's a slightly different test where the #error
is immediately after a case.
jrose-apple
Feb 2, 2018
Contributor
Oops, sorry, I guess that's just part of the body of the case. It's where the #if
is immediately after a case, but contains cases itself.
Oops, sorry, I guess that's just part of the body of the case. It's where the #if
is immediately after a case, but contains cases itself.
harlanhaskins
Feb 2, 2018
Author
Collaborator
Okay, I’ll nest a case inside the existing if config and then put a #error
in there 👍
Okay, I’ll nest a case inside the existing if config and then put a #error
in there
@jrose-apple Okay, this latest commit will fix-it: #warning "foo"
#warning test 123
#warning(test 123) |
@swift-ci please smoke test |
@swift-ci please smoke test |
// Catch #warning(oops, forgot the quotes) | ||
SourceLoc wordsStartLoc = Tok.getLoc(); | ||
|
||
while (!Tok.isAtStartOfLine() && Tok.isNot(tok::r_paren)) { |
jrose-apple
Feb 2, 2018
Contributor
Don't forget to consume the r_paren
!
Don't forget to consume the r_paren
!
harlanhaskins
Feb 2, 2018
Author
Collaborator
Ack! Thanks!
Ack! Thanks!
Could you add check for trailing tokens on the same line? e.g. #warning("foo bar") var x = 1 // expected-error {{extra tokens following warning directive}}
#error("foo bar"); // expected-error {{extra tokens following error directive}} I'm not sure this was discussed, but we don't allow this for any directives so far. |
@swift-ci please smoke test |
Build timed out? @swift-ci please smoke test Linux platform |
This looks fantastic |
|
@@ -157,7 +157,7 @@ syn match swiftOperator "\.\.[<.]" skipwhite nextgroup=swiftTypeParameters | |||
syn match swiftChar /'\([^'\\]\|\\\(["'tnr0\\]\|x[0-9a-fA-F]\{2}\|u[0-9a-fA-F]\{4}\|U[0-9a-fA-F]\{8}\)\)'/ | |||
|
|||
syn match swiftPreproc /#\(\<file\>\|\<line\>\|\<function\>\)/ | |||
syn match swiftPreproc /^\s*#\(\<if\>\|\<else\>\|\<elseif\>\|\<endif\>\)/ | |||
syn match swiftPreproc /^\s*#\(\<if\>\|\<else\>\|\<elseif\>\|\<endif\>\<error\>\|\<warning\>\|\)/ |
natecook1000
Feb 3, 2018
Member
This is what I call fit and finish 💯
This is what I call fit and finish
Is this supported? #warning("""
This is a very long warning \
in a codebase that has 80 \
character line width. ...
""") |
Not in the current implementation, but it absolutely should be. I’ll make a PR with that soon. Thanks for noticing! |
Actually, spoke too soon. Multi line string literals are definitely supported already -- I mistakenly thought they were a different token. |
Hey @harlanhaskins , mind adding a ChangeLog entry for this? |
@DougGregor Submitted as #15110. Thanks for the reminder! |
* Implement #warning and #error * Fix #warning/#error in switch statements * Fix AST printing for #warning/#error * Add to test case * Add extra handling to ParseDeclPoundDiagnostic * fix dumping * Consume the right paren even in the failure case * Diagnose extra tokens on the same line after a diagnostic directive
This PR is an implementation of
#warning
and#error
, whichis currently being pitched to swift-evolutionwas accepted for Swift 5.