TYPE(UntouchableMacroFunc) \
TYPE(CSharpStringLiteral) \
TYPE(CSharpNamedArgumentColon) \
+ TYPE(CSharpNullable) \
TYPE(CSharpNullConditionalLSquare) \
TYPE(CSharpGenericTypeConstraint) \
TYPE(CSharpGenericTypeConstraintColon) \
(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;
}
}
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 '!'.
// 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))
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;
return;
}
+ if (FormatTok->is(Keywords.kw_interface)) {
+ if (parseStructLike()) {
+ return;
+ }
+ break;
+ }
+
if (Style.isCpp() && FormatTok->is(TT_StatementMacro)) {
parseStatementMacro();
return;
// "} 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.
void parseNew();
void parseAccessSpecifier();
bool parseEnum();
+ bool parseStructLike();
void parseConcept();
void parseRequires();
void parseRequiresExpression(unsigned int OriginalLevel);
verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
verifyFormat(R"(var x = new MyContainer<int?>();)", 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) {