Index: clang/lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- clang/lib/Format/UnwrappedLineFormatter.cpp +++ clang/lib/Format/UnwrappedLineFormatter.cpp @@ -449,7 +449,7 @@ unsigned tryMergeCSharpPropertyAccessor( SmallVectorImpl::const_iterator I, - SmallVectorImpl::const_iterator E, unsigned /*Limit*/) { + SmallVectorImpl::const_iterator E, unsigned Limit) { auto CurrentLine = I; // Does line start with `{` @@ -459,6 +459,7 @@ unsigned MergedLines = 0; bool HasGetOrSet = false; + bool HasDefaultValue = false; while (CurrentLine != E) { bool LineIsGetOrSet = isMergeablePropertyAccessor(*CurrentLine); HasGetOrSet = HasGetOrSet || LineIsGetOrSet; @@ -471,18 +472,34 @@ if (Tok && Tok->is(tok::r_brace)) { ++CurrentLine; ++MergedLines; - // See if the next line is a default value so that we can merge `{ get; - // set } = 0` + // See if the next line is a default value so that we can merge + // `{ get; set } = 0` if (CurrentLine != E && (*CurrentLine)->First && (*CurrentLine)->First->is(tok::equal)) { ++MergedLines; + HasDefaultValue = true; } break; } - // Not a '}' or a get/set line so do not merege lines. + // Not a '}' or a get/set line so do not merge lines. return 0; } + // If the Limit is broken, split the default value onto a new line and + // indent it. + // + // This is a crude heuristic that works for cases like: + // `MyVeryLongTypeName Name { get; set } = new MyVeryLongTypeName();` + // A more robust or general solution would be good. + unsigned TotalLength = 0; + for (unsigned Index = 0; Index < MergedLines; ++Index) { + TotalLength += I[Index]->Last->TotalLength; + } + if (TotalLength > Limit && HasDefaultValue) { + I[MergedLines]->Level += 1; + --MergedLines; + } + return HasGetOrSet ? MergedLines : 0; } Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -565,6 +565,10 @@ verifyFormat("int Value { get; set; }", Style); verifyFormat("int Value { get; set; } = 0", Style); verifyFormat("int Value { internal get; internal set; }", Style); + verifyFormat(R"(// +MyVeryLongTypeName MyVeryLongVariableName { internal get; internal set; } + = new MyVeryLongTypeName();)", + Style); // Do not wrap expression body definitions. verifyFormat(R"(//