From 505c974b5fda22be2cc69c681c5397d1a030d17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Mikle=C4=8Di=C4=87?= Date: Tue, 11 Feb 2014 22:34:58 +0100 Subject: [PATCH] Issue with preprocessor directives. --- .../IndentEngine/CSharpIndentEngine.cs | 19 +++++---- .../IndentEngine/IndentState.cs | 41 ++++++++++++++----- .../IndentationTests/BlockTest.cs | 11 +---- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs b/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs index 2d42c870c..478bc45c6 100644 --- a/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/IndentEngine/CSharpIndentEngine.cs @@ -81,10 +81,15 @@ public class CSharpIndentEngine : IStateMachineIndentEngine internal HashSet customConditionalSymbols; /// - /// True if any of the preprocessor if/elif directives in the current - /// block (between #if and #endif) were evaluated to true. + /// Stores the results of evaluations of the preprocessor if/elif directives + /// in the current block (between #if and #endif). /// - internal CloneableStack ifDirectiveEvalResult = new CloneableStack (); + internal CloneableStack ifDirectiveEvalResults = new CloneableStack (); + + /// + /// Stores the indentation levels of the if directives in the current block. + /// + internal CloneableStack ifDirectiveIndents = new CloneableStack(); /// /// Stores the last sequence of characters that can form a @@ -244,7 +249,6 @@ public bool EnableCustomIndentLevels /// internal char previousNewline = '\0'; - /// /// Current indent level on this line. /// @@ -310,7 +314,6 @@ public CSharpIndentEngine(CSharpIndentEngine prototype) this.wordToken = new StringBuilder(prototype.wordToken.ToString()); this.previousKeyword = string.Copy(prototype.previousKeyword); - this.ifDirectiveEvalResult = prototype.ifDirectiveEvalResult; this.offset = prototype.offset; this.line = prototype.line; @@ -323,7 +326,8 @@ public CSharpIndentEngine(CSharpIndentEngine prototype) this.currentIndent = new StringBuilder(prototype.CurrentIndent.ToString()); this.lineBeganInsideMultiLineComment = prototype.lineBeganInsideMultiLineComment; this.lineBeganInsideVerbatimString = prototype.lineBeganInsideVerbatimString; - this.ifDirectiveEvalResult = prototype.ifDirectiveEvalResult.Clone(); + this.ifDirectiveEvalResults = prototype.ifDirectiveEvalResults.Clone(); + this.ifDirectiveIndents = prototype.ifDirectiveIndents.Clone(); this.EnableCustomIndentLevels = prototype.EnableCustomIndentLevels; } @@ -427,7 +431,8 @@ public void Reset() { currentState = new GlobalBodyState(this); conditionalSymbols.Clear(); - ifDirectiveEvalResult.Clear(); + ifDirectiveEvalResults.Clear(); + ifDirectiveIndents.Clear(); offset = 0; line = 1; diff --git a/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs b/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs index c50d890e7..69cc2700a 100644 --- a/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs +++ b/ICSharpCode.NRefactory.CSharp/IndentEngine/IndentState.cs @@ -1267,8 +1267,8 @@ public override void Push(char ch) switch (DirectiveType) { case PreProcessorDirective.If: - Engine.ifDirectiveEvalResult.Push(eval(DirectiveStatement.ToString())); - if (Engine.ifDirectiveEvalResult.Peek()) + Engine.ifDirectiveEvalResults.Push(eval(DirectiveStatement.ToString())); + if (Engine.ifDirectiveEvalResults.Peek()) { // the if/elif directive is true -> continue with the previous state } @@ -1280,11 +1280,11 @@ public override void Push(char ch) } break; case PreProcessorDirective.Elif: - if (Engine.ifDirectiveEvalResult.Count > 0) + if (Engine.ifDirectiveEvalResults.Count > 0) { - if (!Engine.ifDirectiveEvalResult.Peek()) + if (!Engine.ifDirectiveEvalResults.Peek()) { - Engine.ifDirectiveEvalResult.Pop(); + Engine.ifDirectiveEvalResults.Pop(); goto case PreProcessorDirective.If; } } @@ -1292,7 +1292,7 @@ public override void Push(char ch) ChangeState(); break; case PreProcessorDirective.Else: - if (Engine.ifDirectiveEvalResult.Count > 0 && Engine.ifDirectiveEvalResult.Peek()) + if (Engine.ifDirectiveEvalResults.Count > 0 && Engine.ifDirectiveEvalResults.Peek()) { // some if/elif directive was true -> change to a state that will // ignore any chars until #endif @@ -1319,7 +1319,8 @@ public override void Push(char ch) break; case PreProcessorDirective.Endif: // marks the end of this block - Engine.ifDirectiveEvalResult.Pop(); + Engine.ifDirectiveEvalResults.Pop(); + Engine.ifDirectiveIndents.Pop(); break; case PreProcessorDirective.Region: case PreProcessorDirective.Pragma: @@ -1337,7 +1338,14 @@ public override void InitializeState() // OPTION: IndentPreprocessorStatements if (Engine.formattingOptions.IndentPreprocessorDirectives) { - ThisLineIndent = Parent.ThisLineIndent.Clone(); + if (Engine.ifDirectiveIndents.Count > 0) + { + ThisLineIndent = Engine.ifDirectiveIndents.Peek().Clone(); + } + else + { + ThisLineIndent = Parent.ThisLineIndent.Clone(); + } } else { @@ -1389,6 +1397,10 @@ public override void CheckKeyword(string keyword) { ThisLineIndent = Parent.NextLineIndent.Clone(); } + else if (DirectiveType == PreProcessorDirective.If) + { + Engine.ifDirectiveIndents.Push(ThisLineIndent.Clone()); + } } } @@ -1664,8 +1676,17 @@ public override void Push(char ch) public override void InitializeState() { - ThisLineIndent = Parent.NextLineIndent.Clone(); - NextLineIndent = ThisLineIndent.Clone(); + if (Engine.formattingOptions.IndentPreprocessorDirectives && + Engine.ifDirectiveIndents.Count > 0) + { + ThisLineIndent = Engine.ifDirectiveIndents.Peek().Clone(); + NextLineIndent = ThisLineIndent.Clone(); + } + else + { + ThisLineIndent = Parent.NextLineIndent.Clone(); + NextLineIndent = ThisLineIndent.Clone(); + } } public override IndentState Clone(CSharpIndentEngine engine) diff --git a/ICSharpCode.NRefactory.Tests/IndentationTests/BlockTest.cs b/ICSharpCode.NRefactory.Tests/IndentationTests/BlockTest.cs index 96ae82ba3..d0e6afd3a 100644 --- a/ICSharpCode.NRefactory.Tests/IndentationTests/BlockTest.cs +++ b/ICSharpCode.NRefactory.Tests/IndentationTests/BlockTest.cs @@ -1081,7 +1081,6 @@ public static void Main (string[] args) Assert.AreEqual("\t\t\t", indent.NextLineIndent); } - [Ignore("Fixme")] [Test] public void TestPreprocessorIndenting_Case1() { @@ -1096,7 +1095,7 @@ static void Foo (int arg) { #if !DEBUG if (arg > 0) { - $#else + #else$ if (arg < 0) { #endif @@ -1108,10 +1107,8 @@ public static void Main () } }", policy); Assert.AreEqual("\t\t", indent.ThisLineIndent); - Assert.AreEqual("\t\t", indent.NextLineIndent); } - [Ignore("Fixme")] [Test] public void TestPreprocessorIndenting_Case2() { @@ -1127,7 +1124,7 @@ static void Foo (int arg) #if !DEBUG if (arg > 0) { #else - $if (arg < 0) { + if (arg < 0) {$ #endif } @@ -1169,9 +1166,5 @@ public static void Main () Assert.AreEqual("\t\t\t", indent.ThisLineIndent); Assert.AreEqual("\t\t\t", indent.NextLineIndent); } - - - - } }