[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-06 Thread Marek Kurdej via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGec725b307f3f: [clang-format] Fix C# nullable-related errors 
(authored by exv, committed by curdeius).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101860/new/

https://reviews.llvm.org/D101860

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  clang/unittests/Format/FormatTestCSharp.cpp

Index: clang/unittests/Format/FormatTestCSharp.cpp
===
--- clang/unittests/Format/FormatTestCSharp.cpp
+++ clang/unittests/Format/FormatTestCSharp.cpp
@@ -848,6 +848,21 @@
   verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
 
   verifyFormat(R"(var x = new MyContainer();)", Style); // Generics.
+
+  verifyFormat(R"(//
+public interface I {
+  int? Function();
+})",
+   Style); // Interface methods.
+
+  Style.ColumnLimit = 10;
+  verifyFormat(R"(//
+public VeryLongType? Function(
+int arg1,
+int arg2) {
+  //
+})",
+   Style); // ? sticks with identifier.
 }
 
 TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -114,6 +114,7 @@
   void parseNew();
   void parseAccessSpecifier();
   bool parseEnum();
+  bool parseStructLike();
   void parseConcept();
   void parseRequires();
   void parseRequiresExpression(unsigned int OriginalLevel);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1316,15 +1316,7 @@
 case tok::kw_struct:
 case tok::kw_union:
 case tok::kw_class:
-  // parseRecord falls through and does not yet add an unwrapped line as a
-  // record declaration or definition can start a structural element.
-  parseRecord();
-  // This does not apply for Java, JavaScript and C#.
-  if (Style.Language == FormatStyle::LK_Java ||
-  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
-if (FormatTok->is(tok::semi))
-  nextToken();
-addUnwrappedLine();
+  if (parseStructLike()) {
 return;
   }
   break;
@@ -1438,6 +1430,13 @@
 return;
   }
 
+  if (FormatTok->is(Keywords.kw_interface)) {
+if (parseStructLike()) {
+  return;
+}
+break;
+  }
+
   if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
 parseStatementMacro();
 return;
@@ -2525,6 +2524,21 @@
   // "} n, m;" will end up in one unwrapped line.
 }
 
+bool UnwrappedLineParser::parseStructLike() {
+  // parseRecord falls through and does not yet add an unwrapped line as a
+  // record declaration or definition can start a structural element.
+  parseRecord();
+  // This does not apply to Java, JavaScript and C#.
+  if (Style.Language == FormatStyle::LK_Java ||
+  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
+if (FormatTok->is(tok::semi))
+  nextToken();
+addUnwrappedLine();
+return true;
+  }
+  return false;
+}
+
 namespace {
 // A class used to set and restore the Token position when peeking
 // ahead in the token source.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1078,7 +1078,7 @@
 (Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::greater)) ||
 (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
  Tok->Next->Next->is(tok::equal))) {
-  Tok->setType(TT_JsTypeOptionalQuestion);
+  Tok->setType(TT_CSharpNullable);
   break;
 }
   }
@@ -3161,7 +3161,7 @@
   return Style.SpacesInSquareBrackets;
 
 // No space before ? in nullable types.
-if (Right.is(TT_JsTypeOptionalQuestion))
+if (Right.is(TT_CSharpNullable))
   return false;
 
 // No space before null forgiving '!'.
@@ -3818,6 +3818,10 @@
 // Only break after commas for generic type constraints.
 if (Line.First->is(TT_CSharpGenericTypeConstraint))
   return Left.is(TT_CSharpGenericTypeConstraintComma);
+// Keep nullable operators attached to their identifiers.
+if (Right.is(TT_CSharpNullable)) {
+  return false;
+}
   } else if (Style.Language == FormatStyle::LK_Java) {
 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
  Keywords.kw_implements))
Index: clang/lib/Format/FormatToken.h
===
--- 

