OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #library('source_file'); | |
6 | |
7 #import('colors.dart'); | |
8 | |
9 /** | |
10 * Represents a file of source code. | |
11 */ | |
12 class SourceFile { | |
13 | |
14 /** The name of the file. */ | |
15 final String filename; | |
16 | |
17 /** The text content of the file. */ | |
18 final String text; | |
19 | |
20 List<int> _lineStarts; | |
21 | |
22 SourceFile(this.filename, this.text); | |
23 | |
24 List<int> get lineStarts() { | |
25 if (_lineStarts == null) { | |
26 var starts = [0]; | |
27 var index = 0; | |
28 while (index < text.length) { | |
29 index = text.indexOf('\n', index) + 1; | |
30 if (index <= 0) break; | |
31 starts.add(index); | |
32 } | |
33 starts.add(text.length + 1); | |
34 _lineStarts = starts; | |
35 } | |
36 return _lineStarts; | |
37 } | |
38 | |
39 int getLine(int position) { | |
40 // TODO(jimhug): Implement as binary search. | |
41 var starts = lineStarts; | |
42 for (int i=0; i < starts.length; i++) { | |
43 if (starts[i] > position) return i-1; | |
44 } | |
45 throw 'bad position'; | |
46 } | |
47 | |
48 int getColumn(int line, int position) { | |
49 return position - lineStarts[line]; | |
50 } | |
51 | |
52 /** | |
53 * Create a pretty string representation from a character position | |
54 * in the file. | |
55 */ | |
56 String getLocationMessage(String message, int start, | |
57 [int end, bool includeText=false, bool useColors = true]) { | |
58 var line = getLine(start); | |
59 var column = getColumn(line, start); | |
60 | |
61 var buf = new StringBuffer( | |
62 '${filename}:${line + 1}:${column + 1}: $message'); | |
63 if (includeText) { | |
64 buf.add('\n'); | |
65 var textLine; | |
66 // +1 for 0-indexing, +1 again to avoid the last line of the file | |
67 if ((line + 2) < _lineStarts.length) { | |
68 textLine = text.substring(_lineStarts[line], _lineStarts[line+1]); | |
69 } else { | |
70 textLine = text.substring(_lineStarts[line]) + '\n'; | |
71 } | |
72 | |
73 int toColumn = Math.min(column + (end-start), textLine.length); | |
74 if (useColors) { | |
75 buf.add(textLine.substring(0, column)); | |
76 buf.add(RED_COLOR); | |
77 buf.add(textLine.substring(column, toColumn)); | |
78 buf.add(NO_COLOR); | |
79 buf.add(textLine.substring(toColumn)); | |
80 } else { | |
81 buf.add(textLine); | |
82 } | |
83 | |
84 int i = 0; | |
85 for (; i < column; i++) { | |
86 buf.add(' '); | |
87 } | |
88 | |
89 if (useColors) buf.add(RED_COLOR); | |
90 for (; i < toColumn; i++) { | |
91 buf.add('^'); | |
92 } | |
93 if (useColors) buf.add(NO_COLOR); | |
94 } | |
95 | |
96 return buf.toString(); | |
97 } | |
98 } | |
OLD | NEW |