OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /// ----------------------------------------------------------------------- | 5 /// ----------------------------------------------------------------------- |
6 /// ERROR HANDLING | 6 /// ERROR HANDLING |
7 /// ----------------------------------------------------------------------- | 7 /// ----------------------------------------------------------------------- |
8 /// | 8 /// |
9 /// As a rule of thumb, errors that can be detected statically are handled by | 9 /// As a rule of thumb, errors that can be detected statically are handled by |
10 /// the frontend, typically by translating the erroneous code into a 'throw' or | 10 /// the frontend, typically by translating the erroneous code into a 'throw' or |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 /// | 43 /// |
44 /// Use [Transformer] for bulk transformations that are likely to transform lots | 44 /// Use [Transformer] for bulk transformations that are likely to transform lots |
45 /// of nodes, and [TreeNode.replaceWith] for sparse transformations that mutate | 45 /// of nodes, and [TreeNode.replaceWith] for sparse transformations that mutate |
46 /// relatively few nodes. Or use whichever is more convenient. | 46 /// relatively few nodes. Or use whichever is more convenient. |
47 /// | 47 /// |
48 /// The AST can also be mutated by direct field manipulation, but the user then | 48 /// The AST can also be mutated by direct field manipulation, but the user then |
49 /// has to update parent pointers manually. | 49 /// has to update parent pointers manually. |
50 /// | 50 /// |
51 library kernel.ast; | 51 library kernel.ast; |
52 | 52 |
53 import 'dart:convert' show UTF8; | |
54 | |
53 import 'visitor.dart'; | 55 import 'visitor.dart'; |
54 export 'visitor.dart'; | 56 export 'visitor.dart'; |
55 | 57 |
56 import 'canonical_name.dart' show CanonicalName; | 58 import 'canonical_name.dart' show CanonicalName; |
57 export 'canonical_name.dart' show CanonicalName; | 59 export 'canonical_name.dart' show CanonicalName; |
58 | 60 |
59 import 'transformations/flags.dart'; | 61 import 'transformations/flags.dart'; |
60 import 'text/ast_to_text.dart'; | 62 import 'text/ast_to_text.dart'; |
61 import 'type_algebra.dart'; | 63 import 'type_algebra.dart'; |
62 import 'type_environment.dart'; | 64 import 'type_environment.dart'; |
(...skipping 4158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4221 if (node == child) { | 4223 if (node == child) { |
4222 return replacement; | 4224 return replacement; |
4223 } else { | 4225 } else { |
4224 return node; | 4226 return node; |
4225 } | 4227 } |
4226 } | 4228 } |
4227 } | 4229 } |
4228 | 4230 |
4229 class Source { | 4231 class Source { |
4230 final List<int> lineStarts; | 4232 final List<int> lineStarts; |
4233 | |
4231 final List<int> source; | 4234 final List<int> source; |
4232 | 4235 |
4236 String cachedText; | |
4237 | |
4233 Source(this.lineStarts, this.source); | 4238 Source(this.lineStarts, this.source); |
4239 | |
4240 /// Return the text corresponding to [line] which is a 1-based line number. | |
4241 String getTextLine(int line) { | |
4242 RangeError.checkValueInInterval( | |
4243 line, | |
4244 1, | |
4245 lineStarts.length, | |
4246 "line", | |
4247 "The value of 'line' ($line) must be between 1 and " | |
4248 "${lineStarts.length}."); | |
4249 if (source == null) return null; | |
4250 | |
4251 // -1 as line numbers start at 1. | |
4252 int index = line - 1; | |
4253 if (index + 1 == lineStarts.length) { | |
4254 // Last line. | |
4255 return cachedText.substring(lineStarts[index]); | |
asgerf
2017/04/03 08:34:55
cachedText could be null here. The initialization
ahe
2017/04/03 09:26:39
Done.
| |
4256 } else if (index < lineStarts.length) { | |
4257 cachedText ??= UTF8.decode(source, allowMalformed: true); | |
4258 return cachedText.substring(lineStarts[index], lineStarts[index + 1]); | |
4259 } | |
4260 // This shouldn't happen: should have been caught by the range check above. | |
4261 throw "Internal error"; | |
4262 } | |
4234 } | 4263 } |
4235 | 4264 |
4236 /// Returns the [Reference] object for the given member. | 4265 /// Returns the [Reference] object for the given member. |
4237 /// | 4266 /// |
4238 /// Returns `null` if the member is `null`. | 4267 /// Returns `null` if the member is `null`. |
4239 Reference getMemberReference(Member member) { | 4268 Reference getMemberReference(Member member) { |
4240 return member?.reference; | 4269 return member?.reference; |
4241 } | 4270 } |
4242 | 4271 |
4243 /// Returns the [Reference] object for the given class. | 4272 /// Returns the [Reference] object for the given class. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4275 /// library has not been assigned a canonical name yet. | 4304 /// library has not been assigned a canonical name yet. |
4276 /// | 4305 /// |
4277 /// Returns `null` if the library is `null`. | 4306 /// Returns `null` if the library is `null`. |
4278 CanonicalName getCanonicalNameOfLibrary(Library library) { | 4307 CanonicalName getCanonicalNameOfLibrary(Library library) { |
4279 if (library == null) return null; | 4308 if (library == null) return null; |
4280 if (library.canonicalName == null) { | 4309 if (library.canonicalName == null) { |
4281 throw '$library has no canonical name'; | 4310 throw '$library has no canonical name'; |
4282 } | 4311 } |
4283 return library.canonicalName; | 4312 return library.canonicalName; |
4284 } | 4313 } |
OLD | NEW |