| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library source_file; | 5 library source_file; |
| 6 | 6 |
| 7 import 'dart:math'; | 7 import 'dart:math'; |
| 8 import 'dart:convert' show UTF8; | 8 import 'dart:convert' show UTF8; |
| 9 | 9 |
| 10 /** | 10 /** |
| 11 * Represents a file of source code. The content can be either a [String] or | 11 * Represents a file of source code. The content can be either a [String] or |
| 12 * a UTF-8 encoded [List<int>] of bytes. | 12 * a UTF-8 encoded [List<int>] of bytes. |
| 13 */ | 13 */ |
| 14 abstract class SourceFile { | 14 abstract class SourceFile { |
| 15 | 15 |
| 16 /** The name of the file. */ | 16 /** The name of the file. */ |
| 17 final String filename; | 17 String get filename; |
| 18 | |
| 19 SourceFile(this.filename); | |
| 20 | 18 |
| 21 /** The text content of the file represented as a String. */ | 19 /** The text content of the file represented as a String. */ |
| 22 String slowText(); | 20 String slowText(); |
| 23 | 21 |
| 24 /** The content of the file represented as a UTF-8 encoded [List<int>]. */ | 22 /** The content of the file represented as a UTF-8 encoded [List<int>]. */ |
| 25 List<int> slowUtf8Bytes(); | 23 List<int> slowUtf8Bytes(); |
| 26 | 24 |
| 27 /** | 25 /** |
| 28 * The length of the string representation of this source file, i.e., | 26 * The length of the string representation of this source file, i.e., |
| 29 * equivalent to [:slowText().length:], but faster. | 27 * equivalent to [:slowText().length:], but faster. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 * Returns the column number for the offset [position] in the string | 101 * Returns the column number for the offset [position] in the string |
| 104 * representation of this source file. | 102 * representation of this source file. |
| 105 */ | 103 */ |
| 106 int getColumn(int line, int position) { | 104 int getColumn(int line, int position) { |
| 107 return position - lineStarts[line]; | 105 return position - lineStarts[line]; |
| 108 } | 106 } |
| 109 | 107 |
| 110 String slowSubstring(int start, int end); | 108 String slowSubstring(int start, int end); |
| 111 | 109 |
| 112 /** | 110 /** |
| 113 * Create a pretty string representation from a character position | 111 * Create a pretty string representation for [message] from a character |
| 114 * in the file. | 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. |
| 115 */ | 120 */ |
| 116 String getLocationMessage(String message, int start, int end, | 121 String getLocationMessage(String message, int start, int end, |
| 117 bool includeText, String color(String x)) { | 122 {bool includeSourceLine: true, |
| 123 String colorize(String text)}) { |
| 124 if (colorize == null) { |
| 125 colorize = (text) => text; |
| 126 } |
| 118 var line = getLine(start); | 127 var line = getLine(start); |
| 119 var column = getColumn(line, start); | 128 var column = getColumn(line, start); |
| 120 | 129 |
| 121 var buf = new StringBuffer('${filename}:'); | 130 var buf = new StringBuffer('${filename}:'); |
| 122 if (start != end || start != 0) { | 131 if (start != end || start != 0) { |
| 123 // Line/column info is relevant. | 132 // Line/column info is relevant. |
| 124 buf.write('${line + 1}:${column + 1}:'); | 133 buf.write('${line + 1}:${column + 1}:'); |
| 125 } | 134 } |
| 126 buf.write('\n$message\n'); | 135 buf.write('\n$message\n'); |
| 127 | 136 |
| 128 if (start != end && includeText) { | 137 if (start != end && includeSourceLine) { |
| 129 String textLine; | 138 String textLine; |
| 130 // +1 for 0-indexing, +1 again to avoid the last line of the file | 139 // +1 for 0-indexing, +1 again to avoid the last line of the file |
| 131 if ((line + 2) < lineStarts.length) { | 140 if ((line + 2) < lineStarts.length) { |
| 132 textLine = slowSubstring(lineStarts[line], lineStarts[line+1]); | 141 textLine = slowSubstring(lineStarts[line], lineStarts[line+1]); |
| 133 } else { | 142 } else { |
| 134 textLine = '${slowSubstring(lineStarts[line], length)}\n'; | 143 textLine = '${slowSubstring(lineStarts[line], length)}\n'; |
| 135 } | 144 } |
| 136 | 145 |
| 137 int toColumn = min(column + (end-start), textLine.length); | 146 int toColumn = min(column + (end-start), textLine.length); |
| 138 buf.write(textLine.substring(0, column)); | 147 buf.write(textLine.substring(0, column)); |
| 139 buf.write(color(textLine.substring(column, toColumn))); | 148 buf.write(colorize(textLine.substring(column, toColumn))); |
| 140 buf.write(textLine.substring(toColumn)); | 149 buf.write(textLine.substring(toColumn)); |
| 141 | 150 |
| 142 int i = 0; | 151 int i = 0; |
| 143 for (; i < column; i++) { | 152 for (; i < column; i++) { |
| 144 buf.write(' '); | 153 buf.write(' '); |
| 145 } | 154 } |
| 146 | 155 |
| 147 for (; i < toColumn; i++) { | 156 for (; i < toColumn; i++) { |
| 148 buf.write(color('^')); | 157 buf.write(colorize('^')); |
| 149 } | 158 } |
| 150 } | 159 } |
| 151 | 160 |
| 152 return buf.toString(); | 161 return buf.toString(); |
| 153 } | 162 } |
| 154 } | 163 } |
| 155 | 164 |
| 156 class Utf8BytesSourceFile extends SourceFile { | 165 class Utf8BytesSourceFile extends SourceFile { |
| 166 final String filename; |
| 157 | 167 |
| 158 /** The UTF-8 encoded content of the source file. */ | 168 /** The UTF-8 encoded content of the source file. */ |
| 159 final List<int> content; | 169 final List<int> content; |
| 160 | 170 |
| 161 Utf8BytesSourceFile(String filename, this.content) : super(filename); | 171 Utf8BytesSourceFile(this.filename, this.content); |
| 162 | 172 |
| 163 String slowText() => UTF8.decode(content); | 173 String slowText() => UTF8.decode(content); |
| 164 | 174 |
| 165 List<int> slowUtf8Bytes() => content; | 175 List<int> slowUtf8Bytes() => content; |
| 166 | 176 |
| 167 String slowSubstring(int start, int end) { | 177 String slowSubstring(int start, int end) { |
| 168 // TODO(lry): to make this faster, the scanner could record the UTF-8 slack | 178 // TODO(lry): to make this faster, the scanner could record the UTF-8 slack |
| 169 // for all positions of the source text. We could use [:content.sublist:]. | 179 // for all positions of the source text. We could use [:content.sublist:]. |
| 170 return slowText().substring(start, end); | 180 return slowText().substring(start, end); |
| 171 } | 181 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 189 | 199 |
| 190 String slowText() { | 200 String slowText() { |
| 191 if (cachedText == null) { | 201 if (cachedText == null) { |
| 192 cachedText = super.slowText(); | 202 cachedText = super.slowText(); |
| 193 } | 203 } |
| 194 return cachedText; | 204 return cachedText; |
| 195 } | 205 } |
| 196 } | 206 } |
| 197 | 207 |
| 198 class StringSourceFile extends SourceFile { | 208 class StringSourceFile extends SourceFile { |
| 199 | 209 final String filename; |
| 200 final String text; | 210 final String text; |
| 201 | 211 |
| 202 StringSourceFile(String filename, this.text) : super(filename); | 212 StringSourceFile(this.filename, this.text); |
| 203 | 213 |
| 204 int get length => text.length; | 214 int get length => text.length; |
| 205 set length(int v) { } | 215 set length(int v) { } |
| 206 | 216 |
| 207 String slowText() => text; | 217 String slowText() => text; |
| 208 | 218 |
| 209 List<int> slowUtf8Bytes() => UTF8.encode(text); | 219 List<int> slowUtf8Bytes() => UTF8.encode(text); |
| 210 | 220 |
| 211 String slowSubstring(int start, int end) => text.substring(start, end); | 221 String slowSubstring(int start, int end) => text.substring(start, end); |
| 212 } | 222 } |
| OLD | NEW |