Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1566)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/source_file.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 'dart:math';
8 import 'dart:convert' show UTF8;
9
10 /**
11 * Represents a file of source code. The content can be either a [String] or
12 * a UTF-8 encoded [List<int>] of bytes.
13 */
14 abstract class SourceFile {
15
16 /** The name of the file. */
17 String get filename;
18
19 /** The text content of the file represented as a String. */
20 String slowText();
21
22 /** The content of the file represented as a UTF-8 encoded [List<int>]. */
23 List<int> slowUtf8Bytes();
24
25 /**
26 * The length of the string representation of this source file, i.e.,
27 * equivalent to [:slowText().length:], but faster.
28 */
29 int get length;
30
31 /**
32 * Sets the string length of this source file. For source files based on UTF-8
33 * byte arrays, the string length is computed and assigned by the scanner.
34 */
35 set length(int v);
36
37 /**
38 * A map from line numbers to offsets in the string text representation of
39 * this source file.
40 */
41 List<int> get lineStarts {
42 if (lineStartsCache == null) {
43 // When reporting errors during scanning, the line numbers are not yet
44 // available and need to be computed using this slow path.
45 lineStartsCache = lineStartsFromString(slowText());
46 }
47 return lineStartsCache;
48 }
49
50 /**
51 * Sets the line numbers map for this source file. This map is computed and
52 * assigned by the scanner, avoiding a separate traversal of the source file.
53 *
54 * The map contains one additional entry at the end of the file, as if the
55 * source file had one more empty line at the end. This simplifies the binary
56 * search in [getLine].
57 */
58 set lineStarts(List<int> v) => lineStartsCache = v;
59
60 List<int> lineStartsCache;
61
62 List<int> lineStartsFromString(String text) {
63 var starts = [0];
64 var index = 0;
65 while (index < text.length) {
66 index = text.indexOf('\n', index) + 1;
67 if (index <= 0) break;
68 starts.add(index);
69 }
70 starts.add(text.length + 1); // One additional line start at the end.
71 return starts;
72 }
73
74 /**
75 * Returns the line number for the offset [position] in the string
76 * representation of this source file.
77 */
78 int getLine(int position) {
79 List<int> starts = lineStarts;
80 if (position < 0 || starts.last <= position) {
81 throw 'bad position #$position in file $filename with '
82 'length ${length}.';
83 }
84 int first = 0;
85 int count = starts.length;
86 while (count > 1) {
87 int step = count ~/ 2;
88 int middle = first + step;
89 int lineStart = starts[middle];
90 if (position < lineStart) {
91 count = step;
92 } else {
93 first = middle;
94 count -= step;
95 }
96 }
97 return first;
98 }
99
100 /**
101 * Returns the column number for the offset [position] in the string
102 * representation of this source file.
103 */
104 int getColumn(int line, int position) {
105 return position - lineStarts[line];
106 }
107
108 String slowSubstring(int start, int end);
109
110 /**
111 * Create a pretty string representation for [message] from a character
112 * range `[start, end]` in this file.
113 *
114 * If [includeSourceLine] is `true` the first source line code line that
115 * contains the range will be included as well as marker characters ('^')
116 * underlining the range.
117 *
118 * Use [colorize] to wrap source code text and marker characters in color
119 * escape codes.
120 */
121 String getLocationMessage(String message, int start, int end,
122 {bool includeSourceLine: true,
123 String colorize(String text)}) {
124 if (colorize == null) {
125 colorize = (text) => text;
126 }
127 var line = getLine(start);
128 var column = getColumn(line, start);
129
130 var buf = new StringBuffer('${filename}:');
131 if (start != end || start != 0) {
132 // Line/column info is relevant.
133 buf.write('${line + 1}:${column + 1}:');
134 }
135 buf.write('\n$message\n');
136
137 if (start != end && includeSourceLine) {
138 String textLine;
139 // +1 for 0-indexing, +1 again to avoid the last line of the file
140 if ((line + 2) < lineStarts.length) {
141 textLine = slowSubstring(lineStarts[line], lineStarts[line+1]);
142 } else {
143 textLine = '${slowSubstring(lineStarts[line], length)}\n';
144 }
145
146 int toColumn = min(column + (end-start), textLine.length);
147 buf.write(textLine.substring(0, column));
148 buf.write(colorize(textLine.substring(column, toColumn)));
149 buf.write(textLine.substring(toColumn));
150
151 int i = 0;
152 for (; i < column; i++) {
153 buf.write(' ');
154 }
155
156 for (; i < toColumn; i++) {
157 buf.write(colorize('^'));
158 }
159 }
160
161 return buf.toString();
162 }
163 }
164
165 class Utf8BytesSourceFile extends SourceFile {
166 final String filename;
167
168 /** The UTF-8 encoded content of the source file. */
169 final List<int> content;
170
171 Utf8BytesSourceFile(this.filename, this.content);
172
173 String slowText() => UTF8.decode(content);
174
175 List<int> slowUtf8Bytes() => content;
176
177 String slowSubstring(int start, int end) {
178 // TODO(lry): to make this faster, the scanner could record the UTF-8 slack
179 // for all positions of the source text. We could use [:content.sublist:].
180 return slowText().substring(start, end);
181 }
182
183 int get length {
184 if (lengthCache == -1) {
185 // During scanning the length is not yet assigned, so we use a slow path.
186 length = slowText().length;
187 }
188 return lengthCache;
189 }
190 set length(int v) => lengthCache = v;
191 int lengthCache = -1;
192 }
193
194 class CachingUtf8BytesSourceFile extends Utf8BytesSourceFile {
195 String cachedText;
196
197 CachingUtf8BytesSourceFile(String filename, List<int> content)
198 : super(filename, content);
199
200 String slowText() {
201 if (cachedText == null) {
202 cachedText = super.slowText();
203 }
204 return cachedText;
205 }
206 }
207
208 class StringSourceFile extends SourceFile {
209 final String filename;
210 final String text;
211
212 StringSourceFile(this.filename, this.text);
213
214 int get length => text.length;
215 set length(int v) { }
216
217 String slowText() => text;
218
219 List<int> slowUtf8Bytes() => UTF8.encode(text);
220
221 String slowSubstring(int start, int end) => text.substring(start, end);
222 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698