~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.Diagnostics;
 
21
using System.IO;
 
22
using System.Text;
 
23
using ICSharpCode.NRefactory.CSharp;
 
24
using ICSharpCode.NRefactory.Editor;
 
25
using ICSharpCode.NRefactory.PatternMatching;
 
26
 
 
27
namespace ICSharpCode.NRefactory.ConsistencyCheck
 
28
{
 
29
        /// <summary>
 
30
        /// Tests parser + output visitor by roundtripping code.
 
31
        /// Everything but whitespace must be preserved.
 
32
        /// </summary>
 
33
        public class RoundtripTest
 
34
        {
 
35
                public static void RunTest(CSharpFile file)
 
36
                {
 
37
                        string code = file.OriginalText.Replace("\r\n", "\n");
 
38
                        Debug.Assert(code.IndexOf('\r') < 0);
 
39
                        if (code.Contains("#pragma"))
 
40
                                return; // skip code with preprocessor directives
 
41
                        if (code.Contains("enum VarianceModifier") || file.FileName.EndsWith("ecore.cs") || file.FileName.EndsWith("method.cs"))
 
42
                                return; // skip enum with ; at end (see TypeDeclarationTests.EnumWithSemicolonAtEnd)
 
43
                        if (file.FileName.EndsWith("KnownTypeReference.cs") || file.FileName.EndsWith("typemanager.cs") || file.FileName.EndsWith("GetAllBaseTypesTest.cs") || file.FileName.EndsWith("Tokens.cs") || file.FileName.EndsWith("OpCode.cs") || file.FileName.EndsWith("MainWindow.cs"))
 
44
                                return; // skip due to optional , at end of array initializer (see ArrayCreateExpressionTests.ArrayInitializerWithCommaAtEnd)
 
45
                        if (file.FileName.EndsWith("cs-parser.cs"))
 
46
                                return; // skip due to completely messed up comment locations
 
47
                        if (file.FileName.Contains("FormattingTests") || file.FileName.Contains("ContextAction") || file.FileName.Contains("CodeCompletion"))
 
48
                                return; // skip due to AttributeSectionTests.AttributeWithEmptyParenthesis
 
49
                        if (file.FileName.EndsWith("TypeSystemTests.TestCase.cs") || file.FileName.EndsWith("AssemblyInfo.cs"))
 
50
                                return; // skip due to AttributeSectionTests.AssemblyAttributeBeforeNamespace
 
51
                        if (file.FileName.EndsWith("dynamic.cs") || file.FileName.EndsWith("expression.cs"))
 
52
                                return; // skip due to PreprocessorDirectiveTests.NestedInactiveIf
 
53
                        if (file.FileName.EndsWith("property.cs"))
 
54
                                return; // skip due to PreprocessorDirectiveTests.CommentOnEndOfIfDirective
 
55
                        if (file.FileName.EndsWith("DefaultResolvedTypeDefinition.cs"))
 
56
                                return; // skip due to MethodDeclarationTests.GenericMethodWithMultipleConstraints
 
57
                        
 
58
                        Roundtrip(new CSharpParser(file.Project.CompilerSettings), file.FileName, code);
 
59
                        // After trying unix-style newlines, also try windows-style newlines:
 
60
                        Roundtrip(new CSharpParser(file.Project.CompilerSettings), file.FileName, code.Replace("\n", "\r\n"));
 
61
                }
 
62
                
 
63
                public static void Roundtrip(CSharpParser parser, string fileName, string code)
 
64
                {
 
65
                        // 1. Parse
 
66
                        SyntaxTree syntaxTree = parser.Parse(code, fileName);
 
67
                        if (parser.HasErrors)
 
68
                                throw new InvalidOperationException("There were parse errors.");
 
69
                        
 
70
                        // 2. Output
 
71
                        StringWriter w = new StringWriter();
 
72
                        syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ()));
 
73
                        string generatedCode = w.ToString().TrimEnd();
 
74
                        
 
75
                        // 3. Compare output with original (modulo whitespaces)
 
76
                        int pos2 = 0;
 
77
                        for (int pos1 = 0; pos1 < code.Length; pos1++) {
 
78
                                if (!char.IsWhiteSpace(code[pos1])) {
 
79
                                        while (pos2 < generatedCode.Length && char.IsWhiteSpace(generatedCode[pos2]))
 
80
                                                pos2++;
 
81
                                        if (pos2 >= generatedCode.Length || code[pos1] != generatedCode[pos2]) {
 
82
                                                ReadOnlyDocument doc = new ReadOnlyDocument(code);
 
83
                                                File.WriteAllText(Path.Combine(Program.TempPath, "roundtrip-error.cs"), generatedCode);
 
84
                                                throw new InvalidOperationException("Mismatch at " + doc.GetLocation(pos1) + " of file " + fileName);
 
85
                                        }
 
86
                                        pos2++;
 
87
                                }
 
88
                        }
 
89
                        if (pos2 != generatedCode.Length)
 
90
                                throw new InvalidOperationException("Mismatch at end of file " + fileName);
 
91
                        
 
92
                        // 3b - validate that there are no lone \r
 
93
                        if (generatedCode.Replace(w.NewLine, "\n").IndexOf('\r') >= 0)
 
94
                                throw new InvalidOperationException(@"Got lone \r in " + fileName);
 
95
                        
 
96
                        // 4. Parse generated output
 
97
                        SyntaxTree generatedCU;
 
98
                        try {
 
99
                                generatedCU = parser.Parse(generatedCode, fileName);
 
100
                        } catch {
 
101
                                File.WriteAllText(Path.Combine(Program.TempPath, "roundtrip-error.cs"), generatedCode, Encoding.Unicode);
 
102
                                throw;
 
103
                        }
 
104
                        
 
105
                        if (parser.HasErrors) {
 
106
                                File.WriteAllText(Path.Combine(Program.TempPath, "roundtrip-error.cs"), generatedCode);
 
107
                                throw new InvalidOperationException("There were parse errors in the roundtripped " + fileName);
 
108
                        }
 
109
                        
 
110
                        // 5. Compare AST1 with AST2
 
111
                        if (!syntaxTree.IsMatch(generatedCU))
 
112
                                throw new InvalidOperationException("AST match failed for " + fileName + ".");
 
113
                }
 
114
        }
 
115
}