Skip to content

Commit 799a7f2

Browse files
committed
重写缩进算法,试图更好的支持tab缩进
1 parent 208a4c5 commit 799a7f2

17 files changed

+326
-94
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(LuaCodeStyle)
44

55
set(CMAKE_CXX_STANDARD 20)
66

7-
option(BuildAsLuaLib "Build for lua dll" OFF)
7+
option(BuildAsLuaLib "Build for lua dll" ON)
88
option(BuildCodeFormat "Build CodeFormat" ON)
99
option(BuildCodeFormatServer "Build CodeFormatServer" ON)
1010
option(EnableTest "Test project" ON)

CodeService/src/FormatElement/AlignToFirstElement.cpp

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "CodeService/FormatElement/AlignToFirstElement.h"
22

3-
AlignToFirstElement::AlignToFirstElement(int lowestIndent)
4-
: _lowestIndent(lowestIndent)
3+
AlignToFirstElement::AlignToFirstElement()
54
{
65
}
76

@@ -14,28 +13,53 @@ void AlignToFirstElement::Serialize(SerializeContext& ctx, ChildIterator selfIt,
1413
{
1514
for (auto it = _children.begin(); it != _children.end(); ++it)
1615
{
17-
auto child = *it;
16+
const auto child = *it;
1817
if (it == _children.begin())
1918
{
2019
auto writeCount = ctx.GetCharacterCount();
21-
auto indentCount = ctx.GetCurrentIndent();
22-
if (writeCount > indentCount)
20+
auto indentState = ctx.GetCurrentIndent();
21+
switch (indentState.IndentStyle)
2322
{
24-
ctx.AddIndent(writeCount, ctx.GetOptions().indent_style);
25-
}
26-
else
27-
{
28-
indentCount += _lowestIndent;
29-
const auto column = ctx.GetColumn(child->GetTextRange().StartOffset);
30-
if (column > static_cast<int>(indentCount))
23+
case IndentStyle::Space:
3124
{
32-
ctx.AddIndent(column, ctx.GetOptions().indent_style);
25+
if (writeCount > indentState.SpaceIndent)
26+
{
27+
indentState.SpaceIndent = writeCount;
28+
}
29+
else
30+
{
31+
indentState.SpaceIndent = ctx.GetColumn(child->GetTextRange().StartOffset);
32+
}
33+
break;
3334
}
34-
else
35+
case IndentStyle::Tab:
3536
{
36-
ctx.AddIndent(indentCount, ctx.GetOptions().indent_style);
37+
if (writeCount > indentState.TabIndent)
38+
{
39+
indentState.SpaceIndent += writeCount - indentState.TabIndent;
40+
}
41+
else
42+
{
43+
auto& options = ctx.GetOptions();
44+
auto state = ctx.CalculateIndentState(child->GetTextRange().StartOffset);
45+
if (state.TabIndent < indentState.TabIndent)
46+
{
47+
auto diff = (indentState.TabIndent - state.TabIndent) * options.tab_width;
48+
if (state.SpaceIndent > diff)
49+
{
50+
indentState.SpaceIndent = state.SpaceIndent - diff;
51+
}
52+
}
53+
else
54+
{
55+
indentState.SpaceIndent = (state.TabIndent - indentState.TabIndent) * options.tab_width +
56+
state.SpaceIndent;
57+
}
58+
}
59+
break;
3760
}
3861
}
62+
ctx.AddIndent(indentState);
3963
}
4064

4165
child->Serialize(ctx, it, *this);
@@ -51,28 +75,53 @@ void AlignToFirstElement::Diagnosis(DiagnosisContext& ctx, ChildIterator selfIt,
5175
{
5276
for (auto it = _children.begin(); it != _children.end(); ++it)
5377
{
54-
auto child = *it;
78+
const auto child = *it;
5579
if (it == _children.begin())
5680
{
5781
auto writeCount = ctx.GetCharacterCount();
58-
auto indentCount = ctx.GetCurrentIndent();
59-
if (writeCount > indentCount)
82+
auto indentState = ctx.GetCurrentIndent();
83+
switch (indentState.IndentStyle)
6084
{
61-
ctx.AddIndent(writeCount, ctx.GetOptions().indent_style);
85+
case IndentStyle::Space:
86+
{
87+
if (writeCount > indentState.SpaceIndent)
88+
{
89+
indentState.SpaceIndent = writeCount;
90+
}
91+
else
92+
{
93+
indentState.SpaceIndent = ctx.GetColumn(child->GetTextRange().StartOffset);
94+
}
95+
break;
6296
}
63-
else
97+
case IndentStyle::Tab:
6498
{
65-
indentCount += _lowestIndent;
66-
const auto column = ctx.GetColumn(child->GetTextRange().StartOffset);
67-
if (column > static_cast<int>(indentCount))
99+
if (writeCount > indentState.TabIndent)
68100
{
69-
ctx.AddIndent(column, ctx.GetOptions().indent_style);
101+
indentState.SpaceIndent += writeCount - indentState.TabIndent;
70102
}
71103
else
72104
{
73-
ctx.AddIndent(indentCount, ctx.GetOptions().indent_style);
105+
auto& options = ctx.GetOptions();
106+
auto state = ctx.CalculateIndentState(child->GetTextRange().StartOffset);
107+
if (state.TabIndent < indentState.TabIndent)
108+
{
109+
auto diff = (indentState.TabIndent - state.TabIndent) * options.tab_width;
110+
if (state.SpaceIndent > diff)
111+
{
112+
indentState.SpaceIndent = state.SpaceIndent - diff;
113+
}
114+
}
115+
else
116+
{
117+
indentState.SpaceIndent = (state.TabIndent - indentState.TabIndent) * options.tab_width +
118+
state.SpaceIndent;
119+
}
74120
}
121+
break;
122+
}
75123
}
124+
ctx.AddIndent(indentState);
76125
}
77126

78127
child->Diagnosis(ctx, it, *this);

CodeService/src/FormatElement/FormatContext.cpp

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,41 @@ void FormatContext::AddIndent()
1818
{
1919
if (_indentStack.empty())
2020
{
21-
_indentStack.push_back({0, IndentStyle::Space});
21+
_indentStack.push_back({0, 0, IndentStyle::Space});
2222
return;
2323
}
2424

2525
auto& topIndent = _indentStack.back();
26-
std::size_t newIndent = _options.indent_size + topIndent.Indent;
26+
std::size_t newIndent = _options.indent_size + topIndent.SpaceIndent;
2727

28-
_indentStack.push_back({newIndent, IndentStyle::Space});
28+
_indentStack.push_back({newIndent, 0, IndentStyle::Space});
2929
}
3030
else
3131
{
3232
if (_indentStack.empty())
3333
{
34-
_indentStack.push_back({0, IndentStyle::Tab});
34+
_indentStack.push_back({0, 0, IndentStyle::Tab});
3535
return;
3636
}
3737

3838
auto& topIndent = _indentStack.back();
39+
IndentState state{topIndent.SpaceIndent, topIndent.TabIndent, IndentStyle::Tab};
40+
if (topIndent.SpaceIndent != 0)
41+
{
42+
state.SpaceIndent += _options.tab_width;
43+
}
44+
else
45+
{
46+
state.TabIndent += 1;
47+
}
3948

40-
_indentStack.push_back({1 + topIndent.Indent, IndentStyle::Tab});
49+
_indentStack.push_back(state);
4150
}
4251
}
4352

44-
void FormatContext::AddIndent(std::size_t specialIndent, IndentStyle style)
53+
void FormatContext::AddIndent(IndentState state)
4554
{
46-
_indentStack.push_back({specialIndent, style});
55+
_indentStack.push_back(state);
4756
}
4857

4958
void FormatContext::RecoverIndent()
@@ -66,29 +75,60 @@ int FormatContext::GetColumn(int offset)
6675
return _parser->GetColumn(offset);
6776
}
6877

78+
FormatContext::IndentState FormatContext::CalculateIndentState(int offset)
79+
{
80+
auto file = _parser->GetLuaFile();
81+
auto source = file->GetSource();
82+
auto line = file->GetLine(offset);
83+
auto start = file->GetOffsetFromPosition(line, 0);
84+
85+
86+
IndentState state = {0, 0, IndentStyle::Space};
87+
for (; start < offset; start++)
88+
{
89+
auto ch = source[start];
90+
if (ch == '\t')
91+
{
92+
state.IndentStyle = IndentStyle::Tab;
93+
state.TabIndent++;
94+
}
95+
else
96+
{
97+
state.SpaceIndent++;
98+
}
99+
}
100+
101+
if(state.TabIndent == 0 && state.SpaceIndent == 0)
102+
{
103+
state.IndentStyle = _options.indent_style;
104+
}
105+
106+
return state;
107+
}
108+
69109
std::size_t FormatContext::GetCharacterCount() const
70110
{
71111
return _characterCount;
72112
}
73113

74-
std::size_t FormatContext::GetCurrentIndent() const
114+
FormatContext::IndentState FormatContext::GetCurrentIndent() const
75115
{
76116
if (_indentStack.empty())
77117
{
78-
return 0;
118+
return IndentState{0, 0, _options.indent_style};
79119
}
80120

81-
return _indentStack.back().Indent;
121+
return _indentStack.back();
82122
}
83123

84-
std::size_t FormatContext::GetLastIndent() const
124+
FormatContext::IndentState FormatContext::GetLastIndent() const
85125
{
86126
if (_indentStack.size() < 2)
87127
{
88-
return 0;
128+
return IndentState(0, 0, _options.indent_style);
89129
}
90130

91-
return _indentStack[_indentStack.size() - 2].Indent;
131+
return _indentStack[_indentStack.size() - 2];
92132
}
93133

94134
std::shared_ptr<LuaParser> FormatContext::GetParser()

CodeService/src/FormatElement/IndentElement.cpp

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@ void IndentElement::Serialize(SerializeContext& ctx, ChildIterator selfIt, Forma
2929
{
3030
ctx.AddIndent();
3131
}
32+
else if (_style == IndentStyle::Tab)
33+
{
34+
ctx.AddIndent(FormatContext::IndentState{0, _specialIndent, IndentStyle::Tab});
35+
}
3236
else
3337
{
34-
ctx.AddIndent(_specialIndent, _style);
38+
ctx.AddIndent(FormatContext::IndentState{_specialIndent, 0, IndentStyle::Space});
3539
}
3640

3741
FormatElement::Serialize(ctx, selfIt, parent);
@@ -45,32 +49,69 @@ void IndentElement::Diagnosis(DiagnosisContext& ctx, ChildIterator selfIt, Forma
4549
{
4650
ctx.AddIndent();
4751
}
52+
else if (_style == IndentStyle::Tab)
53+
{
54+
ctx.AddIndent(FormatContext::IndentState{0, _specialIndent, IndentStyle::Tab});
55+
}
4856
else
4957
{
50-
ctx.AddIndent(_specialIndent, _style);
58+
ctx.AddIndent(FormatContext::IndentState{_specialIndent, 0, IndentStyle::Space});
5159
}
5260

61+
5362
for (auto it = _children.begin(); it != _children.end(); ++it)
5463
{
5564
const auto child = *it;
5665

57-
if (child->HasValidTextRange() && ctx.GetOptions().indent_style == IndentStyle::Space
58-
&& child->GetType() != FormatElementType::IndentElement && child->GetType() !=
59-
FormatElementType::NoIndentElement)
66+
if (child->HasValidTextRange()
67+
&& child->GetType() != FormatElementType::IndentElement
68+
&& child->GetType() != FormatElementType::NoIndentElement)
6069
{
6170
auto range = child->GetTextRange();
71+
auto line = ctx.GetLine(range.StartOffset);
6272
auto character = ctx.GetColumn(range.StartOffset);
63-
if (character != static_cast<int>(ctx.GetCurrentIndent()))
73+
auto indentState = ctx.CalculateIndentState(range.StartOffset);
74+
auto state = ctx.GetCurrentIndent();
75+
if (ctx.GetOptions().indent_style != indentState.IndentStyle)
6476
{
65-
auto line = ctx.GetLine(range.StartOffset);
66-
ctx.PushDiagnosis(format(LText("incorrect indentation {}, here need {} indent"),
67-
character, ctx.GetCurrentIndent()),
68-
LuaDiagnosisPosition(line, 0),
69-
LuaDiagnosisPosition(line, character)
77+
ctx.PushDiagnosis(
78+
format(LText("incorrect indentation style, expect {}, but here is {}"),
79+
GetIndentStyleName(state.IndentStyle),
80+
GetIndentStyleName(indentState.IndentStyle)
81+
),
82+
LuaDiagnosisPosition(line, 0),
83+
LuaDiagnosisPosition(line, character)
7084
);
85+
goto endIndentDiagnose;
86+
}
87+
88+
if (indentState.IndentStyle == IndentStyle::Space) {
89+
if (state.SpaceIndent != indentState.SpaceIndent)
90+
{
91+
ctx.PushDiagnosis(
92+
format(LText("incorrect indentation {}, here need {} space indentation"),
93+
indentState.SpaceIndent, state.SpaceIndent),
94+
LuaDiagnosisPosition(line, 0),
95+
LuaDiagnosisPosition(line, character)
96+
);
97+
}
98+
goto endIndentDiagnose;
99+
}
100+
else
101+
{
102+
if (state.SpaceIndent != indentState.SpaceIndent || state.TabIndent != indentState.TabIndent)
103+
{
104+
ctx.PushDiagnosis(
105+
format(LText("incorrect indentation, here need {} tab and {} space indentation"),
106+
state.TabIndent, state.SpaceIndent),
107+
LuaDiagnosisPosition(line, 0),
108+
LuaDiagnosisPosition(line, character)
109+
);
110+
}
71111
}
72112
}
73113

114+
endIndentDiagnose:
74115
child->Diagnosis(ctx, it, *this);
75116
}
76117

CodeService/src/FormatElement/IndentManager.cpp

Whitespace-only changes.

CodeService/src/FormatElement/KeepElement.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void KeepElement::Serialize(SerializeContext& ctx, ChildIterator selfIt,
3535
{
3636
line--;
3737
}
38+
3839
ctx.PrintLine(line);
3940
}
4041
}

CodeService/src/FormatElement/LongExpressionLayoutElement.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ void LongExpressionLayoutElement::SerializeSubExpression(SerializeContext& ctx,
5050
if (ctx.GetCharacterCount() == 0 && !_hasContinuation)
5151
{
5252
_hasContinuation = true;
53-
ctx.AddIndent(ctx.GetCurrentIndent() + _continuationIndent, IndentStyle::Space);
53+
auto state = ctx.GetCurrentIndent();
54+
state.SpaceIndent = _continuationIndent;
55+
ctx.AddIndent(state);
5456
}
5557
}
5658
}
@@ -59,7 +61,7 @@ void LongExpressionLayoutElement::SerializeSubExpression(SerializeContext& ctx,
5961
void LongExpressionLayoutElement::DiagnosisSubExpression(DiagnosisContext& ctx, FormatElement& parent)
6062
{
6163
auto& children = parent.GetChildren();
62-
for (auto it = children.begin();it != children.end(); ++it)
64+
for (auto it = children.begin(); it != children.end(); ++it)
6365
{
6466
auto child = *it;
6567

@@ -76,7 +78,9 @@ void LongExpressionLayoutElement::DiagnosisSubExpression(DiagnosisContext& ctx,
7678
if (ctx.GetCharacterCount() == 0 && !_hasContinuation)
7779
{
7880
_hasContinuation = true;
79-
ctx.AddIndent(ctx.GetCurrentIndent() + _continuationIndent, IndentStyle::Space);
81+
auto state = ctx.GetCurrentIndent();
82+
state.SpaceIndent = _continuationIndent;
83+
ctx.AddIndent(state);
8084
}
8185
}
8286
}

0 commit comments

Comments
 (0)