[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-05 Thread Eliza Velasquez via Phabricator via cfe-commits
exv updated this revision to Diff 343180.
exv added a comment.

Rebase again in an attempt to fix CI


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101860/new/

https://reviews.llvm.org/D101860

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  clang/unittests/Format/FormatTestCSharp.cpp

Index: clang/unittests/Format/FormatTestCSharp.cpp
===
--- clang/unittests/Format/FormatTestCSharp.cpp
+++ clang/unittests/Format/FormatTestCSharp.cpp
@@ -848,6 +848,21 @@
   verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
 
   verifyFormat(R"(var x = new MyContainer();)", Style); // Generics.
+
+  verifyFormat(R"(//
+public interface I {
+  int? Function();
+})",
+   Style); // Interface methods.
+
+  Style.ColumnLimit = 10;
+  verifyFormat(R"(//
+public VeryLongType? Function(
+int arg1,
+int arg2) {
+  //
+})",
+   Style); // ? sticks with identifier.
 }
 
 TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -114,6 +114,7 @@
   void parseNew();
   void parseAccessSpecifier();
   bool parseEnum();
+  bool parseStructLike();
   void parseConcept();
   void parseRequires();
   void parseRequiresExpression(unsigned int OriginalLevel);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1316,15 +1316,7 @@
 case tok::kw_struct:
 case tok::kw_union:
 case tok::kw_class:
-  // parseRecord falls through and does not yet add an unwrapped line as a
-  // record declaration or definition can start a structural element.
-  parseRecord();
-  // This does not apply for Java, JavaScript and C#.
-  if (Style.Language == FormatStyle::LK_Java ||
-  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
-if (FormatTok->is(tok::semi))
-  nextToken();
-addUnwrappedLine();
+  if (parseStructLike()) {
 return;
   }
   break;
@@ -1438,6 +1430,13 @@
 return;
   }
 
+  if (FormatTok->is(Keywords.kw_interface)) {
+if (parseStructLike()) {
+  return;
+}
+break;
+  }
+
   if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
 parseStatementMacro();
 return;
@@ -2525,6 +2524,21 @@
   // "} n, m;" will end up in one unwrapped line.
 }
 
+bool UnwrappedLineParser::parseStructLike() {
+  // parseRecord falls through and does not yet add an unwrapped line as a
+  // record declaration or definition can start a structural element.
+  parseRecord();
+  // This does not apply to Java, JavaScript and C#.
+  if (Style.Language == FormatStyle::LK_Java ||
+  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
+if (FormatTok->is(tok::semi))
+  nextToken();
+addUnwrappedLine();
+return true;
+  }
+  return false;
+}
+
 namespace {
 // A class used to set and restore the Token position when peeking
 // ahead in the token source.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1078,7 +1078,7 @@
 (Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::greater)) ||
 (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
  Tok->Next->Next->is(tok::equal))) {
-  Tok->setType(TT_JsTypeOptionalQuestion);
+  Tok->setType(TT_CSharpNullable);
   break;
 }
   }
@@ -3161,7 +3161,7 @@
   return Style.SpacesInSquareBrackets;
 
 // No space before ? in nullable types.
-if (Right.is(TT_JsTypeOptionalQuestion))
+if (Right.is(TT_CSharpNullable))
   return false;
 
 // No space before null forgiving '!'.
@@ -3818,6 +3818,10 @@
 // Only break after commas for generic type constraints.
 if (Line.First->is(TT_CSharpGenericTypeConstraint))
   return Left.is(TT_CSharpGenericTypeConstraintComma);
+// Keep nullable operators attached to their identifiers.
+if (Right.is(TT_CSharpNullable)) {
+  return false;
+}
   } else if (Style.Language == FormatStyle::LK_Java) {
 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
  Keywords.kw_implements))
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -112,6 +112,7 @@
   

