2 // ConditionTextExtractor.cs
5 // Chris Bacon (chrisbacon76@gmail.com)
7 // Copyright (C) 2010 Chris Bacon
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections.Generic;
33 using Mono.CodeContracts.Rewrite.AstVisitors;
36 namespace Mono.CodeContracts.Rewrite {
37 class ConditionTextExtractor {
39 public ConditionTextExtractor (string filename, SourcePositionVisitor.CodePosition start, SourcePositionVisitor.CodePosition end)
41 this.filename = filename;
46 private string filename;
47 private SourcePositionVisitor.CodePosition start, end;
56 public string GetConditionText ()
58 if (this.filename == null || this.start.IsEmpty || this.end.IsEmpty){
59 return "<unknown source code position>";
63 lines = File.ReadAllLines (this.filename);
65 return "<cannot access source code>";
68 StringBuilder sb = new StringBuilder ();
69 for (int i = this.start.Line; i <= this.end.Line; i++) {
70 string line = lines [i - 1];
71 if (i == this.end.Line && this.end.Column != 0) {
72 line = line.Substring (0, this.end.Column - 1);
74 if (i == this.start.Line && this.start.Column != 0) {
75 line = line.Substring (this.start.Column - 1);
77 sb.Append (line.Trim());
79 string cndStr = sb.ToString ();
81 this.state = State.FunctionName;
83 var cnd = this.RunStateMachine (cndStr);
85 return cnd.ToString ().Trim ();
87 return "<source-code parse error>";
91 private StringBuilder RunStateMachine (string line)
93 StringBuilder cnd = new StringBuilder ();
95 bool inDoubleQuotes = false;
96 bool inSingleQuotes = false;
97 bool inEscape = false;
98 foreach (char c in line) {
100 case State.FunctionName:
102 this.state = State.Parameters;
105 case State.Parameters:
108 if (inBrackets == 0 && !inDoubleQuotes && !inSingleQuotes) {
113 if (!inDoubleQuotes && !inSingleQuotes) {
118 if (!inDoubleQuotes && !inSingleQuotes) {
119 if (inBrackets == 0) {
127 inDoubleQuotes = !inDoubleQuotes;
132 inSingleQuotes = !inSingleQuotes;
144 throw new NotSupportedException ("Cannot handle state: " + this.state);
148 return new StringBuilder ("<bad source code>");