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

Unified 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, 8 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/ast.dart
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index d93b704191debdf92ea41a532e35422977e1b13e..daa5427e83ab2e3d8af16aec6b0c292b3b547747 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -228,6 +228,13 @@ class Reference {
}
return node as Procedure;
}
+
+ Typedef get asTypedef {
+ if (node == null) {
+ throw '$this is not bound to an AST node. A typedef was expected';
+ }
+ return node as Typedef;
+ }
}
// ------------------------------------------------------------------------
@@ -258,6 +265,7 @@ class Library extends NamedNode implements Comparable<Library> {
String name;
final List<DeferredImport> deferredImports;
+ final List<Typedef> typedefs;
final List<Class> classes;
final List<Procedure> procedures;
final List<Field> fields;
@@ -266,16 +274,20 @@ class Library extends NamedNode implements Comparable<Library> {
{this.name,
this.isExternal: false,
List<DeferredImport> imports,
+ List<Typedef> typedefs,
List<Class> classes,
List<Procedure> procedures,
List<Field> fields,
this.fileUri,
Reference reference})
: this.deferredImports = imports ?? <DeferredImport>[],
+ this.typedefs = typedefs ?? <Typedef>[],
this.classes = classes ?? <Class>[],
this.procedures = procedures ?? <Procedure>[],
this.fields = fields ?? <Field>[],
super(reference) {
+ setParents(this.deferredImports, this);
+ setParents(this.typedefs, this);
setParents(this.classes, this);
setParents(this.procedures, this);
setParents(this.fields, this);
@@ -304,8 +316,16 @@ class Library extends NamedNode implements Comparable<Library> {
classes.add(class_);
}
+ void addTypedef(Typedef typedef_) {
+ typedef_.parent = this;
+ typedefs.add(typedef_);
+ }
+
void computeCanonicalNames() {
assert(canonicalName != null);
+ for (var typedef_ in typedefs) {
+ canonicalName.getChildFromTypedef(typedef_).bindTo(typedef_.reference);
+ }
for (var field in fields) {
canonicalName.getChildFromMember(field).bindTo(field.reference);
}
@@ -321,12 +341,16 @@ class Library extends NamedNode implements Comparable<Library> {
accept(TreeVisitor v) => v.visitLibrary(this);
visitChildren(Visitor v) {
+ visitList(deferredImports, v);
+ visitList(typedefs, v);
visitList(classes, v);
visitList(procedures, v);
visitList(fields, v);
}
transformChildren(Transformer v) {
+ transformList(deferredImports, v, this);
+ transformList(typedefs, v, this);
transformList(classes, v, this);
transformList(procedures, v, this);
transformList(fields, v, this);
@@ -366,6 +390,51 @@ class DeferredImport extends TreeNode {
transformChildren(Transformer v) {}
}
+/// Declaration of a type alias.
+class Typedef extends NamedNode {
+ /// The uri of the source file that contains the declaration of this typedef.
+ String fileUri;
+ List<Expression> annotations = const <Expression>[];
+ String name;
+ final List<TypeParameter> typeParameters;
+ DartType type;
+
+ Typedef(this.name, this.type,
+ {Reference reference, this.fileUri, List<TypeParameter> typeParameters})
+ : this.typeParameters = typeParameters ?? <TypeParameter>[],
+ super(reference) {
+ setParents(this.typeParameters, this);
+ }
+
+ Library get enclosingLibrary => parent;
+
+ accept(TreeVisitor v) {
+ return v.visitTypedef(this);
+ }
+
+ transformChildren(Transformer v) {
+ transformList(annotations, v, this);
+ transformList(typeParameters, v, this);
+ if (type != null) {
+ type = v.visitDartType(type);
+ }
+ }
+
+ visitChildren(Visitor v) {
+ visitList(annotations, v);
+ visitList(typeParameters, v);
+ type?.accept(v);
+ }
+
+ void addAnnotation(Expression node) {
+ if (annotations.isEmpty) {
+ annotations = <Expression>[];
+ }
+ annotations.add(node);
+ node.parent = this;
+ }
+}
+
/// The degree to which the contents of a class have been loaded into memory.
///
/// Each level imply the requirements of the previous ones.
@@ -3695,6 +3764,16 @@ abstract class DartType extends Node {
accept(DartTypeVisitor v);
bool operator ==(Object other);
+
+ /// If this is a typedef type, repeatedly unfolds its type definition until
+ /// the root term is not a typedef type, otherwise returns the type itself.
+ ///
+ /// Will never return a typedef type.
+ DartType get unalias => this;
+
+ /// If this is a typedef type, unfolds its type definition once, otherwise
+ /// returns the type itself.
+ DartType get unaliasOnce => this;
}
/// The type arising from invalid type annotations.
@@ -3924,6 +4003,60 @@ class FunctionType extends DartType {
}
}
+/// A use of a [Typedef] as a type.
+///
+/// The underlying type can be extracted using [unalias].
+class TypedefType extends DartType {
+ final Reference typedefReference;
+ final List<DartType> typeArguments;
+
+ TypedefType(Typedef typedefNode, [List<DartType> typeArguments])
+ : this.byReference(
+ typedefNode.reference, typeArguments ?? const <DartType>[]);
+
+ TypedefType.byReference(this.typedefReference, this.typeArguments);
+
+ Typedef get typedefNode => typedefReference.asTypedef;
+
+ accept(DartTypeVisitor v) => v.visitTypedefType(this);
+
+ visitChildren(Visitor v) {
+ visitList(typeArguments, v);
+ v.visitTypedefReference(typedefNode);
+ }
+
+ DartType get unaliasOnce {
+ return Substitution.fromTypedefType(this).substituteType(typedefNode.type);
+ }
+
+ DartType get unalias {
+ return unaliasOnce.unalias;
+ }
+
+ bool operator ==(Object other) {
+ if (identical(this, other)) return true;
+ if (other is TypedefType) {
+ if (typedefReference != other.typedefReference ||
+ typeArguments.length != other.typeArguments.length) {
+ return false;
+ }
+ for (int i = 0; i < typeArguments.length; ++i) {
+ if (typeArguments[i] != other.typeArguments[i]) return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ int get hashCode {
+ int hash = 0x3fffffff & typedefNode.hashCode;
+ for (int i = 0; i < typeArguments.length; ++i) {
+ hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode));
+ }
+ return hash;
+ }
+}
+
/// A named parameter in [FunctionType].
class NamedType extends Node implements Comparable<NamedType> {
final String name;
@@ -4323,3 +4456,15 @@ CanonicalName getCanonicalNameOfLibrary(Library library) {
}
return library.canonicalName;
}
+
+/// Returns the canonical name of [typedef_], or throws an exception if the
+/// typedef has not been assigned a canonical name yet.
+///
+/// Returns `null` if the typedef is `null`.
+CanonicalName getCanonicalNameOfTypedef(Typedef typedef_) {
+ if (typedef_ == null) return null;
+ if (typedef_.canonicalName == null) {
+ throw '$typedef_ has no canonical name';
+ }
+ return typedef_.canonicalName;
+}
« 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