Index: lib/src/js/nodes.dart |
diff --git a/lib/src/js/nodes.dart b/lib/src/js/nodes.dart |
index 0ba181426578b19f97656189834b4847ce9d161d..5b26cde6167430d6a559823e3f10c55958de7fea 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); |
@@ -94,6 +94,18 @@ abstract class NodeVisitor<T> { |
T visitDestructuredVariable(DestructuredVariable 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); |
@@ -221,6 +233,17 @@ class BaseVisitor<T> implements NodeVisitor<T> { |
T visitObjectBindingPattern(ObjectBindingPattern node) |
=> visitBindingPattern(node); |
T visitDestructuredVariable(DestructuredVariable 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 { |
@@ -780,7 +803,8 @@ class DestructuredVariable extends Expression implements Parameter { |
final Identifier 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); |
} |
@@ -1022,14 +1046,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]*$'); |
@@ -1043,6 +1072,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); |
@@ -1107,19 +1137,27 @@ class NamedFunction extends Expression { |
abstract class FunctionExpression extends Expression { |
List<Parameter> get params; |
+ |
get body; // Expression or block |
+ /// For TypeScript / Closure's ES6_TYPED. |
Jennifer Messerly
2016/02/09 01:21:33
Maybe:
/// Type parameters passed to this generic
ochafik
2016/02/10 18:12:45
Done.
|
+ List<Identifier> get typeArgs; |
Jennifer Messerly
2016/02/09 01:21:33
These are type parameters, right? I'd suggest nami
ochafik
2016/02/10 18:12:45
Both kinds of generic functions are valid TS / ES6
|
+ /// For TypeScript / Closure's ES6_TYPED. |
Jennifer Messerly
2016/02/09 01:21:33
/// The return type of the function, if any.
ochafik
2016/02/10 18:12:45
Done.
|
+ TypeRef get returnType; |
} |
class Fun extends FunctionExpression { |
final List<Parameter> params; |
final Block body; |
+ final List<Identifier> typeArgs; |
Jennifer Messerly
2016/02/09 01:21:33
Not for now, but, what do you think about using @o
ochafik
2016/02/10 18:12:45
I love @override, so since you mentioned it... don
|
+ 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.typeArgs, this.returnType}); |
accept(NodeVisitor visitor) => visitor.visitFun(this); |
@@ -1137,8 +1175,10 @@ class Fun extends FunctionExpression { |
class ArrowFun extends FunctionExpression { |
final List<Parameter> params; |
final body; // Expression or Block |
+ final List<Identifier> typeArgs; |
+ final TypeRef returnType; |
- ArrowFun(this.params, this.body); |
+ ArrowFun(this.params, this.body, {this.typeArgs, this.returnType}); |
accept(NodeVisitor visitor) => visitor.visitArrowFun(this); |
@@ -1425,8 +1465,13 @@ class ClassExpression extends Expression { |
final Identifier name; |
final Expression heritage; // Can be null. |
final List<Method> methods; |
+ /// For TypeScript / Closure's ES6_TYPED. |
Jennifer Messerly
2016/02/09 01:21:33
(Same comment -- I think we should give this a pro
ochafik
2016/02/10 18:12:45
Done.
|
+ final List<Identifier> typeArgs; |
+ /// For TypeScript / Closure's ES6_TYPED. |
+ final List<VariableDeclarationList> fields; |
- ClassExpression(this.name, this.heritage, this.methods); |
+ ClassExpression(this.name, this.heritage, this.methods, |
+ [this.typeArgs = const [], this.fields = const []]); |
Jennifer Messerly
2016/02/09 01:21:33
I think it'd be fine to use a normal list. In gene
ochafik
2016/02/10 18:12:45
Done.
|
accept(NodeVisitor visitor) => visitor.visitClassExpression(this); |
@@ -1434,6 +1479,8 @@ class ClassExpression extends Expression { |
name.accept(visitor); |
if (heritage != null) heritage.accept(visitor); |
for (Method element in methods) element.accept(visitor); |
+ for (var field in fields) field.accept(visitor); |
+ for (var typeParam in typeArgs) typeParam.accept(visitor); |
} |
ClassExpression _clone() => new ClassExpression(name, heritage, methods); |
@@ -1501,6 +1548,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; |
@@ -1560,6 +1608,7 @@ class InterpolatedMethod extends Expression with InterpolatedNode |
class InterpolatedIdentifier extends Expression with InterpolatedNode |
implements Identifier { |
final nameOrPosition; |
+ TypeRef get type => null; |
InterpolatedIdentifier(this.nameOrPosition); |