Index: lib/src/js/nodes.dart |
diff --git a/lib/src/js/nodes.dart b/lib/src/js/nodes.dart |
index 5d0b3d172e7b5d96ae1e9cc0ee01b9290037217d..cd0e807a9542a3cf4c5cb13da93722b2f49473a4 100644 |
--- a/lib/src/js/nodes.dart |
+++ b/lib/src/js/nodes.dart |
@@ -4,7 +4,7 @@ |
part of js_ast; |
-abstract class NodeVisitor<T> { |
+abstract class NodeVisitor<T> implements TypeRefVisitor<T> { |
T visitProgram(Program node); |
T visitBlock(Block node); |
@@ -95,6 +95,18 @@ abstract class NodeVisitor<T> { |
T visitSimpleBindingPattern(SimpleBindingPattern node); |
} |
+abstract class TypeRefVisitor<T> { |
+ T visitQualifiedTypeRef(QualifiedTypeRef node); |
+ T visitGenericTypeRef(GenericTypeRef node); |
+ T visitUnionTypeRef(UnionTypeRef node); |
+ T visitRecordTypeRef(RecordTypeRef node); |
+ T visitOptionalTypeRef(OptionalTypeRef node); |
+ T visitFunctionTypeRef(FunctionTypeRef node); |
+ T visitAnyTypeRef(AnyTypeRef node); |
+ T visitUnknownTypeRef(UnknownTypeRef node); |
+ T visitArrayTypeRef(ArrayTypeRef node); |
+} |
+ |
class BaseVisitor<T> implements NodeVisitor<T> { |
T visitNode(Node node) { |
node.visitChildren(this); |
@@ -223,6 +235,17 @@ class BaseVisitor<T> implements NodeVisitor<T> { |
=> visitBindingPattern(node); |
T visitDestructuredVariable(DestructuredVariable node) => visitNode(node); |
T visitSimpleBindingPattern(SimpleBindingPattern node) => visitNode(node); |
+ |
+ T visitTypeRef(TypeRef node) => visitNode(node); |
+ T visitQualifiedTypeRef(QualifiedTypeRef node) => visitTypeRef(node); |
+ T visitGenericTypeRef(GenericTypeRef node) => visitTypeRef(node); |
+ T visitOptionalTypeRef(OptionalTypeRef node) => visitTypeRef(node); |
+ T visitRecordTypeRef(RecordTypeRef node) => visitTypeRef(node); |
+ T visitUnionTypeRef(UnionTypeRef node) => visitTypeRef(node); |
+ T visitFunctionTypeRef(FunctionTypeRef node) => visitTypeRef(node); |
+ T visitAnyTypeRef(AnyTypeRef node) => visitTypeRef(node); |
+ T visitUnknownTypeRef(UnknownTypeRef node) => visitTypeRef(node); |
+ T visitArrayTypeRef(ArrayTypeRef node) => visitTypeRef(node); |
} |
abstract class Node { |
@@ -783,7 +806,8 @@ class DestructuredVariable extends Expression implements Parameter { |
final Expression name; |
final BindingPattern structure; |
final Expression defaultValue; |
- DestructuredVariable({this.name, this.structure, this.defaultValue}) { |
+ final TypeRef type; |
+ DestructuredVariable({this.name, this.structure, this.defaultValue, this.type}) { |
assert(name != null || structure != null); |
} |
@@ -1036,14 +1060,19 @@ class Postfix extends Expression { |
int get precedenceLevel => UNARY; |
} |
-abstract class Parameter implements Expression, VariableBinding {} |
+abstract class Parameter implements Expression, VariableBinding { |
+ TypeRef get type; |
+} |
class Identifier extends Expression implements Parameter, VariableBinding { |
final String name; |
final bool allowRename; |
+ final TypeRef type; |
- Identifier(this.name, {this.allowRename: true}) { |
- assert(_identifierRE.hasMatch(name)); |
+ Identifier(this.name, {this.allowRename: true, this.type}) { |
+ if (!_identifierRE.hasMatch(name)) { |
+ throw new ArgumentError.value(name, "name", "not a valid identifier"); |
+ } |
} |
static RegExp _identifierRE = new RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$'); |
@@ -1057,6 +1086,7 @@ class Identifier extends Expression implements Parameter, VariableBinding { |
// This is an expression for convenience in the AST. |
class RestParameter extends Expression implements Parameter { |
final Identifier parameter; |
+ TypeRef get type => null; |
RestParameter(this.parameter); |
@@ -1121,19 +1151,28 @@ class NamedFunction extends Expression { |
abstract class FunctionExpression extends Expression { |
List<Parameter> get params; |
+ |
get body; // Expression or block |
+ /// Type parameters passed to this generic function, if any. `null` otherwise. |
+ // TODO(ochafik): Support type bounds. |
+ List<Identifier> get typeParams; |
+ /// Return type of this function, if any. `null` otherwise. |
+ TypeRef get returnType; |
} |
class Fun extends FunctionExpression { |
final List<Parameter> params; |
final Block body; |
+ @override final List<Identifier> typeParams; |
+ @override final TypeRef returnType; |
/** Whether this is a JS generator (`function*`) that may contain `yield`. */ |
final bool isGenerator; |
final AsyncModifier asyncModifier; |
Fun(this.params, this.body, {this.isGenerator: false, |
- this.asyncModifier: const AsyncModifier.sync()}); |
+ this.asyncModifier: const AsyncModifier.sync(), |
+ this.typeParams, this.returnType}); |
accept(NodeVisitor visitor) => visitor.visitFun(this); |
@@ -1151,8 +1190,10 @@ class Fun extends FunctionExpression { |
class ArrowFun extends FunctionExpression { |
final List<Parameter> params; |
final body; // Expression or Block |
+ @override final List<Identifier> typeParams; |
+ @override final TypeRef returnType; |
- ArrowFun(this.params, this.body); |
+ ArrowFun(this.params, this.body, {this.typeParams, this.returnType}); |
accept(NodeVisitor visitor) => visitor.visitArrowFun(this); |
@@ -1439,8 +1480,14 @@ class ClassExpression extends Expression { |
final Identifier name; |
final Expression heritage; // Can be null. |
final List<Method> methods; |
+ /// Type parameters of this class, if any. `null` otherwise. |
+ // TODO(ochafik): Support type bounds. |
+ final List<Identifier> typeParams; |
+ /// Field declarations of this class (TypeScript / ES6_TYPED). |
+ final List<VariableDeclarationList> fields; |
- ClassExpression(this.name, this.heritage, this.methods); |
+ ClassExpression(this.name, this.heritage, this.methods, |
+ {this.typeParams, this.fields}); |
accept(NodeVisitor visitor) => visitor.visitClassExpression(this); |
@@ -1448,9 +1495,20 @@ class ClassExpression extends Expression { |
name.accept(visitor); |
if (heritage != null) heritage.accept(visitor); |
for (Method element in methods) element.accept(visitor); |
+ if (fields != null) { |
+ for (var field in fields) { |
+ field.accept(visitor); |
+ } |
+ } |
+ if (typeParams != null) { |
+ for (var typeParam in typeParams) { |
+ typeParam.accept(visitor); |
+ } |
+ } |
} |
- ClassExpression _clone() => new ClassExpression(name, heritage, methods); |
+ ClassExpression _clone() => new ClassExpression( |
+ name, heritage, methods, typeParams: typeParams, fields: fields); |
int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
} |
@@ -1515,6 +1573,7 @@ class InterpolatedLiteral extends Literal with InterpolatedNode { |
class InterpolatedParameter extends Expression with InterpolatedNode |
implements Identifier { |
final nameOrPosition; |
+ TypeRef get type => null; |
String get name { throw "InterpolatedParameter.name must not be invoked"; } |
bool get allowRename => false; |
@@ -1574,6 +1633,7 @@ class InterpolatedMethod extends Expression with InterpolatedNode |
class InterpolatedIdentifier extends Expression with InterpolatedNode |
implements Identifier { |
final nameOrPosition; |
+ TypeRef get type => null; |
InterpolatedIdentifier(this.nameOrPosition); |