From 94bb16ac8307ab8fe5e86f42ca2ce0676e8a7d0f Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Fri, 3 Apr 2020 19:23:05 +0900 Subject: [PATCH 01/12] [Diagnostics] Improve {{none}} fix-it verifier --- lib/Frontend/DiagnosticVerifier.cpp | 95 ++++++++++++++++++------- test/FixCode/verify-fixits.swift | 60 +++++++++++++++- test/FixCode/verify-fixits.swift.result | 62 +++++++++++++++- test/Frontend/verify-fixits.swift | 77 ++++++++++++++++++++ test/diagnostics/verifier.swift | 2 +- 5 files changed, 265 insertions(+), 31 deletions(-) create mode 100644 test/Frontend/verify-fixits.swift diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index 147ec4e163ef..c21a300dae3c 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -547,46 +547,87 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { auto &FoundDiagnostic = *FoundDiagnosticIter; - const char *IncorrectFixit = nullptr; + const char *missedFixitLoc = nullptr; // Verify that any expected fix-its are present in the diagnostic. for (auto fixit : expected.Fixits) { // If we found it, we're ok. - if (!checkForFixIt(fixit, FoundDiagnostic, InputFile)) - IncorrectFixit = fixit.StartLoc; + if (!checkForFixIt(fixit, FoundDiagnostic, InputFile)) { + missedFixitLoc = fixit.StartLoc; + break; + } } - bool matchedAllFixIts = - expected.Fixits.size() == FoundDiagnostic.FixIts.size(); + bool isUnexpectedFixitsSeen = + expected.Fixits.size() < FoundDiagnostic.FixIts.size(); // If we have any expected fixits that didn't get matched, then they are // wrong. Replace the failed fixit with what actually happened. - if (IncorrectFixit) { - if (FoundDiagnostic.FixIts.empty()) { - addError(IncorrectFixit, "expected fix-it not seen"); - } else { - // If we had an incorrect expected fixit, render it and produce a fixit - // of our own. - auto actual = renderFixits(FoundDiagnostic.FixIts, InputFile); - auto replStartLoc = SMLoc::getFromPointer(expected.Fixits[0].StartLoc); - auto replEndLoc = SMLoc::getFromPointer(expected.Fixits.back().EndLoc); - - llvm::SMFixIt fix(llvm::SMRange(replStartLoc, replEndLoc), actual); - addError(IncorrectFixit, - "expected fix-it not seen; actual fix-its: " + actual, fix); + + if (missedFixitLoc || + (expected.noExtraFixitsMayAppear && isUnexpectedFixitsSeen)) { + const char *fixItsStartLoc = missedFixitLoc; + if (!fixItsStartLoc) { + assert(expected.noExtraFixitsMayAppear); + fixItsStartLoc = expected.ExpectedEnd - 8; // {{none}} length } - } else if (expected.noExtraFixitsMayAppear && - !matchedAllFixIts && - !expected.mayAppear) { + + // If we had an incorrect expected fixit, render it and produce a fixit + // of our own. // If there was no fixit specification, but some were produced, add a // fixit to add them in. - auto actual = renderFixits(FoundDiagnostic.FixIts, InputFile); - auto replStartLoc = SMLoc::getFromPointer(expected.ExpectedEnd - 8); // {{none}} length - auto replEndLoc = SMLoc::getFromPointer(expected.ExpectedEnd); + std::string actualFixits; + const char *replStartLoc = nullptr, *replEndLoc = nullptr; + if (!FoundDiagnostic.FixIts.empty()) { + actualFixits = renderFixits(FoundDiagnostic.FixIts, InputFile); + } - llvm::SMFixIt fix(llvm::SMRange(replStartLoc, replEndLoc), actual); - addError(replStartLoc.getPointer(), "expected no fix-its; actual fix-it seen: " + actual, fix); + if (!expected.Fixits.empty()) { + replStartLoc = expected.Fixits.front().StartLoc; + replEndLoc = expected.Fixits.back().EndLoc; + } else { + assert(expected.noExtraFixitsMayAppear); + // insert fix-its before {{none}} + replStartLoc = fixItsStartLoc; + replEndLoc = replStartLoc; + } + + std::string message; + if (missedFixitLoc) { + message = "expected fix-it not seen"; + } else { + assert(expected.noExtraFixitsMayAppear); + if (expected.Fixits.empty()) { + message = "expected no fix-its"; + } else { + message = "unexpected fix-it seen"; + } + } + + if (replStartLoc && replEndLoc) { + if (!actualFixits.empty()) { + message += "; actual fix-it seen: " + actualFixits; + } + + std::string fixRepl = actualFixits; + if (fixRepl.empty()) { + if (replStartLoc[-1] == ' ') { + replStartLoc--; + } + } else { + if (replStartLoc == replEndLoc) { + fixRepl += " "; + } + } + + llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), + SMLoc::getFromPointer(replEndLoc)), + fixRepl); + addError(fixItsStartLoc, message, fix); + } else { + addError(fixItsStartLoc, message); + } } - + // Actually remove the diagnostic from the list, so we don't match it // again. We do have to do this after checking fix-its, though, because // the diagnostic owns its fix-its. diff --git a/test/FixCode/verify-fixits.swift b/test/FixCode/verify-fixits.swift index 81c4943e39a4..96a7b631ee35 100644 --- a/test/FixCode/verify-fixits.swift +++ b/test/FixCode/verify-fixits.swift @@ -6,4 +6,62 @@ func f1() { guard true { return } // expected-error {{...}} guard true { return } // expected-error {{expected 'else' after 'guard' condition}} {{none}} -} \ No newline at end of file +} + +func labeledFunc(aa: Int, bb: Int) {} + +func test0Fixits() { + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} {{2-2=b}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} {{none}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} {{2-2=b}} {{none}} +} + +func test1Fixits() { + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{15-18=xx}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} {{15-18=aa}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{15-18=xx}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} {{15-18=aa}} {{none}} +} + +func test2Fixits() { + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=xx}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=xx}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=xx}} {{none}} +} diff --git a/test/FixCode/verify-fixits.swift.result b/test/FixCode/verify-fixits.swift.result index d6c3324067f7..9518c01360b1 100644 --- a/test/FixCode/verify-fixits.swift.result +++ b/test/FixCode/verify-fixits.swift.result @@ -5,5 +5,63 @@ func f1() { guard true { return } // expected-error {{expected 'else' after 'guard' condition}} - guard true { return } // expected-error {{expected 'else' after 'guard' condition}} {{14-14=else }} -} \ No newline at end of file + guard true { return } // expected-error {{expected 'else' after 'guard' condition}} {{14-14=else }} {{none}} +} + +func labeledFunc(aa: Int, bb: Int) {} + +func test0Fixits() { + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} +} + +func test1Fixits() { + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} +} + +func test2Fixits() { + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} +} diff --git a/test/Frontend/verify-fixits.swift b/test/Frontend/verify-fixits.swift new file mode 100644 index 000000000000..541d12a74a49 --- /dev/null +++ b/test/Frontend/verify-fixits.swift @@ -0,0 +1,77 @@ +// Tests for fix-its on `-verify` mode. + +// RUN: not %target-typecheck-verify-swift 2>&1 | %FileCheck %s + +func labeledFunc(aa: Int, bb: Int) {} + +func test0Fixits() { + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} + + // CHECK: [[@LINE+1]]:86: error: expected fix-it not seen + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} + + // CHECK: [[@LINE+1]]:86: error: expected fix-it not seen + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} {{2-2=b}} + + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} + + // CHECK: [[@LINE+1]]:86: error: expected fix-it not seen + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} {{none}} + + // CHECK: [[@LINE+1]]:86: error: expected fix-it not seen + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{1-1=a}} {{2-2=b}} {{none}} +} + +func test1Fixits() { + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} + + // CHECK: [[@LINE+1]]:121: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} + + // CHECK: [[@LINE+1]]:134: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{15-18=xx}} + + // CHECK: [[@LINE+1]]:121: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} {{15-18=aa}} + + // CHECK: [[@LINE+1]]:121: error: expected no fix-its; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{none}} + + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + // CHECK: [[@LINE+1]]:121: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} {{none}} + + // CHECK: [[@LINE+1]]:134: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{15-18=xx}} {{none}} + + // CHECK: [[@LINE+1]]:121: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=xx}} {{15-18=aa}} {{none}} +} + +func test2Fixits() { + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} + + // CHECK: [[@LINE+1]]:124: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=xx}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} + + // CHECK: [[@LINE+1]]:137: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=xx}} + + // CHECK: [[@LINE+1]]:124: error: expected no fix-its; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{none}} + + // CHECK: [[@LINE+1]]:137: error: unexpected fix-it seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} + + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} + + // CHECK: [[@LINE+1]]:137: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=xx}} {{none}} +} diff --git a/test/diagnostics/verifier.swift b/test/diagnostics/verifier.swift index 4a2c1b10c6c9..37ac6b0da588 100644 --- a/test/diagnostics/verifier.swift +++ b/test/diagnostics/verifier.swift @@ -16,7 +16,7 @@ let y: Int = "hello, world!" // expected-error@:49 {{cannot convert value of typ // Wrong fix-it let z: Int = "hello, world!" as Any // expected-error@-1 {{cannot convert value of type}} {{3-3=foobarbaz}} -// CHECK: expected fix-it not seen; actual fix-its: {{[{][{]}}36-36= as! Int{{[}][}]}} +// CHECK: expected fix-it not seen; actual fix-it seen: {{[{][{]}}36-36= as! Int{{[}][}]}} // Expected no fix-it let a: Bool = "hello, world!" as Any From 1a434a4445922efcbb24a25bbbc717e18719636e Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Sat, 4 Apr 2020 15:16:40 +0900 Subject: [PATCH 02/12] split two conditions --- lib/Frontend/DiagnosticVerifier.cpp | 96 ++++++++++++++--------------- 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index c21a300dae3c..f687060db04e 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -563,69 +563,65 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { // If we have any expected fixits that didn't get matched, then they are // wrong. Replace the failed fixit with what actually happened. - if (missedFixitLoc || - (expected.noExtraFixitsMayAppear && isUnexpectedFixitsSeen)) { - const char *fixItsStartLoc = missedFixitLoc; - if (!fixItsStartLoc) { - assert(expected.noExtraFixitsMayAppear); - fixItsStartLoc = expected.ExpectedEnd - 8; // {{none}} length - } - + if (missedFixitLoc) { // If we had an incorrect expected fixit, render it and produce a fixit // of our own. - // If there was no fixit specification, but some were produced, add a - // fixit to add them in. + + assert(!expected.Fixits.empty() && + "some fix-its should be expected here"); + + const char *replStartLoc = expected.Fixits.front().StartLoc; + const char *replEndLoc = expected.Fixits.back().EndLoc; + + std::string message = "expected fix-it not seen"; std::string actualFixits; - const char *replStartLoc = nullptr, *replEndLoc = nullptr; - if (!FoundDiagnostic.FixIts.empty()) { - actualFixits = renderFixits(FoundDiagnostic.FixIts, InputFile); - } - if (!expected.Fixits.empty()) { - replStartLoc = expected.Fixits.front().StartLoc; - replEndLoc = expected.Fixits.back().EndLoc; + if (FoundDiagnostic.FixIts.empty()) { + if (replStartLoc[-1] == ' ') { + replStartLoc--; + } } else { - assert(expected.noExtraFixitsMayAppear); - // insert fix-its before {{none}} - replStartLoc = fixItsStartLoc; - replEndLoc = replStartLoc; + actualFixits = renderFixits(FoundDiagnostic.FixIts, InputFile); + message += "; actual fix-it seen: " + actualFixits; } + llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), + SMLoc::getFromPointer(replEndLoc)), + actualFixits); + addError(missedFixitLoc, message, fix); + } else if (expected.noExtraFixitsMayAppear && isUnexpectedFixitsSeen) { + // If unexpected fixit were produced, add a fixit to add them in. + + assert(!FoundDiagnostic.FixIts.empty() && + "some fix-its should be produced here"); + + const char *noneStartLoc = expected.ExpectedEnd - 8; // {{none}} length + + std::string actualFixits = + renderFixits(FoundDiagnostic.FixIts, InputFile); + + const char *replStartLoc = nullptr, *replEndLoc = nullptr; std::string message; - if (missedFixitLoc) { - message = "expected fix-it not seen"; + if (expected.Fixits.empty()) { + message = "expected no fix-its"; + replStartLoc = noneStartLoc; + replEndLoc = noneStartLoc; } else { - assert(expected.noExtraFixitsMayAppear); - if (expected.Fixits.empty()) { - message = "expected no fix-its"; - } else { - message = "unexpected fix-it seen"; - } + message = "unexpected fix-it seen"; + replStartLoc = expected.Fixits.front().StartLoc; + replEndLoc = expected.Fixits.back().EndLoc; } - if (replStartLoc && replEndLoc) { - if (!actualFixits.empty()) { - message += "; actual fix-it seen: " + actualFixits; - } - - std::string fixRepl = actualFixits; - if (fixRepl.empty()) { - if (replStartLoc[-1] == ' ') { - replStartLoc--; - } - } else { - if (replStartLoc == replEndLoc) { - fixRepl += " "; - } - } + message += "; actual fix-it seen: " + actualFixits; - llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), - SMLoc::getFromPointer(replEndLoc)), - fixRepl); - addError(fixItsStartLoc, message, fix); - } else { - addError(fixItsStartLoc, message); + if (replStartLoc == replEndLoc) { + actualFixits += " "; } + + llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), + SMLoc::getFromPointer(replEndLoc)), + actualFixits); + addError(noneStartLoc, message, fix); } // Actually remove the diagnostic from the list, so we don't match it From ca42e69929b8750fbbdc20d227a4149d93411633 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Sat, 4 Apr 2020 15:29:11 +0900 Subject: [PATCH 03/12] define "none" constant --- lib/Frontend/DiagnosticVerifier.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index f687060db04e..8a118a738307 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -34,6 +34,9 @@ struct ExpectedFixIt { } // end namespace swift namespace { + +static constexpr StringLiteral fixitExpectationNoneString("none"); + struct ExpectedDiagnosticInfo { // This specifies the full range of the "expected-foo {{}}" specifier. const char *ExpectedStart, *ExpectedEnd = nullptr; @@ -457,11 +460,11 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { ExtraChecks = ExtraChecks.substr(EndLoc+2).ltrim(); // Special case for specifying no fixits should appear. - if (FixItStr == "none") { + if (FixItStr == fixitExpectationNoneString) { Expected.noExtraFixitsMayAppear = true; continue; } - + // Parse the pieces of the fix-it. size_t MinusLoc = FixItStr.find('-'); if (MinusLoc == StringRef::npos) { @@ -595,7 +598,9 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { assert(!FoundDiagnostic.FixIts.empty() && "some fix-its should be produced here"); - const char *noneStartLoc = expected.ExpectedEnd - 8; // {{none}} length + const char *noneStartLoc = + expected.ExpectedEnd - + (fixitExpectationNoneString.size() + 4) /* length of '{{none}}' */; std::string actualFixits = renderFixits(FoundDiagnostic.FixIts, InputFile); From 87edf8eb8c21f434cecddee1c42a5640286f65dc Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Sat, 4 Apr 2020 23:28:21 +0900 Subject: [PATCH 04/12] support plural --- lib/Frontend/DiagnosticVerifier.cpp | 46 ++++++++++++++++++++--------- test/Frontend/verify-fixits.swift | 10 +++---- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index 8a118a738307..66d5bae4ae1b 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -563,6 +563,29 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { bool isUnexpectedFixitsSeen = expected.Fixits.size() < FoundDiagnostic.FixIts.size(); + auto makeActualFixitsPhrase = + [&](ArrayRef actualFixits, + std::string &actualFixitsStr) -> std::string { + actualFixitsStr = renderFixits(actualFixits, InputFile); + + std::string str("actual fix-it"); + if (actualFixits.size() >= 2) { + str += "s"; + } + str += " seen: "; + str += actualFixitsStr; + return str; + }; + + auto emitFixItsError = [&](const char *location, const std::string &message, + const char *replStartLoc, const char *replEndLoc, + const std::string &replStr) { + llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), + SMLoc::getFromPointer(replEndLoc)), + replStr); + addError(location, message, fix); + }; + // If we have any expected fixits that didn't get matched, then they are // wrong. Replace the failed fixit with what actually happened. @@ -584,14 +607,12 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { replStartLoc--; } } else { - actualFixits = renderFixits(FoundDiagnostic.FixIts, InputFile); - message += "; actual fix-it seen: " + actualFixits; + message += + "; " + makeActualFixitsPhrase(FoundDiagnostic.FixIts, actualFixits); } - llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), - SMLoc::getFromPointer(replEndLoc)), - actualFixits); - addError(missedFixitLoc, message, fix); + emitFixItsError(missedFixitLoc, message, replStartLoc, replEndLoc, + actualFixits); } else if (expected.noExtraFixitsMayAppear && isUnexpectedFixitsSeen) { // If unexpected fixit were produced, add a fixit to add them in. @@ -602,9 +623,6 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { expected.ExpectedEnd - (fixitExpectationNoneString.size() + 4) /* length of '{{none}}' */; - std::string actualFixits = - renderFixits(FoundDiagnostic.FixIts, InputFile); - const char *replStartLoc = nullptr, *replEndLoc = nullptr; std::string message; if (expected.Fixits.empty()) { @@ -617,16 +635,16 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { replEndLoc = expected.Fixits.back().EndLoc; } - message += "; actual fix-it seen: " + actualFixits; + std::string actualFixits; + message += + "; " + makeActualFixitsPhrase(FoundDiagnostic.FixIts, actualFixits); if (replStartLoc == replEndLoc) { actualFixits += " "; } - llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), - SMLoc::getFromPointer(replEndLoc)), - actualFixits); - addError(noneStartLoc, message, fix); + emitFixItsError(noneStartLoc, message, replStartLoc, replEndLoc, + actualFixits); } // Actually remove the diagnostic from the list, so we don't match it diff --git a/test/Frontend/verify-fixits.swift b/test/Frontend/verify-fixits.swift index 541d12a74a49..6e651c19669b 100644 --- a/test/Frontend/verify-fixits.swift +++ b/test/Frontend/verify-fixits.swift @@ -56,22 +56,22 @@ func test2Fixits() { labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} - // CHECK: [[@LINE+1]]:124: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + // CHECK: [[@LINE+1]]:124: error: expected fix-it not seen; actual fix-its seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=xx}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} - // CHECK: [[@LINE+1]]:137: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + // CHECK: [[@LINE+1]]:137: error: expected fix-it not seen; actual fix-its seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=xx}} - // CHECK: [[@LINE+1]]:124: error: expected no fix-its; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + // CHECK: [[@LINE+1]]:124: error: expected no fix-its; actual fix-its seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{none}} - // CHECK: [[@LINE+1]]:137: error: unexpected fix-it seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + // CHECK: [[@LINE+1]]:137: error: unexpected fix-it seen; actual fix-its seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=bb}} {{none}} - // CHECK: [[@LINE+1]]:137: error: expected fix-it not seen; actual fix-it seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} + // CHECK: [[@LINE+1]]:137: error: expected fix-it not seen; actual fix-its seen: {{{{}}15-18=aa}} {{{{}}23-26=bb}} labeledFunc(aax: 0, bbx: 1) // expected-error {{incorrect argument labels in call (have 'aax:bbx:', expected 'aa:bb:')}} {{15-18=aa}} {{23-26=xx}} {{none}} } From 1971f4ad73c0db1ea0cfb027a8c28d13544227f3 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Mon, 6 Apr 2020 10:26:36 +0900 Subject: [PATCH 05/12] use Twine and add comment for replacement range --- lib/Frontend/DiagnosticVerifier.cpp | 49 +++++++++++++++++++---------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index 66d5bae4ae1b..abba5b373dd6 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -563,18 +563,16 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { bool isUnexpectedFixitsSeen = expected.Fixits.size() < FoundDiagnostic.FixIts.size(); + // it returns actual fix-its string and diagnostic phrase auto makeActualFixitsPhrase = - [&](ArrayRef actualFixits, - std::string &actualFixitsStr) -> std::string { - actualFixitsStr = renderFixits(actualFixits, InputFile); - - std::string str("actual fix-it"); - if (actualFixits.size() >= 2) { - str += "s"; - } - str += " seen: "; - str += actualFixitsStr; - return str; + [&](ArrayRef actualFixits) + -> std::tuple { + std::string actualFixitsStr = renderFixits(actualFixits, InputFile); + + auto phrase = Twine("actual fix-it") + + (actualFixits.size() >= 2 ? "s" : "") + + " seen: " + actualFixitsStr; + return std::make_tuple(actualFixitsStr, phrase.str()); }; auto emitFixItsError = [&](const char *location, const std::string &message, @@ -603,12 +601,22 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { std::string actualFixits; if (FoundDiagnostic.FixIts.empty()) { + /// If actual fix-its is empty, + /// eat a space before first marker. + /// For example, + /// + /// @code + /// expected-error {{message}} {{1-2=aa}} + /// ~~~~~~~~~~~ + /// ^ remove + /// @endcode if (replStartLoc[-1] == ' ') { replStartLoc--; } } else { - message += - "; " + makeActualFixitsPhrase(FoundDiagnostic.FixIts, actualFixits); + auto actualAndPhrase = makeActualFixitsPhrase(FoundDiagnostic.FixIts); + actualFixits = std::get<0>(actualAndPhrase); + message += "; " + std::get<1>(actualAndPhrase); } emitFixItsError(missedFixitLoc, message, replStartLoc, replEndLoc, @@ -635,11 +643,20 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { replEndLoc = expected.Fixits.back().EndLoc; } - std::string actualFixits; - message += - "; " + makeActualFixitsPhrase(FoundDiagnostic.FixIts, actualFixits); + auto actualAndPhrase = makeActualFixitsPhrase(FoundDiagnostic.FixIts); + std::string actualFixits = std::get<0>(actualAndPhrase); + message += "; " + std::get<1>(actualAndPhrase); if (replStartLoc == replEndLoc) { + /// If no fix-its was expected and range of replacement is empty, + /// insert space after new last marker. + /// For example: + /// + /// @code + /// expected-error {{message}} {{none}} + /// ^ + /// insert `{{1-2=aa}} ` + /// @endcode actualFixits += " "; } From 08d332f62053a253fcc73a2de6750381451cd036 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Mon, 6 Apr 2020 12:10:39 +0900 Subject: [PATCH 06/12] check if {{none}} is at the end --- lib/Frontend/DiagnosticVerifier.cpp | 32 +++++++++++++++++++++-------- test/Frontend/verify-fixits.swift | 8 ++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index abba5b373dd6..bc39d1a30af7 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -49,7 +49,7 @@ struct ExpectedDiagnosticInfo { // This is true if a '{{none}}' is present to mark that there should be no // extra fixits. - bool noExtraFixitsMayAppear = false; + bool noExtraFixitsMayAppear() const { return noneMarkerStartLoc != nullptr; }; // This is the raw input buffer for the message text, the part in the // {{...}} @@ -62,6 +62,9 @@ struct ExpectedDiagnosticInfo { std::vector Fixits; + // Loc of {{none}} + const char *noneMarkerStartLoc = nullptr; + ExpectedDiagnosticInfo(const char *ExpectedStart, DiagnosticKind Classification) : ExpectedStart(ExpectedStart), Classification(Classification) {} @@ -291,16 +294,15 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { unsigned PrevExpectedContinuationLine = 0; std::vector ExpectedDiagnostics; - - auto addError = [&](const char *Loc, std::string message, + + auto addError = [&](const char *Loc, const Twine &message, ArrayRef FixIts = {}) { auto loc = SourceLoc(SMLoc::getFromPointer(Loc)); auto diag = SM.GetMessage(loc, llvm::SourceMgr::DK_Error, message, {}, FixIts); Errors.push_back(diag); }; - - + // Scan the memory buffer looking for expected-note/warning/error. for (size_t Match = InputFile.find("expected-"); Match != StringRef::npos; Match = InputFile.find("expected-", Match+1)) { @@ -461,10 +463,24 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { // Special case for specifying no fixits should appear. if (FixItStr == fixitExpectationNoneString) { - Expected.noExtraFixitsMayAppear = true; + if (Expected.noneMarkerStartLoc) { + addError(FixItStr.data() - 2, + Twine("A second {{") + fixitExpectationNoneString + + "}} is found. it can be put only one."); + break; + } + + Expected.noneMarkerStartLoc = FixItStr.data() - 2; continue; } + if (Expected.noneMarkerStartLoc) { + addError(Expected.noneMarkerStartLoc, Twine("{{") + + fixitExpectationNoneString + + "}} must be at the end."); + break; + } + // Parse the pieces of the fix-it. size_t MinusLoc = FixItStr.find('-'); if (MinusLoc == StringRef::npos) { @@ -575,7 +591,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { return std::make_tuple(actualFixitsStr, phrase.str()); }; - auto emitFixItsError = [&](const char *location, const std::string &message, + auto emitFixItsError = [&](const char *location, const Twine &message, const char *replStartLoc, const char *replEndLoc, const std::string &replStr) { llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc), @@ -621,7 +637,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { emitFixItsError(missedFixitLoc, message, replStartLoc, replEndLoc, actualFixits); - } else if (expected.noExtraFixitsMayAppear && isUnexpectedFixitsSeen) { + } else if (expected.noExtraFixitsMayAppear() && isUnexpectedFixitsSeen) { // If unexpected fixit were produced, add a fixit to add them in. assert(!FoundDiagnostic.FixIts.empty() && diff --git a/test/Frontend/verify-fixits.swift b/test/Frontend/verify-fixits.swift index 6e651c19669b..8679b9384da8 100644 --- a/test/Frontend/verify-fixits.swift +++ b/test/Frontend/verify-fixits.swift @@ -4,6 +4,14 @@ func labeledFunc(aa: Int, bb: Int) {} +func testNoneMarkerCheck() { + // CHECK: [[@LINE+1]]:95: error: A second {{{{}}none}} is found. it can be put only one. + undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} {{none}} + + // CHECK: [[@LINE+1]]:134: error: {{{{}}none}} must be at the end. + labeledFunc(aax: 0, bb: 1) // expected-error {{incorrect argument label in call (have 'aax:bb:', expected 'aa:bb:')}} {{15-18=aa}} {{none}} {{23-26=bb}} +} + func test0Fixits() { undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} From 45c9034d32e60d8be8eb57f6b496d8fed4f21f27 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Mon, 6 Apr 2020 12:20:35 +0900 Subject: [PATCH 07/12] use noneMarkerStartLoc --- lib/Frontend/DiagnosticVerifier.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index bc39d1a30af7..b84048af31d4 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -642,17 +642,14 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { assert(!FoundDiagnostic.FixIts.empty() && "some fix-its should be produced here"); - - const char *noneStartLoc = - expected.ExpectedEnd - - (fixitExpectationNoneString.size() + 4) /* length of '{{none}}' */; + assert(expected.noneMarkerStartLoc && "none marker location is null"); const char *replStartLoc = nullptr, *replEndLoc = nullptr; std::string message; if (expected.Fixits.empty()) { message = "expected no fix-its"; - replStartLoc = noneStartLoc; - replEndLoc = noneStartLoc; + replStartLoc = expected.noneMarkerStartLoc; + replEndLoc = expected.noneMarkerStartLoc; } else { message = "unexpected fix-it seen"; replStartLoc = expected.Fixits.front().StartLoc; @@ -676,8 +673,8 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { actualFixits += " "; } - emitFixItsError(noneStartLoc, message, replStartLoc, replEndLoc, - actualFixits); + emitFixItsError(expected.noneMarkerStartLoc, message, replStartLoc, + replEndLoc, actualFixits); } // Actually remove the diagnostic from the list, so we don't match it From 11a20c9ccdb1b3e4bb94adea783993358a48639a Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Wed, 8 Apr 2020 20:41:19 +0900 Subject: [PATCH 08/12] update second {{none}} error message Co-Authored-By: Owen Voorhees --- lib/Frontend/DiagnosticVerifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index b84048af31d4..58690eb9ab34 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -466,7 +466,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { if (Expected.noneMarkerStartLoc) { addError(FixItStr.data() - 2, Twine("A second {{") + fixitExpectationNoneString + - "}} is found. it can be put only one."); + "}} was found. It may only appear once in an expectation."); break; } From 34d52bb5223c1b772e8fcbe935ee45c07428c40d Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Wed, 8 Apr 2020 21:24:00 +0900 Subject: [PATCH 09/12] update test case for second {{none}} --- test/Frontend/verify-fixits.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Frontend/verify-fixits.swift b/test/Frontend/verify-fixits.swift index 8679b9384da8..d0ba01a33407 100644 --- a/test/Frontend/verify-fixits.swift +++ b/test/Frontend/verify-fixits.swift @@ -5,7 +5,7 @@ func labeledFunc(aa: Int, bb: Int) {} func testNoneMarkerCheck() { - // CHECK: [[@LINE+1]]:95: error: A second {{{{}}none}} is found. it can be put only one. + // CHECK: [[@LINE+1]]:95: error: A second {{{{}}none}} was found. It may only appear once in an expectation. undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}} {{none}} {{none}} // CHECK: [[@LINE+1]]:134: error: {{{{}}none}} must be at the end. From e8cc1f11e96d4d82bc364d6d4630e258205bc4b9 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Wed, 8 Apr 2020 21:40:41 +0900 Subject: [PATCH 10/12] fix test case for new {{none}} check --- test/Parse/type_expr.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Parse/type_expr.swift b/test/Parse/type_expr.swift index 4384e823852f..8a4645ceb3b0 100644 --- a/test/Parse/type_expr.swift +++ b/test/Parse/type_expr.swift @@ -297,7 +297,7 @@ func complexSequence() { // (type_expr typerepr='P1 & P2 throws -> P3 & P1'))) _ = try P1 & P2 throws -> P3 & P1 // expected-warning @-1 {{no calls to throwing functions occur within 'try' expression}} - // expected-error @-2 {{single argument function types require parentheses}} {{none}} {{11-11=(}} {{18-18=)}} + // expected-error @-2 {{single argument function types require parentheses}} {{11-11=(}} {{18-18=)}} // expected-error @-3 {{expected member name or constructor call after type name}} // expected-note @-4 {{use '.self' to reference the type object}} {{11-11=(}} {{36-36=).self}} } From eed176ad036a2bd23c1994d3692477ae2a6a76e2 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Fri, 10 Apr 2020 00:12:38 +0900 Subject: [PATCH 11/12] Use named struct --- lib/Frontend/DiagnosticVerifier.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index 58690eb9ab34..f56a4a47801a 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -579,16 +579,20 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { bool isUnexpectedFixitsSeen = expected.Fixits.size() < FoundDiagnostic.FixIts.size(); - // it returns actual fix-its string and diagnostic phrase + struct ActualFixitsPhrase { + std::string phrase; + std::string actualFixits; + }; + auto makeActualFixitsPhrase = [&](ArrayRef actualFixits) - -> std::tuple { + -> ActualFixitsPhrase { std::string actualFixitsStr = renderFixits(actualFixits, InputFile); auto phrase = Twine("actual fix-it") + (actualFixits.size() >= 2 ? "s" : "") + " seen: " + actualFixitsStr; - return std::make_tuple(actualFixitsStr, phrase.str()); + return ActualFixitsPhrase{phrase.str(), actualFixitsStr}; }; auto emitFixItsError = [&](const char *location, const Twine &message, @@ -630,9 +634,9 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { replStartLoc--; } } else { - auto actualAndPhrase = makeActualFixitsPhrase(FoundDiagnostic.FixIts); - actualFixits = std::get<0>(actualAndPhrase); - message += "; " + std::get<1>(actualAndPhrase); + auto phrase = makeActualFixitsPhrase(FoundDiagnostic.FixIts); + actualFixits = phrase.actualFixits; + message += "; " + phrase.phrase; } emitFixItsError(missedFixitLoc, message, replStartLoc, replEndLoc, @@ -656,9 +660,9 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { replEndLoc = expected.Fixits.back().EndLoc; } - auto actualAndPhrase = makeActualFixitsPhrase(FoundDiagnostic.FixIts); - std::string actualFixits = std::get<0>(actualAndPhrase); - message += "; " + std::get<1>(actualAndPhrase); + auto phrase = makeActualFixitsPhrase(FoundDiagnostic.FixIts); + std::string actualFixits = phrase.actualFixits; + message += "; " + phrase.phrase; if (replStartLoc == replEndLoc) { /// If no fix-its was expected and range of replacement is empty, From 9f59f11f85792049f79e34393e7909e8bdbe5476 Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Fri, 10 Apr 2020 00:15:03 +0900 Subject: [PATCH 12/12] set const --- lib/Frontend/DiagnosticVerifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index f56a4a47801a..6cce8a28cbb9 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -576,7 +576,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) { } } - bool isUnexpectedFixitsSeen = + const bool isUnexpectedFixitsSeen = expected.Fixits.size() < FoundDiagnostic.FixIts.size(); struct ActualFixitsPhrase {