[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-05 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay accepted this revision.
MyDeveloperDay added a comment.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101860/new/

https://reviews.llvm.org/D101860

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-05 Thread Eliza Velasquez via Phabricator via cfe-commits
exv updated this revision to Diff 343143.
exv marked an inline comment as done.
exv added a comment.

- Incorporate curdeius's feedback


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101860/new/

https://reviews.llvm.org/D101860

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  clang/unittests/Format/FormatTestCSharp.cpp

Index: clang/unittests/Format/FormatTestCSharp.cpp
===
--- clang/unittests/Format/FormatTestCSharp.cpp
+++ clang/unittests/Format/FormatTestCSharp.cpp
@@ -848,6 +848,21 @@
   verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
 
   verifyFormat(R"(var x = new MyContainer();)", Style); // Generics.
+
+  verifyFormat(R"(//
+public interface I {
+  int? Function();
+})",
+   Style); // Interface methods.
+
+  Style.ColumnLimit = 10;
+  verifyFormat(R"(//
+public VeryLongType? Function(
+int arg1,
+int arg2) {
+  //
+})",
+   Style); // ? sticks with identifier.
 }
 
 TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -114,6 +114,7 @@
   void parseNew();
   void parseAccessSpecifier();
   bool parseEnum();
+  bool parseStructLike();
   void parseConcept();
   void parseRequires();
   void parseRequiresExpression(unsigned int OriginalLevel);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1316,15 +1316,7 @@
 case tok::kw_struct:
 case tok::kw_union:
 case tok::kw_class:
-  // parseRecord falls through and does not yet add an unwrapped line as a
-  // record declaration or definition can start a structural element.
-  parseRecord();
-  // This does not apply for Java, JavaScript and C#.
-  if (Style.Language == FormatStyle::LK_Java ||
-  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
-if (FormatTok->is(tok::semi))
-  nextToken();
-addUnwrappedLine();
+  if (parseStructLike()) {
 return;
   }
   break;
@@ -1438,6 +1430,13 @@
 return;
   }
 
+  if (FormatTok->is(Keywords.kw_interface)) {
+if (parseStructLike()) {
+  return;
+}
+break;
+  }
+
   if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
 parseStatementMacro();
 return;
@@ -2525,6 +2524,21 @@
   // "} n, m;" will end up in one unwrapped line.
 }
 
+bool UnwrappedLineParser::parseStructLike() {
+  // parseRecord falls through and does not yet add an unwrapped line as a
+  // record declaration or definition can start a structural element.
+  parseRecord();
+  // This does not apply to Java, JavaScript and C#.
+  if (Style.Language == FormatStyle::LK_Java ||
+  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
+if (FormatTok->is(tok::semi))
+  nextToken();
+addUnwrappedLine();
+return true;
+  }
+  return false;
+}
+
 namespace {
 // A class used to set and restore the Token position when peeking
 // ahead in the token source.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1078,7 +1078,7 @@
 (Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::greater)) ||
 (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
  Tok->Next->Next->is(tok::equal))) {
-  Tok->setType(TT_JsTypeOptionalQuestion);
+  Tok->setType(TT_CSharpNullable);
   break;
 }
   }
@@ -3161,7 +3161,7 @@
   return Style.SpacesInSquareBrackets;
 
 // No space before ? in nullable types.
-if (Right.is(TT_JsTypeOptionalQuestion))
+if (Right.is(TT_CSharpNullable))
   return false;
 
 // No space before null forgiving '!'.
@@ -3818,6 +3818,10 @@
 // Only break after commas for generic type constraints.
 if (Line.First->is(TT_CSharpGenericTypeConstraint))
   return Left.is(TT_CSharpGenericTypeConstraintComma);
