jbcoe created this revision. jbcoe added a reviewer: krasimir. jbcoe added a project: clang-format. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77064 Files: clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestCSharp.cpp Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -702,12 +702,13 @@ })", Style); + Style.ColumnLimit = 50; // Force lines to be wrapped. verifyFormat(R"(// -class ItemFactory<T> - where T : new(), - IAnInterface<T>, - IAnotherInterface<T>, - IAnotherInterfaceStill<T> {})", +class ItemFactory<T, U> + where T : new(), + IAnInterface<T>, + IAnotherInterface<T, U>, + IAnotherInterfaceStill<T, U> {})", Style); // In other languages `where` can be used as a normal identifier. Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -2339,7 +2339,13 @@ break; } if (FormatTok->Tok.is(tok::semi)) + return; + if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + addUnwrappedLine(); + nextToken(); + parseCSharpGenericTypeConstraint(); return; + } nextToken(); } } @@ -2354,6 +2360,11 @@ /*MunchSemi=*/false); } } + // if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + // addUnwrappedLine(); + // nextToken(); + // parseCSharpGenericTypeConstraint(); + // } // There is no addUnwrappedLine() here so that we fall through to parsing a // structural element afterwards. Thus, in "class A {} n, m;", // "} n, m;" will end up in one unwrapped line. Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -1060,15 +1060,20 @@ } void parseCSharpGenericTypeConstraint() { + int OpenAngleBracketsCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::less)) { // parseAngle is too greedy and will consume the whole line. CurrentToken->Type = TT_TemplateOpener; + ++OpenAngleBracketsCount; next(); } else if (CurrentToken->is(tok::greater)) { CurrentToken->Type = TT_TemplateCloser; + --OpenAngleBracketsCount; next(); - } else if (CurrentToken->is(tok::comma)) { + } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount==0) { + // We allow line breaks after GenericTypeConstraintComma's + // so do not flag commas in Generics as GenericTypeConstraintComma's. CurrentToken->Type = TT_CSharpGenericTypeConstraintComma; next(); } else if (CurrentToken->is(Keywords.kw_where)) {
Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -702,12 +702,13 @@ })", Style); + Style.ColumnLimit = 50; // Force lines to be wrapped. verifyFormat(R"(// -class ItemFactory<T> - where T : new(), - IAnInterface<T>, - IAnotherInterface<T>, - IAnotherInterfaceStill<T> {})", +class ItemFactory<T, U> + where T : new(), + IAnInterface<T>, + IAnotherInterface<T, U>, + IAnotherInterfaceStill<T, U> {})", Style); // In other languages `where` can be used as a normal identifier. Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -2339,7 +2339,13 @@ break; } if (FormatTok->Tok.is(tok::semi)) + return; + if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + addUnwrappedLine(); + nextToken(); + parseCSharpGenericTypeConstraint(); return; + } nextToken(); } } @@ -2354,6 +2360,11 @@ /*MunchSemi=*/false); } } + // if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + // addUnwrappedLine(); + // nextToken(); + // parseCSharpGenericTypeConstraint(); + // } // There is no addUnwrappedLine() here so that we fall through to parsing a // structural element afterwards. Thus, in "class A {} n, m;", // "} n, m;" will end up in one unwrapped line. Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -1060,15 +1060,20 @@ } void parseCSharpGenericTypeConstraint() { + int OpenAngleBracketsCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::less)) { // parseAngle is too greedy and will consume the whole line. CurrentToken->Type = TT_TemplateOpener; + ++OpenAngleBracketsCount; next(); } else if (CurrentToken->is(tok::greater)) { CurrentToken->Type = TT_TemplateCloser; + --OpenAngleBracketsCount; next(); - } else if (CurrentToken->is(tok::comma)) { + } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount==0) { + // We allow line breaks after GenericTypeConstraintComma's + // so do not flag commas in Generics as GenericTypeConstraintComma's. CurrentToken->Type = TT_CSharpGenericTypeConstraintComma; next(); } else if (CurrentToken->is(Keywords.kw_where)) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits