Browse Source

Fixed some preprocessor directive tests.

pull/45/merge
Mike Krüger 12 years ago
parent
commit
ae6b9e27cb
  1. 34
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs
  2. 34
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  3. 5
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  4. 2
      ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs
  5. 30
      ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs
  6. 6
      ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs
  7. 22
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs

34
ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs

@ -24,6 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
@ -45,6 +46,39 @@ namespace ICSharpCode.NRefactory.CSharp
Pragma = 11, Pragma = 11,
Line = 12 Line = 12
} }
public class PragmaWarningPreprocssorDirective : PreProcessorDirective
{
public bool Disable {
get;
set;
}
List<int> warningList = new List<int> ();
public IList<int> WarningList {
get {
return warningList;
}
}
public PragmaWarningPreprocssorDirective(TextLocation startLocation, TextLocation endLocation) : base (PreProcessorDirectiveType.Pragma, startLocation, endLocation)
{
}
public PragmaWarningPreprocssorDirective(string argument = null) : base (PreProcessorDirectiveType.Pragma, argument)
{
}
public void AddWarnings(IEnumerable<int> warningCodes)
{
warningList.AddRange(warningCodes);
}
public void AddWarnings(params int[] warningCodes)
{
warningList.AddRange(warningCodes);
}
}
public class PreProcessorDirective : AstNode public class PreProcessorDirective : AstNode
{ {

34
ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs

@ -3650,13 +3650,22 @@ namespace ICSharpCode.NRefactory.CSharp
}; };
role = Roles.Comment; role = Roles.Comment;
} else if (!GenerateTypeSystemMode) { } else if (!GenerateTypeSystemMode) {
var directive = special as SpecialsBag.PreProcessorDirective; var pragmaDirective = special as SpecialsBag.PragmaPreProcessorDirective;
if (directive != null) { if (pragmaDirective != null) {
newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.CSharp.PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol)) { var pragma = new PragmaWarningPreprocssorDirective(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), new TextLocation(pragmaDirective.EndLine, pragmaDirective.EndCol));
Argument = directive.Arg, pragma.Disable = pragmaDirective.Disalbe;
Take = directive.Take pragma.AddWarnings(pragmaDirective.Codes);
}; newLeaf = pragma;
role = Roles.PreProcessorDirective; role = Roles.PreProcessorDirective;
} else {
var directive = special as SpecialsBag.PreProcessorDirective;
if (directive != null) {
newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.CSharp.PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol)) {
Argument = directive.Arg,
Take = directive.Take
};
role = Roles.PreProcessorDirective;
}
} }
} }
if (newLeaf != null) { if (newLeaf != null) {
@ -3802,7 +3811,18 @@ namespace ICSharpCode.NRefactory.CSharp
} }
conversionVisitor.Unit.FileName = fileName; conversionVisitor.Unit.FileName = fileName;
conversionVisitor.Unit.ConditionalSymbols = top.Conditionals.Concat (compilerSettings.ConditionalSymbols).ToArray (); List<string> conditionals = new List<string>();
foreach (var settings in compilerSettings.ConditionalSymbols) {
if (top.Conditionals.ContainsKey(settings) && !top.Conditionals [settings])
continue;
conditionals.Add(settings);
}
foreach (var kv in top.Conditionals) {
if (!kv.Value || compilerSettings.ConditionalSymbols.Contains (kv.Key))
continue;
conditionals.Add(kv.Key);
}
conversionVisitor.Unit.ConditionalSymbols = conditionals;
return conversionVisitor.Unit; return conversionVisitor.Unit;
} }

5
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs

@ -2456,6 +2456,7 @@ namespace Mono.CSharp
// //
if (length == pragma_warning_disable.Length) { if (length == pragma_warning_disable.Length) {
bool disable = IsTokenIdentifierEqual (pragma_warning_disable); bool disable = IsTokenIdentifierEqual (pragma_warning_disable);
sbag.SetPragmaDisable (disable);
if (disable || IsTokenIdentifierEqual (pragma_warning_restore)) { if (disable || IsTokenIdentifierEqual (pragma_warning_restore)) {
// skip over white space // skip over white space
while (c == ' ' || c == '\t') while (c == ' ' || c == '\t')
@ -2483,6 +2484,7 @@ namespace Mono.CSharp
do { do {
code = TokenizePragmaNumber (ref c); code = TokenizePragmaNumber (ref c);
if (code > 0) { if (code > 0) {
sbag.AddPragmaCode (code);
if (disable) { if (disable) {
Report.RegisterWarningRegion (loc).WarningDisable (loc, code, context.Report); Report.RegisterWarningRegion (loc).WarningDisable (loc, code, context.Report);
} else { } else {
@ -2821,6 +2823,7 @@ namespace Mono.CSharp
} }
if ((state & TAKING) != 0) { if ((state & TAKING) != 0) {
sbag.SkipIf ();
ifstack.Push (0); ifstack.Push (0);
return false; return false;
} }
@ -2830,6 +2833,7 @@ namespace Mono.CSharp
return true; return true;
} }
sbag.SkipIf ();
ifstack.Push (state); ifstack.Push (state);
return false; return false;
} }
@ -3609,6 +3613,7 @@ namespace Mono.CSharp
if (c == '#') { if (c == '#') {
if (ParsePreprocessingDirective (false)) if (ParsePreprocessingDirective (false))
break; break;
sbag.StartComment(SpecialsBag.CommentType.InactiveCode, false, line, 1);
} }
sbag.PushCommentChar (c); sbag.PushCommentChar (c);
directive_expected = false; directive_expected = false;

2
ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs

@ -419,7 +419,7 @@ namespace Mono.CSharp
public ModuleContainer ModuleCompiled { get; set; } public ModuleContainer ModuleCompiled { get; set; }
public LocationsBag LocationsBag { get; set; } public LocationsBag LocationsBag { get; set; }
public SpecialsBag SpecialsBag { get; set; } public SpecialsBag SpecialsBag { get; set; }
public IEnumerable<string> Conditionals { get; set; } public IDictionary<string, bool> Conditionals { get; set; }
public object LastYYValue { get; set; } public object LastYYValue { get; set; }
} }

30
ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs

@ -483,6 +483,16 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
} }
} }
public class PragmaPreProcessorDirective : PreProcessorDirective
{
public bool Disalbe { get; set; }
public List<int> Codes = new List<int> ();
public PragmaPreProcessorDirective (int line, int col, int endLine, int endCol, Tokenizer.PreprocessorDirective cmd, string arg) : base (line, col, endLine, endCol, cmd, arg)
{
}
}
public class PreProcessorDirective : SpecialBase public class PreProcessorDirective : SpecialBase
{ {
public readonly int Line; public readonly int Line;
@ -562,7 +572,25 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
{ {
if (inComment) if (inComment)
EndComment (startLine, startCol); EndComment (startLine, startCol);
Specials.Add (new PreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg)); Specials.Add (cmd == Tokenizer.PreprocessorDirective.Pragma ? new PragmaPreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg) : new PreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg));
}
[Conditional ("FULL_AST")]
public void SetPragmaDisable(bool disable)
{
var pragmaDirective = Specials [Specials.Count - 1] as PragmaPreProcessorDirective;
if (pragmaDirective == null)
return;
pragmaDirective.Disalbe = disable;
}
[Conditional ("FULL_AST")]
public void AddPragmaCode(int code)
{
var pragmaDirective = Specials [Specials.Count - 1] as PragmaPreProcessorDirective;
if (pragmaDirective == null)
return;
pragmaDirective.Codes.Add (code);
} }
public enum NewLine { Unix, Windows } public enum NewLine { Unix, Windows }

6
ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs

@ -674,11 +674,9 @@ namespace Mono.CSharp {
} }
} }
public IEnumerable<string> Conditionals { public IDictionary<string, bool> Conditionals {
get { get {
if (conditionals == null) return conditionals ?? new Dictionary<string, bool> ();
return Enumerable.Empty<string> ();
return conditionals.Where (kv => kv.Value).Select (kv => kv.Key);
} }
} }

22
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs

@ -66,7 +66,6 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual(new TextLocation(4, 8), pp.Last().EndLocation); Assert.AreEqual(new TextLocation(4, 8), pp.Last().EndLocation);
} }
[Ignore("Fixme!")]
[Test] [Test]
public void NestedInactiveIf() public void NestedInactiveIf()
{ {
@ -94,7 +93,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Roles.Comment, Roles.Comment,
Roles.PreProcessorDirective, Roles.PreProcessorDirective,
Roles.RBrace Roles.RBrace
}, ns.Children.Select(c => c.Role).ToArray()); }, ns.Children.Where (c => !(c is NewLineNode)).Select(c => c.Role).ToArray());
} }
[Ignore("Fixme!")] [Ignore("Fixme!")]
@ -118,19 +117,19 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Roles.Comment, Roles.Comment,
Roles.PreProcessorDirective, Roles.PreProcessorDirective,
Roles.RBrace Roles.RBrace
}, ns.Children.Select(c => c.Role).ToArray()); }, ns.Children.Where (c => !(c is NewLineNode)).Select(c => c.Role).ToArray());
Assert.AreEqual(CommentType.SingleLine, ns.GetChildrenByRole(Roles.Comment).First().CommentType); Assert.AreEqual(CommentType.SingleLine, ns.GetChildrenByRole(Roles.Comment).First().CommentType);
Assert.AreEqual(CommentType.InactiveCode, ns.GetChildrenByRole(Roles.Comment).Last().CommentType); Assert.AreEqual(CommentType.InactiveCode, ns.GetChildrenByRole(Roles.Comment).Last().CommentType);
} }
[Ignore("Fixme!")]
[Test] [Test]
public void PragmaWarning() public void PragmaWarning()
{ {
string program = "#pragma warning disable 809"; string program = "#pragma warning disable 809";
var ppd = ParseUtilCSharp.ParseGlobal<PreProcessorDirective>(program); var ppd = ParseUtilCSharp.ParseGlobal<PragmaWarningPreprocssorDirective>(program);
Assert.AreEqual(PreProcessorDirectiveType.Pragma, ppd.Type); Assert.AreEqual(PreProcessorDirectiveType.Pragma, ppd.Type);
Assert.AreEqual("warning disable 809", ppd.Argument); Assert.IsTrue(ppd.Disable);
Assert.IsTrue(ppd.WarningList.Contains (809));
} }
const string elifProgram = @" const string elifProgram = @"
@ -141,20 +140,18 @@ class B { }
#endif"; #endif";
[Test] [Test]
[Ignore("parser bug (missing comment node)")]
public void ElifBothFalse() public void ElifBothFalse()
{ {
CSharpParser parser = new CSharpParser(); CSharpParser parser = new CSharpParser();
var syntaxTree = parser.Parse(elifProgram, "elif.cs"); var syntaxTree = parser.Parse(elifProgram, "elif.cs");
Assert.IsFalse(parser.HasErrors); Assert.IsFalse(parser.HasErrors);
Assert.AreEqual(new Role[] { Assert.AreEqual(new Role[] {
Roles.PreProcessorDirective, Roles.PreProcessorDirective,
Roles.Comment, Roles.Comment,
Roles.PreProcessorDirective, Roles.PreProcessorDirective,
Roles.Comment, Roles.Comment,
Roles.PreProcessorDirective Roles.PreProcessorDirective
}, syntaxTree.Children.Select(c => c.Role).ToArray()); }, syntaxTree.Children.Where (c => !(c is NewLineNode)).Select(c => c.Role).ToArray());
var aaa = syntaxTree.GetChildrenByRole(Roles.PreProcessorDirective).ElementAt(0); var aaa = syntaxTree.GetChildrenByRole(Roles.PreProcessorDirective).ElementAt(0);
Assert.IsFalse(aaa.Take); Assert.IsFalse(aaa.Take);
Assert.AreEqual(PreProcessorDirectiveType.If, aaa.Type); Assert.AreEqual(PreProcessorDirectiveType.If, aaa.Type);
@ -167,7 +164,6 @@ class B { }
} }
[Test] [Test]
[Ignore("parser bug (bbb.Take is true, should be false)")]
public void ElifBothTrue() public void ElifBothTrue()
{ {
CSharpParser parser = new CSharpParser(); CSharpParser parser = new CSharpParser();
@ -181,7 +177,7 @@ class B { }
Roles.PreProcessorDirective, Roles.PreProcessorDirective,
Roles.Comment, Roles.Comment,
Roles.PreProcessorDirective Roles.PreProcessorDirective
}, syntaxTree.Children.Select(c => c.Role).ToArray()); }, syntaxTree.Children.Where (c => !(c is NewLineNode)).Select(c => c.Role).ToArray());
var aaa = syntaxTree.GetChildrenByRole(Roles.PreProcessorDirective).ElementAt(0); var aaa = syntaxTree.GetChildrenByRole(Roles.PreProcessorDirective).ElementAt(0);
Assert.IsTrue(aaa.Take); Assert.IsTrue(aaa.Take);
Assert.AreEqual(PreProcessorDirectiveType.If, aaa.Type); Assert.AreEqual(PreProcessorDirectiveType.If, aaa.Type);
@ -194,7 +190,6 @@ class B { }
} }
[Test] [Test]
[Ignore("parser bug (bbb.Take is true, should be false)")]
public void ElifFirstTaken() public void ElifFirstTaken()
{ {
CSharpParser parser = new CSharpParser(); CSharpParser parser = new CSharpParser();
@ -208,7 +203,7 @@ class B { }
Roles.PreProcessorDirective, Roles.PreProcessorDirective,
Roles.Comment, Roles.Comment,
Roles.PreProcessorDirective Roles.PreProcessorDirective
}, syntaxTree.Children.Select(c => c.Role).ToArray()); }, syntaxTree.Children.Where (c => !(c is NewLineNode)).Select(c => c.Role).ToArray());
var aaa = syntaxTree.GetChildrenByRole(Roles.PreProcessorDirective).ElementAt(0); var aaa = syntaxTree.GetChildrenByRole(Roles.PreProcessorDirective).ElementAt(0);
Assert.IsTrue(aaa.Take); Assert.IsTrue(aaa.Take);
Assert.AreEqual(PreProcessorDirectiveType.If, aaa.Type); Assert.AreEqual(PreProcessorDirectiveType.If, aaa.Type);
@ -247,7 +242,6 @@ class B { }
} }
[Test] [Test]
[Ignore("parser bug (BBB is missing)")]
public void ConditionalSymbolTest() public void ConditionalSymbolTest()
{ {
const string program = @"// Test const string program = @"// Test

Loading…
Cancel
Save