+// Keep nullable operators attached to their identifiers.
+if (Right.is(TT_CSharpNullable)) {
+  return false;
+}
   } else if (Style.Language == FormatStyle::LK_Java) {
 if (Left.isOneOf(Keywords.kw_throws, Keywords.kw_extends,
  Keywords.kw_implements))
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h

[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-05 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius accepted this revision.
curdeius added a comment.
This revision is now accepted and ready to land.

LGTM pending CI.




Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2531
+  parseRecord();
+  // This does not apply for Java, JavaScript and C#.
+  if (Style.Language == FormatStyle::LK_Java ||

Nit when you're here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101860/new/

https://reviews.llvm.org/D101860

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-05 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius added a comment.

You can add a parent revision so that this patch will be applied upon its 
parent.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101860/new/

https://reviews.llvm.org/D101860

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D101860: [clang-format] Fix C# nullable-related errors

2021-05-04 Thread Eliza Velasquez via Phabricator via cfe-commits
exv created this revision.
exv requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This diff is based on https://reviews.llvm.org/D101702.

This fixes two errors:

Previously, clang-format was splitting up type identifiers from the
nullable ?. This changes this behavior so that the type name sticks with
the operator.

Additionally, nullable operators attached to return types in interface
functions were not parsed correctly. Digging deeper, it looks like
interface bodies were being parsed differently than classes and structs,
causing MustBeDeclaration to be incorrect for interface members. They
now share the same logic.

One other change is reintroducing the CSharpNullable type independent of
JsTypeOptionalQuestion. Despite having a similar semantic purpose, their
actual syntax differs quite a bit.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101860

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  clang/unittests/Format/FormatTestCSharp.cpp

Index: clang/unittests/Format/FormatTestCSharp.cpp
===
--- clang/unittests/Format/FormatTestCSharp.cpp
+++ clang/unittests/Format/FormatTestCSharp.cpp
@@ -848,6 +848,21 @@
   verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
 
   verifyFormat(R"(var x = new MyContainer();)", Style); // Generics.
+
+  verifyFormat(R"(//
+public interface I {
+  int? Function();
+})",
+   Style); // Interface methods.
+
+  Style.ColumnLimit = 10;
+  verifyFormat(R"(//
+public VeryLongType? Function(
+int arg1,
+int arg2) {
+  //
+})",
+   Style); // ? sticks with identifier.
 }
 
 TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -114,6 +114,7 @@
   void parseNew();
   void parseAccessSpecifier();
   bool parseEnum();
+  bool parseStructLike();
   void parseConcept();
   void parseRequires();
   void parseRequiresExpression(unsigned int OriginalLevel);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1316,15 +1316,7 @@
 case tok::kw_struct:
 case tok::kw_union:
 case tok::kw_class:
-  // parseRecord falls through and does not yet add an unwrapped line as a
-  // record declaration or definition can start a structural element.
-  parseRecord();
-  // This does not apply for Java, JavaScript and C#.
-  if (Style.Language == FormatStyle::LK_Java ||
-  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
-if (FormatTok->is(tok::semi))
-  nextToken();
-addUnwrappedLine();
+  if (parseStructLike()) {
 return;
   }
   break;
@@ -1438,6 +1430,13 @@
 return;
   }
 
+  if (FormatTok->is(Keywords.kw_interface)) {
+if (parseStructLike()) {
+  return;
+}
+break;
+  }
+
   if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
 parseStatementMacro();
 return;
@@ -2525,6 +2524,21 @@
   // "} n, m;" will end up in one unwrapped line.
 }
 
+bool UnwrappedLineParser::parseStructLike() {
+  // parseRecord falls through and does not yet add an unwrapped line as a
+  // record declaration or definition can start a structural element.
+  parseRecord();
+  // This does not apply for Java, JavaScript and C#.
+  if (Style.Language == FormatStyle::LK_Java ||
+  Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
+if (FormatTok->is(tok::semi))
+  nextToken();
+addUnwrappedLine();
+return true;
+  }
+  return false;
+}
+
 namespace {
 // A class used to set and restore the Token position when peeking
 // ahead in the token source.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1071,7 +1071,7 @@
 (Tok->Next && Tok->Next->isOneOf(tok::r_paren, tok::greater)) ||
 (Tok->Next && Tok->Next->is(tok::identifier) && Tok->Next->Next &&
  Tok->Next->Next->is(tok::equal))) {
-  Tok->setType(TT_JsTypeOptionalQuestion);
+  Tok->setType(TT_CSharpNullable);
   break;
 }
   }
@@ -3154,7 +3154,7 @@
   return Style.SpacesInSquareBrackets;
 
 // No space before ? in nullable types.
-if (Right.is(TT_JsTypeOptionalQuestion))
+if (Right.is(TT_CSharpNullable))
   return false;
 
 // No space before null forgiving '!'.
@@ -3811,6