fix function type printing in DDC to match VM

Change-Id: I2e15d34c8a40d9ed86b44f5c3db7052fb7c8a783
Reviewed-on: https://dart-review.googlesource.com/14780
Commit-Queue: Jenny Messerly <jmesserly@google.com>
Reviewed-by: Vijay Menon <vsm@google.com>
This commit is contained in:
Jenny Messerly
2017-10-27 22:35:20 +00:00
committed by commit-bot@chromium.org
parent 6fdc91d049
commit 0aa6801f8a
19 changed files with 133 additions and 84 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -4439,8 +4439,22 @@ class CodeGenerator extends Object
}
throw new StateError('failed to evaluate $node');
}
return _emitInstanceCreationExpression(
element, constructor.type.type, name, node.argumentList, node.isConst);
// TODO(jmesserly): this is a workaround for Analyzer's type not
// correctly tracking typedefs used in type arguments.
DartType getType(TypeAnnotation typeNode) {
if (typeNode is NamedType && typeNode.typeArguments != null) {
var e = typeNode.name.staticElement;
if (e is TypeParameterizedElement) {
return e.type.instantiate(
typeNode.typeArguments.arguments.map(getType).toList());
}
}
return typeNode.type;
}
return _emitInstanceCreationExpression(element, getType(constructor.type),
name, node.argumentList, node.isConst);
}
bool isPrimitiveType(DartType t) => _typeRep.isPrimitive(t);
@@ -406,13 +406,13 @@ class FunctionType extends AbstractFunctionType {
buffer += ', ';
}
var typeNameString = typeName(JS('', '#[#[#]]', named, names, i));
buffer += '${JS('', '#[#]', names, i)}: $typeNameString';
buffer += '$typeNameString ${JS('', '#[#]', names, i)}';
}
buffer += '}';
}
var returnTypeName = typeName(returnType);
buffer += ') -> $returnTypeName';
buffer += ') => $returnTypeName';
_stringValue = buffer;
return buffer;
}
@@ -458,9 +458,23 @@ class Typedef extends AbstractFunctionType {
Typedef(this._name, this._closure) {}
toString() =>
JS('String', '# + "(" + #.toString() + ")"', _name, functionType);
get name => _name;
toString() {
var typeArgs = getGenericArgs(this);
if (typeArgs == null) return name;
var result = name + '<';
var allDynamic = true;
for (var i = 0, n = JS('int', '#.length', typeArgs); i < n; ++i) {
if (i > 0) result += ', ';
var typeArg = JS('', '#[#]', typeArgs, i);
if (JS('bool', '# !== #', typeArg, _dynamic)) allDynamic = false;
result += typeName(typeArg);
}
result += '>';
return allDynamic ? name : result;
}
String get name => JS('String', '#', _name);
AbstractFunctionType get functionType {
var ft = _functionType;
@@ -220,15 +220,15 @@ testTearOffRuntimeType() {
'covariant params should reify with Object as their type');
TearOff<num> t = new TearOff<int>();
expectRTTI(t.method1, '(Object) -> dynamic');
expectRTTI(t.method1, '(Object) => dynamic');
expectRTTI(t.method2, '((int) -> dynamic) -> dynamic');
expectRTTI(t.method3, '(Object) -> dynamic');
expectRTTI(t.method2, '((int) => dynamic) => dynamic');
expectRTTI(t.method3, '(Object) => dynamic');
expectRTTI(t.method4, '(Object) -> dynamic');
expectRTTI(t.method5, '((() -> int) -> dynamic) -> dynamic');
expectRTTI(t.method6, '(() -> (int) -> dynamic) -> dynamic');
expectRTTI(t.method7, '(Object) -> dynamic');
expectRTTI(t.method4, '(Object) => dynamic');
expectRTTI(t.method5, '((() => int) => dynamic) => dynamic');
expectRTTI(t.method6, '(() => (int) => dynamic) => dynamic');
expectRTTI(t.method7, '(Object) => dynamic');
}
main() {
+6 -6
View File
@@ -20,8 +20,8 @@ main() {
var c = new C<int>();
var f = c.f;
var g = c.g;
Expect.equals("(int) -> int", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) -> int", g.runtimeType.toString()); //# 01: ok
Expect.equals("(int) => int", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) => int", g.runtimeType.toString()); //# 01: ok
Expect.equals(21, f(21));
Expect.equals(14, g(14));
Expect.isTrue(f is Function);
@@ -44,8 +44,8 @@ main() {
var c = new C<bool>();
var f = c.f;
var g = c.g;
Expect.equals("(bool) -> bool", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) -> bool", g.runtimeType.toString()); //# 01: ok
Expect.equals("(bool) => bool", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) => bool", g.runtimeType.toString()); //# 01: ok
Expect.isTrue(f is F);
Expect.isTrue(g is F);
Expect.isTrue(f is! F<int>);
@@ -58,8 +58,8 @@ main() {
var c = new C();
var f = c.f;
var g = c.g;
Expect.equals("(dynamic) -> dynamic", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) -> dynamic", g.runtimeType.toString()); //# 01: ok
Expect.equals("(dynamic) => dynamic", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) => dynamic", g.runtimeType.toString()); //# 01: ok
Expect.isTrue(f is F);
Expect.isTrue(g is F);
Expect.isTrue(f is! F<int>);
@@ -13,7 +13,7 @@ void testInstantiateToBounds() {
Expect.listEquals((f as dynamic)(), [num, num]);
Expect.equals((g as dynamic)().join('|'), 'List<int>|int');
Expect.equals((h as dynamic)(null, null),
'<T extends num, U extends T>(T, U) -> String');
'<T extends num, U extends T>(T, U) => String');
i<T extends Iterable<T>>() => null;
j<T extends Iterable<S>, S extends T>() => null;
@@ -65,9 +65,9 @@ void testToString() {
num g<T, U>(T x, U y) => max(x as num, y as num);
String h<T, U>(T x, U y) => h.runtimeType.toString();
Expect.equals(
f.runtimeType.toString(), '<T extends num, U extends T>(T, U) -> num');
Expect.equals(g.runtimeType.toString(), '<T, U>(T, U) -> num');
Expect.equals(h(42, 123.0), '<T, U>(T, U) -> String');
f.runtimeType.toString(), '<T extends num, U extends T>(T, U) => num');
Expect.equals(g.runtimeType.toString(), '<T, U>(T, U) => num');
Expect.equals(h(42, 123.0), '<T, U>(T, U) => String');
}
main() {
@@ -46,9 +46,7 @@ void testGenericFnAsGenericFnArg() {
void testGenericFnTypeToString() {
T f<T>(T a) => a;
// TODO(jmesserly): other Dart implementations use `=>` arrow, so we may need
// to change this in DDC at some point.
Expect.equals(f.runtimeType.toString(), "<T>(T) -> T");
Expect.equals(f.runtimeType.toString(), "<T>(T) => T");
}
main() {
@@ -815,7 +815,6 @@ try_catch_on_syntax_test/10: MissingCompileTimeError
try_catch_on_syntax_test/11: MissingCompileTimeError
try_catch_syntax_test/08: MissingCompileTimeError
type_checks_in_factory_method_test/01: MissingCompileTimeError
type_literal_test: RuntimeError
type_parameter_test/05: MissingCompileTimeError
type_promotion_parameter_test/01: MissingCompileTimeError
type_promotion_parameter_test/02: MissingCompileTimeError
-1
View File
@@ -699,7 +699,6 @@ try_catch_on_syntax_test/10: MissingCompileTimeError
try_catch_on_syntax_test/11: MissingCompileTimeError
try_catch_syntax_test/08: MissingCompileTimeError
type_checks_in_factory_method_test/01: MissingCompileTimeError
type_literal_test: RuntimeError
type_promotion_parameter_test/01: MissingCompileTimeError
type_promotion_parameter_test/02: MissingCompileTimeError
type_promotion_parameter_test/03: MissingCompileTimeError
@@ -53,35 +53,11 @@ String form2(String returns, String positional,
result.write(")");
}
/// Formats types the DDC way: `(String, [int], {name: bool}) -> double`.
String form3(String returns, String positional,
[Map<String, String> named = const {}]) {
var result = new StringBuffer();
result.write("($positional");
if (positional != "" && named.isNotEmpty) result.write(", ");
if (named.isNotEmpty) {
result.write("{");
bool first = true;
named.forEach((name, type) {
if (first) {
first = false;
} else {
result.write(", ");
}
result.write("$name: $type");
});
result.write("}");
}
result.write(") -> $returns");
return result.toString();
}
F detectForm() {
var s = main.runtimeType.toString();
if (s.contains('=>')) return form1;
if (s.contains('Function')) return form2;
if (s.contains('->')) return form3;
Expect.fail('"$s" contains neither "=>", "->" nor "Function"');
Expect.fail('"$s" contains neither "=>", nor "Function"');
}
main() {
+3 -6
View File
@@ -42,12 +42,9 @@ main() {
testType(new Box<Box<Foo>>().typeArg, "Box<Foo>");
// Typedef.
testType(Func, "Func((bool) -> int)");
testType(GenericFunc, "GenericFunc((bottom) -> int)");
// TODO(rnystrom): This should print "GenericFunc<int>", but that isn't
// implemented yet.
testType(new Box<GenericFunc<int>>().typeArg, "(int) -> int");
testType(Func, "Func");
testType(GenericFunc, "GenericFunc");
testType(new Box<GenericFunc<int>>().typeArg, "GenericFunc<int>");
// Literals are canonicalized.
Expect.identical(Foo, Foo);