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

Side by Side Diff: pkg/kernel/lib/ast.dart

Issue 2825053002: Add typedef AST node boilerplate. (Closed)
Patch Set: Update FastaVerifyingVisitor to work with the changes in VerifyingVisitor Created 3 years, 7 months 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
OLDNEW
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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 221 }
222 return node as Constructor; 222 return node as Constructor;
223 } 223 }
224 224
225 Procedure get asProcedure { 225 Procedure get asProcedure {
226 if (node == null) { 226 if (node == null) {
227 throw '$this is not bound to an AST node. A procedure was expected'; 227 throw '$this is not bound to an AST node. A procedure was expected';
228 } 228 }
229 return node as Procedure; 229 return node as Procedure;
230 } 230 }
231
232 Typedef get asTypedef {
233 if (node == null) {
234 throw '$this is not bound to an AST node. A typedef was expected';
235 }
236 return node as Typedef;
237 }
231 } 238 }
232 239
233 // ------------------------------------------------------------------------ 240 // ------------------------------------------------------------------------
234 // LIBRARIES and CLASSES 241 // LIBRARIES and CLASSES
235 // ------------------------------------------------------------------------ 242 // ------------------------------------------------------------------------
236 243
237 class Library extends NamedNode implements Comparable<Library> { 244 class Library extends NamedNode implements Comparable<Library> {
238 /// An import path to this library. 245 /// An import path to this library.
239 /// 246 ///
240 /// The [Uri] should have the `dart`, `package`, `app`, or `file` scheme. 247 /// The [Uri] should have the `dart`, `package`, `app`, or `file` scheme.
(...skipping 10 matching lines...) Expand all
251 /// Classes of an external library are loaded at one of the [ClassLevel]s 258 /// Classes of an external library are loaded at one of the [ClassLevel]s
252 /// other than [ClassLevel.Body]. Members in an external library have no 259 /// other than [ClassLevel.Body]. Members in an external library have no
253 /// body, but have their typed interface present. 260 /// body, but have their typed interface present.
254 /// 261 ///
255 /// If the libary is non-external, then its classes are at [ClassLevel.Body] 262 /// If the libary is non-external, then its classes are at [ClassLevel.Body]
256 /// and all members are loaded. 263 /// and all members are loaded.
257 bool isExternal; 264 bool isExternal;
258 265
259 String name; 266 String name;
260 final List<DeferredImport> deferredImports; 267 final List<DeferredImport> deferredImports;
268 final List<Typedef> typedefs;
261 final List<Class> classes; 269 final List<Class> classes;
262 final List<Procedure> procedures; 270 final List<Procedure> procedures;
263 final List<Field> fields; 271 final List<Field> fields;
264 272
265 Library(this.importUri, 273 Library(this.importUri,
266 {this.name, 274 {this.name,
267 this.isExternal: false, 275 this.isExternal: false,
268 List<DeferredImport> imports, 276 List<DeferredImport> imports,
277 List<Typedef> typedefs,
269 List<Class> classes, 278 List<Class> classes,
270 List<Procedure> procedures, 279 List<Procedure> procedures,
271 List<Field> fields, 280 List<Field> fields,
272 this.fileUri, 281 this.fileUri,
273 Reference reference}) 282 Reference reference})
274 : this.deferredImports = imports ?? <DeferredImport>[], 283 : this.deferredImports = imports ?? <DeferredImport>[],
284 this.typedefs = typedefs ?? <Typedef>[],
275 this.classes = classes ?? <Class>[], 285 this.classes = classes ?? <Class>[],
276 this.procedures = procedures ?? <Procedure>[], 286 this.procedures = procedures ?? <Procedure>[],
277 this.fields = fields ?? <Field>[], 287 this.fields = fields ?? <Field>[],
278 super(reference) { 288 super(reference) {
289 setParents(this.deferredImports, this);
290 setParents(this.typedefs, this);
279 setParents(this.classes, this); 291 setParents(this.classes, this);
280 setParents(this.procedures, this); 292 setParents(this.procedures, this);
281 setParents(this.fields, this); 293 setParents(this.fields, this);
282 } 294 }
283 295
284 /// Returns the top-level fields and procedures defined in this library. 296 /// Returns the top-level fields and procedures defined in this library.
285 /// 297 ///
286 /// This getter is for convenience, not efficiency. Consider manually 298 /// This getter is for convenience, not efficiency. Consider manually
287 /// iterating the members to speed up code in production. 299 /// iterating the members to speed up code in production.
288 Iterable<Member> get members => 300 Iterable<Member> get members =>
289 <Iterable<Member>>[fields, procedures].expand((x) => x); 301 <Iterable<Member>>[fields, procedures].expand((x) => x);
290 302
291 void addMember(Member member) { 303 void addMember(Member member) {
292 member.parent = this; 304 member.parent = this;
293 if (member is Procedure) { 305 if (member is Procedure) {
294 procedures.add(member); 306 procedures.add(member);
295 } else if (member is Field) { 307 } else if (member is Field) {
296 fields.add(member); 308 fields.add(member);
297 } else { 309 } else {
298 throw new ArgumentError(member); 310 throw new ArgumentError(member);
299 } 311 }
300 } 312 }
301 313
302 void addClass(Class class_) { 314 void addClass(Class class_) {
303 class_.parent = this; 315 class_.parent = this;
304 classes.add(class_); 316 classes.add(class_);
305 } 317 }
306 318
319 void addTypedef(Typedef typedef_) {
320 typedef_.parent = this;
321 typedefs.add(typedef_);
322 }
323
307 void computeCanonicalNames() { 324 void computeCanonicalNames() {
308 assert(canonicalName != null); 325 assert(canonicalName != null);
326 for (var typedef_ in typedefs) {
327 canonicalName.getChildFromTypedef(typedef_).bindTo(typedef_.reference);
328 }
309 for (var field in fields) { 329 for (var field in fields) {
310 canonicalName.getChildFromMember(field).bindTo(field.reference); 330 canonicalName.getChildFromMember(field).bindTo(field.reference);
311 } 331 }
312 for (var member in procedures) { 332 for (var member in procedures) {
313 canonicalName.getChildFromMember(member).bindTo(member.reference); 333 canonicalName.getChildFromMember(member).bindTo(member.reference);
314 } 334 }
315 for (var class_ in classes) { 335 for (var class_ in classes) {
316 canonicalName.getChild(class_.name).bindTo(class_.reference); 336 canonicalName.getChild(class_.name).bindTo(class_.reference);
317 class_.computeCanonicalNames(); 337 class_.computeCanonicalNames();
318 } 338 }
319 } 339 }
320 340
321 accept(TreeVisitor v) => v.visitLibrary(this); 341 accept(TreeVisitor v) => v.visitLibrary(this);
322 342
323 visitChildren(Visitor v) { 343 visitChildren(Visitor v) {
344 visitList(deferredImports, v);
345 visitList(typedefs, v);
324 visitList(classes, v); 346 visitList(classes, v);
325 visitList(procedures, v); 347 visitList(procedures, v);
326 visitList(fields, v); 348 visitList(fields, v);
327 } 349 }
328 350
329 transformChildren(Transformer v) { 351 transformChildren(Transformer v) {
352 transformList(deferredImports, v, this);
353 transformList(typedefs, v, this);
330 transformList(classes, v, this); 354 transformList(classes, v, this);
331 transformList(procedures, v, this); 355 transformList(procedures, v, this);
332 transformList(fields, v, this); 356 transformList(fields, v, this);
333 } 357 }
334 358
335 static int _libraryIdCounter = 0; 359 static int _libraryIdCounter = 0;
336 int _libraryId = ++_libraryIdCounter; 360 int _libraryId = ++_libraryIdCounter;
337 361
338 int compareTo(Library other) => _libraryId - other._libraryId; 362 int compareTo(Library other) => _libraryId - other._libraryId;
339 363
(...skipping 19 matching lines...) Expand all
359 Library get enclosingLibrary => parent; 383 Library get enclosingLibrary => parent;
360 Library get importedLibrary => importedLibraryReference.asLibrary; 384 Library get importedLibrary => importedLibraryReference.asLibrary;
361 385
362 accept(TreeVisitor v) => v.visitDeferredImport(this); 386 accept(TreeVisitor v) => v.visitDeferredImport(this);
363 387
364 visitChildren(Visitor v) {} 388 visitChildren(Visitor v) {}
365 389
366 transformChildren(Transformer v) {} 390 transformChildren(Transformer v) {}
367 } 391 }
368 392
393 /// Declaration of a type alias.
394 class Typedef extends NamedNode {
395 /// The uri of the source file that contains the declaration of this typedef.
396 String fileUri;
397 List<Expression> annotations = const <Expression>[];
398 String name;
399 final List<TypeParameter> typeParameters;
400 DartType type;
401
402 Typedef(this.name, this.type,
403 {Reference reference, this.fileUri, List<TypeParameter> typeParameters})
404 : this.typeParameters = typeParameters ?? <TypeParameter>[],
405 super(reference) {
406 setParents(this.typeParameters, this);
407 }
408
409 Library get enclosingLibrary => parent;
410
411 accept(TreeVisitor v) {
412 return v.visitTypedef(this);
413 }
414
415 transformChildren(Transformer v) {
416 transformList(annotations, v, this);
417 transformList(typeParameters, v, this);
418 if (type != null) {
419 type = v.visitDartType(type);
420 }
421 }
422
423 visitChildren(Visitor v) {
424 visitList(annotations, v);
425 visitList(typeParameters, v);
426 type?.accept(v);
427 }
428
429 void addAnnotation(Expression node) {
430 if (annotations.isEmpty) {
431 annotations = <Expression>[];
432 }
433 annotations.add(node);
434 node.parent = this;
435 }
436 }
437
369 /// The degree to which the contents of a class have been loaded into memory. 438 /// The degree to which the contents of a class have been loaded into memory.
370 /// 439 ///
371 /// Each level imply the requirements of the previous ones. 440 /// Each level imply the requirements of the previous ones.
372 enum ClassLevel { 441 enum ClassLevel {
373 /// Temporary loading level for internal use by IR producers. Consumers of 442 /// Temporary loading level for internal use by IR producers. Consumers of
374 /// kernel code should not expect to see classes at this level. 443 /// kernel code should not expect to see classes at this level.
375 Temporary, 444 Temporary,
376 445
377 /// The class may be used as a type, and it may contain members that are 446 /// The class may be used as a type, and it may contain members that are
378 /// referenced from this build unit. 447 /// referenced from this build unit.
(...skipping 3309 matching lines...) Expand 10 before | Expand all | Expand 10 after
3688 /// cyclic structures that are constructed by mutation. 3757 /// cyclic structures that are constructed by mutation.
3689 /// 3758 ///
3690 /// The `==` operator on [DartType]s compare based on type equality, not 3759 /// The `==` operator on [DartType]s compare based on type equality, not
3691 /// object identity. 3760 /// object identity.
3692 abstract class DartType extends Node { 3761 abstract class DartType extends Node {
3693 const DartType(); 3762 const DartType();
3694 3763
3695 accept(DartTypeVisitor v); 3764 accept(DartTypeVisitor v);
3696 3765
3697 bool operator ==(Object other); 3766 bool operator ==(Object other);
3767
3768 /// If this is a typedef type, repeatedly unfolds its type definition until
3769 /// the root term is not a typedef type, otherwise returns the type itself.
3770 ///
3771 /// Will never return a typedef type.
3772 DartType get unalias => this;
3773
3774 /// If this is a typedef type, unfolds its type definition once, otherwise
3775 /// returns the type itself.
3776 DartType get unaliasOnce => this;
3698 } 3777 }
3699 3778
3700 /// The type arising from invalid type annotations. 3779 /// The type arising from invalid type annotations.
3701 /// 3780 ///
3702 /// Can usually be treated as 'dynamic', but should occasionally be handled 3781 /// Can usually be treated as 'dynamic', but should occasionally be handled
3703 /// differently, e.g. `x is ERROR` should evaluate to false. 3782 /// differently, e.g. `x is ERROR` should evaluate to false.
3704 class InvalidType extends DartType { 3783 class InvalidType extends DartType {
3705 final int hashCode = 12345; 3784 final int hashCode = 12345;
3706 3785
3707 const InvalidType(); 3786 const InvalidType();
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
3917 } 3996 }
3918 hash = 0x3fffffff & (hash * 31 + returnType.hashCode); 3997 hash = 0x3fffffff & (hash * 31 + returnType.hashCode);
3919 for (int i = 0; i < typeParameters.length; ++i) { 3998 for (int i = 0; i < typeParameters.length; ++i) {
3920 // Remove the type parameters from the scope again. 3999 // Remove the type parameters from the scope again.
3921 _temporaryHashCodeTable.remove(typeParameters[i]); 4000 _temporaryHashCodeTable.remove(typeParameters[i]);
3922 } 4001 }
3923 return hash; 4002 return hash;
3924 } 4003 }
3925 } 4004 }
3926 4005
4006 /// A use of a [Typedef] as a type.
4007 ///
4008 /// The underlying type can be extracted using [unalias].
4009 class TypedefType extends DartType {
4010 final Reference typedefReference;
4011 final List<DartType> typeArguments;
4012
4013 TypedefType(Typedef typedefNode, [List<DartType> typeArguments])
4014 : this.byReference(
4015 typedefNode.reference, typeArguments ?? const <DartType>[]);
4016
4017 TypedefType.byReference(this.typedefReference, this.typeArguments);
4018
4019 Typedef get typedefNode => typedefReference.asTypedef;
4020
4021 accept(DartTypeVisitor v) => v.visitTypedefType(this);
4022
4023 visitChildren(Visitor v) {
4024 visitList(typeArguments, v);
4025 v.visitTypedefReference(typedefNode);
4026 }
4027
4028 DartType get unaliasOnce {
4029 return Substitution.fromTypedefType(this).substituteType(typedefNode.type);
4030 }
4031
4032 DartType get unalias {
4033 return unaliasOnce.unalias;
4034 }
4035
4036 bool operator ==(Object other) {
4037 if (identical(this, other)) return true;
4038 if (other is TypedefType) {
4039 if (typedefReference != other.typedefReference ||
4040 typeArguments.length != other.typeArguments.length) {
4041 return false;
4042 }
4043 for (int i = 0; i < typeArguments.length; ++i) {
4044 if (typeArguments[i] != other.typeArguments[i]) return false;
4045 }
4046 return true;
4047 }
4048 return false;
4049 }
4050
4051 int get hashCode {
4052 int hash = 0x3fffffff & typedefNode.hashCode;
4053 for (int i = 0; i < typeArguments.length; ++i) {
4054 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode));
4055 }
4056 return hash;
4057 }
4058 }
4059
3927 /// A named parameter in [FunctionType]. 4060 /// A named parameter in [FunctionType].
3928 class NamedType extends Node implements Comparable<NamedType> { 4061 class NamedType extends Node implements Comparable<NamedType> {
3929 final String name; 4062 final String name;
3930 final DartType type; 4063 final DartType type;
3931 4064
3932 NamedType(this.name, this.type); 4065 NamedType(this.name, this.type);
3933 4066
3934 bool operator ==(Object other) { 4067 bool operator ==(Object other) {
3935 return other is NamedType && name == other.name && type == other.type; 4068 return other is NamedType && name == other.name && type == other.type;
3936 } 4069 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
4316 /// library has not been assigned a canonical name yet. 4449 /// library has not been assigned a canonical name yet.
4317 /// 4450 ///
4318 /// Returns `null` if the library is `null`. 4451 /// Returns `null` if the library is `null`.
4319 CanonicalName getCanonicalNameOfLibrary(Library library) { 4452 CanonicalName getCanonicalNameOfLibrary(Library library) {
4320 if (library == null) return null; 4453 if (library == null) return null;
4321 if (library.canonicalName == null) { 4454 if (library.canonicalName == null) {
4322 throw '$library has no canonical name'; 4455 throw '$library has no canonical name';
4323 } 4456 }
4324 return library.canonicalName; 4457 return library.canonicalName;
4325 } 4458 }
4459
4460 /// Returns the canonical name of [typedef_], or throws an exception if the
4461 /// typedef has not been assigned a canonical name yet.
4462 ///
4463 /// Returns `null` if the typedef is `null`.
4464 CanonicalName getCanonicalNameOfTypedef(Typedef typedef_) {
4465 if (typedef_ == null) return null;
4466 if (typedef_.canonicalName == null) {
4467 throw '$typedef_ has no canonical name';
4468 }
4469 return typedef_.canonicalName;
4470 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/verifier.dart ('k') | pkg/kernel/lib/binary/ast_from_binary.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698