[PATCH] D40424: clang-format: [JS] handle semis in generic types.

2017-11-25 Thread Martin Probst via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL318975: clang-format: [JS] handle semis in generic types. 
(authored by mprobst).

Repository:
  rL LLVM

https://reviews.llvm.org/D40424

Files:
  cfe/trunk/lib/Format/UnwrappedLineParser.cpp
  cfe/trunk/unittests/Format/FormatTestJS.cpp


Index: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
===
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp
@@ -379,13 +379,16 @@
 switch (Tok->Tok.getKind()) {
 case tok::l_brace:
   if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
-if (PrevTok->is(tok::colon))
-  // A colon indicates this code is in a type, or a braced list
-  // following a label in an object literal ({a: {b: 1}}). The code
-  // below could be confused by semicolons between the individual
-  // members in a type member list, which would normally trigger
-  // BK_Block. In both cases, this must be parsed as an inline braced
-  // init.
+if (PrevTok->isOneOf(tok::colon, tok::less))
+  // A ':' indicates this code is in a type, or a braced list
+  // following a label in an object literal ({a: {b: 1}}).
+  // A '<' could be an object used in a comparison, but that is 
nonsense
+  // code (can never return true), so more likely it is a generic type
+  // argument (`X<{a: string; b: number}>`).
+  // The code below could be confused by semicolons between the
+  // individual members in a type member list, which would normally
+  // trigger BK_Block. In both cases, this must be parsed as an inline
+  // braced init.
   Tok->BlockKind = BK_BracedInit;
 else if (PrevTok->is(tok::r_paren))
   // `) { }` can only occur in function or method declarations in JS.
Index: cfe/trunk/unittests/Format/FormatTestJS.cpp
===
--- cfe/trunk/unittests/Format/FormatTestJS.cpp
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp
@@ -1414,6 +1414,7 @@
   verifyFormat("function x(y: {a?: number;} = {}): number {\n"
"  return 12;\n"
"}");
+  verifyFormat("const x: Array<{a: number; b: string;}> = [];");
   verifyFormat("((a: string, b: number): string => a + b);");
   verifyFormat("var x: (y: number) => string;");
   verifyFormat("var x: P string>;");


Index: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
===
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp
@@ -379,13 +379,16 @@
 switch (Tok->Tok.getKind()) {
 case tok::l_brace:
   if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
-if (PrevTok->is(tok::colon))
-  // A colon indicates this code is in a type, or a braced list
-  // following a label in an object literal ({a: {b: 1}}). The code
-  // below could be confused by semicolons between the individual
-  // members in a type member list, which would normally trigger
-  // BK_Block. In both cases, this must be parsed as an inline braced
-  // init.
+if (PrevTok->isOneOf(tok::colon, tok::less))
+  // A ':' indicates this code is in a type, or a braced list
+  // following a label in an object literal ({a: {b: 1}}).
+  // A '<' could be an object used in a comparison, but that is nonsense
+  // code (can never return true), so more likely it is a generic type
+  // argument (`X<{a: string; b: number}>`).
+  // The code below could be confused by semicolons between the
+  // individual members in a type member list, which would normally
+  // trigger BK_Block. In both cases, this must be parsed as an inline
+  // braced init.
   Tok->BlockKind = BK_BracedInit;
 else if (PrevTok->is(tok::r_paren))
   // `) { }` can only occur in function or method declarations in JS.
Index: cfe/trunk/unittests/Format/FormatTestJS.cpp
===
--- cfe/trunk/unittests/Format/FormatTestJS.cpp
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp
@@ -1414,6 +1414,7 @@
   verifyFormat("function x(y: {a?: number;} = {}): number {\n"
"  return 12;\n"
"}");
+  verifyFormat("const x: Array<{a: number; b: string;}> = [];");
   verifyFormat("((a: string, b: number): string => a + b);");
   verifyFormat("var x: (y: number) => string;");
   verifyFormat("var x: P string>;");
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40424: clang-format: [JS] handle semis in generic types.

2017-11-24 Thread Daniel Jasper via Phabricator via cfe-commits
djasper accepted this revision.
djasper added a comment.
This revision is now accepted and ready to land.

Looks good.


https://reviews.llvm.org/D40424



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


[PATCH] D40424: clang-format: [JS] handle semis in generic types.

2017-11-24 Thread Martin Probst via Phabricator via cfe-commits
mprobst created this revision.
Herald added a subscriber: klimek.

TypeScript generic type arguments can contain object (literal) types,
which in turn can contain semicolons:

  const x: Array<{a: number; b: string;} = [];

Previously, clang-format would incorrectly categorize the braced list as
a block and terminate the line at the openening `{`, and then format the
entire expression badly.

With this change, clang-format recognizes `<` preceding a `{` as
introducing a type expression. In JS, `<` comparison with an object
literal can never be true, so the chance of introducing false positives
here is very low.


https://reviews.llvm.org/D40424

Files:
  lib/Format/UnwrappedLineParser.cpp
  unittests/Format/FormatTestJS.cpp


Index: unittests/Format/FormatTestJS.cpp
===
--- unittests/Format/FormatTestJS.cpp
+++ unittests/Format/FormatTestJS.cpp
@@ -1406,6 +1406,7 @@
   verifyFormat("function x(y: {a?: number;} = {}): number {\n"
"  return 12;\n"
"}");
+  verifyFormat("const x: Array<{a: number; b: string;}> = [];");
   verifyFormat("((a: string, b: number): string => a + b);");
   verifyFormat("var x: (y: number) => string;");
   verifyFormat("var x: P string>;");
Index: lib/Format/UnwrappedLineParser.cpp
===
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -377,13 +377,16 @@
 switch (Tok->Tok.getKind()) {
 case tok::l_brace:
   if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
-if (PrevTok->is(tok::colon))
-  // A colon indicates this code is in a type, or a braced list
-  // following a label in an object literal ({a: {b: 1}}). The code
-  // below could be confused by semicolons between the individual
-  // members in a type member list, which would normally trigger
-  // BK_Block. In both cases, this must be parsed as an inline braced
-  // init.
+if (PrevTok->isOneOf(tok::colon, tok::less))
+  // A ':' indicates this code is in a type, or a braced list
+  // following a label in an object literal ({a: {b: 1}}).
+  // A '<' could be an object used in a comparison, but that is 
nonsense
+  // code (can never return true), so more likely it is a generic type
+  // argument (`X<{a: string; b: number}>`).
+  // The code below could be confused by semicolons between the
+  // individual members in a type member list, which would normally
+  // trigger BK_Block. In both cases, this must be parsed as an inline
+  // braced init.
   Tok->BlockKind = BK_BracedInit;
 else if (PrevTok->is(tok::r_paren))
   // `) { }` can only occur in function or method declarations in JS.


Index: unittests/Format/FormatTestJS.cpp
===
--- unittests/Format/FormatTestJS.cpp
+++ unittests/Format/FormatTestJS.cpp
@@ -1406,6 +1406,7 @@
   verifyFormat("function x(y: {a?: number;} = {}): number {\n"
"  return 12;\n"
"}");
+  verifyFormat("const x: Array<{a: number; b: string;}> = [];");
   verifyFormat("((a: string, b: number): string => a + b);");
   verifyFormat("var x: (y: number) => string;");
   verifyFormat("var x: P string>;");
Index: lib/Format/UnwrappedLineParser.cpp
===
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -377,13 +377,16 @@
 switch (Tok->Tok.getKind()) {
 case tok::l_brace:
   if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) {
-if (PrevTok->is(tok::colon))
-  // A colon indicates this code is in a type, or a braced list
-  // following a label in an object literal ({a: {b: 1}}). The code
-  // below could be confused by semicolons between the individual
-  // members in a type member list, which would normally trigger
-  // BK_Block. In both cases, this must be parsed as an inline braced
-  // init.
+if (PrevTok->isOneOf(tok::colon, tok::less))
+  // A ':' indicates this code is in a type, or a braced list
+  // following a label in an object literal ({a: {b: 1}}).
+  // A '<' could be an object used in a comparison, but that is nonsense
+  // code (can never return true), so more likely it is a generic type
+  // argument (`X<{a: string; b: number}>`).
+  // The code below could be confused by semicolons between the
+  // individual members in a type member list, which would normally
+  // trigger BK_Block. In both cases, this must be parsed as an inline
+  // braced init.
   Tok->BlockKind = BK_BracedInit;
 else if