Index: lib/src/js/js_types.dart |
diff --git a/lib/src/js/js_types.dart b/lib/src/js/js_types.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..737d98312349b9d1fbe243d6a41fa436736fdf5c |
--- /dev/null |
+++ b/lib/src/js/js_types.dart |
@@ -0,0 +1,189 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
Jennifer Messerly
2016/02/09 01:21:33
2016? :)
ochafik
2016/02/10 18:12:45
Time flies!
|
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+part of js_ast; |
+ |
+final _any = new AnyTypeRef._(); |
+final _unknown = new UnknownTypeRef._(); |
+final _null = new NullTypeRef(); |
+ |
+/// JavaScript type reference. |
Jennifer Messerly
2016/02/09 01:21:33
It'd be good to add more info here. Like maybe a q
ochafik
2016/02/10 18:12:45
Done.
|
+abstract class TypeRef extends Expression { |
+ static final _namedCache = <String, TypeRef>{}; |
Jennifer Messerly
2016/02/09 01:21:33
Is this an optimization or is canonicalization a r
ochafik
2016/02/10 18:12:45
Dropped the premature opt, I'm not testing for typ
|
+ |
+ int get precedenceLevel => EXPRESSION; |
Jennifer Messerly
2016/02/09 01:21:33
this seems like a really low precedence. I'd expec
ochafik
2016/02/10 18:12:45
Done.
|
+ |
+ TypeRef(); |
Jennifer Messerly
2016/02/09 01:21:33
Is this needed? I think you'll get it for free
ochafik
2016/02/10 18:12:45
As soon as there's a factory ctor, seems we don't
|
+ |
+ factory TypeRef.any() => _any; |
+ |
+ factory TypeRef.void_() => new TypeRef.named('void'); |
+ |
+ factory TypeRef.unknown() => _unknown; |
+ |
+ factory TypeRef.generic(TypeRef rawType, Iterable<TypeRef> typeParams) => |
+ typeParams.isEmpty |
+ ? rawType |
+ : new GenericTypeRef(rawType, typeParams.toList()); |
Jennifer Messerly
2016/02/09 16:41:57
looking at these factories again ... I'd probably
ochafik
2016/02/10 18:12:45
Done.
|
+ |
+ factory TypeRef.array([TypeRef elementType]) => |
+ elementType == null ? new TypeRef.named('Array') : new ArrayTypeRef(elementType); |
Jennifer Messerly
2016/02/09 01:21:33
long line
Jennifer Messerly
2016/02/09 16:41:57
Another thought here. I noticed in the printing co
ochafik
2016/02/10 18:12:45
Done.
ochafik
2016/02/10 18:12:45
Done for Array & Function. Left a TODO for object
|
+ |
+ factory TypeRef.object([TypeRef keyType, TypeRef valueType]) { |
+ var rawType = new TypeRef.named('Object'); |
+ return keyType == null && valueType == null |
+ ? rawType |
+ : new GenericTypeRef(rawType, [keyType ?? _any, valueType ?? _any]); |
+ } |
+ |
+ factory TypeRef.function([TypeRef returnType, Map<Identifier, TypeRef> paramTypes]) => |
Jennifer Messerly
2016/02/09 01:21:33
long line here too
ochafik
2016/02/10 18:12:45
Sorry, formatter strangely didn't tackle that one.
|
+ returnType == null && paramTypes == null |
+ ? new TypeRef.named('Function') |
+ : new FunctionTypeRef(returnType, paramTypes); |
+ |
+ factory TypeRef.record(Map<Identifier, TypeRef> types) => |
+ new RecordTypeRef(types); |
+ |
+ factory TypeRef.string() => new TypeRef.named('string'); |
+ |
+ factory TypeRef.number() => new TypeRef.named('number'); |
+ |
+ factory TypeRef.undefined() => new TypeRef.named('undefined'); |
+ |
+ factory TypeRef.boolean() => new TypeRef.named('boolean'); |
+ |
+ factory TypeRef.qualified(List<Identifier> path) => |
+ _namedCache.putIfAbsent( |
+ path.map((p) => p.name).join('.'), |
+ () => new QualifiedTypeRef(path)); |
+ |
+ factory TypeRef.named(String name) => |
+ new TypeRef.qualified(<Identifier>[new Identifier(name)]); |
+ |
+ bool get isAny => this is AnyTypeRef; |
+ bool get isUnknown => this is UnknownTypeRef; |
+ bool get isNull => this is NullTypeRef; |
+ |
+ TypeRef or(TypeRef other) => new UnionTypeRef([this, other]); |
+ |
+ TypeRef orUndefined() => or(new TypeRef.undefined()); |
+ TypeRef orNull() => or(_null); |
+ |
+ TypeRef toOptional() => |
+ new OptionalTypeRef(this); |
+} |
+ |
+class AnyTypeRef extends TypeRef { |
+ AnyTypeRef._() : super(); |
+ |
+ factory AnyTypeRef() => _any; |
+ accept(NodeVisitor visitor) => visitor.visitAnyTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) {} |
+ _clone() => new AnyTypeRef(); |
+} |
+ |
+class NullTypeRef extends QualifiedTypeRef { |
+ NullTypeRef() : super([new Identifier("null")]); |
+ _clone() => new NullTypeRef(); |
+} |
+ |
+class UnknownTypeRef extends TypeRef { |
+ UnknownTypeRef._() : super(); |
+ |
+ factory UnknownTypeRef() => _unknown; |
+ accept(NodeVisitor visitor) => visitor.visitUnknownTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) {} |
+ _clone() => new UnknownTypeRef(); |
+} |
+ |
+class QualifiedTypeRef extends TypeRef { |
+ final List<Identifier> path; |
+ QualifiedTypeRef(this.path); |
+ |
+ accept(NodeVisitor visitor) => visitor.visitQualifiedTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) => |
+ path.forEach((p) => p.accept(visitor)); |
+ _clone() => new QualifiedTypeRef(path); |
+} |
+ |
+class ArrayTypeRef extends TypeRef { |
+ final TypeRef elementType; |
+ ArrayTypeRef(this.elementType); |
+ accept(NodeVisitor visitor) => visitor.visitArrayTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) { |
+ elementType.accept(visitor); |
+ } |
+ _clone() => new ArrayTypeRef(elementType); |
+} |
+ |
+class GenericTypeRef extends TypeRef { |
+ final TypeRef rawType; |
+ final List<TypeRef> typeParams; |
+ GenericTypeRef(this.rawType, this.typeParams); |
+ |
+ accept(NodeVisitor visitor) => visitor.visitGenericTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) { |
+ rawType.accept(visitor); |
+ typeParams.forEach((p) => p.accept(visitor)); |
+ } |
+ _clone() => new GenericTypeRef(rawType, typeParams); |
+} |
+ |
+class UnionTypeRef extends TypeRef { |
+ final List<TypeRef> types; |
+ UnionTypeRef(this.types); |
+ |
+ accept(NodeVisitor visitor) => visitor.visitUnionTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) { |
+ types.forEach((p) => p.accept(visitor)); |
+ } |
+ _clone() => new UnionTypeRef(types); |
+ |
+ @override |
+ TypeRef or(TypeRef other) { |
+ if (types.contains(other)) return this; |
+ return new UnionTypeRef([]..addAll(types)..add(other)); |
+ } |
+} |
+ |
+class OptionalTypeRef extends TypeRef { |
+ final TypeRef type; |
+ OptionalTypeRef(this.type); |
+ |
+ accept(NodeVisitor visitor) => visitor.visitOptionalTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) { |
+ type.accept(visitor); |
+ } |
+ _clone() => new OptionalTypeRef(type); |
+ |
+ @override |
+ TypeRef orUndefined() => this; |
+} |
+ |
+class RecordTypeRef extends TypeRef { |
+ final Map<Identifier, TypeRef> types; |
+ RecordTypeRef(this.types); |
+ |
+ accept(NodeVisitor visitor) => visitor.visitRecordTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) { |
+ types.values.forEach((p) => p.accept(visitor)); |
+ } |
+ _clone() => new RecordTypeRef(types); |
+} |
+ |
+class FunctionTypeRef extends TypeRef { |
+ final TypeRef returnType; |
+ final Map<Identifier, TypeRef> paramTypes; |
+ FunctionTypeRef(this.returnType, this.paramTypes); |
+ |
+ accept(NodeVisitor visitor) => visitor.visitFunctionTypeRef(this); |
+ void visitChildren(NodeVisitor visitor) { |
+ returnType.accept(visitor); |
+ paramTypes.forEach((n, t) { |
+ n.accept(visitor); |
+ t.accept(visitor); |
+ }); |
+ } |
+ _clone() => new FunctionTypeRef(returnType, paramTypes); |
+} |