From bd223d0ec499db7d8ee756bc41ca6b802be40b0a Mon Sep 17 00:00:00 2001 From: Stephen Adams Date: Fri, 12 Oct 2018 00:52:25 +0000 Subject: [PATCH] Add consistent_type_error_test Change-Id: Ic48765468dcdd19371291a32514b9b04012a762a Reviewed-on: https://dart-review.googlesource.com/c/79146 Commit-Queue: Stephen Adams Reviewed-by: Sigmund Cherem --- .../instantiation_stub_generator.dart | 30 +-- .../_internal/js_runtime/lib/js_helper.dart | 10 +- sdk/lib/_internal/js_runtime/lib/js_rti.dart | 2 +- .../dart2js/analyses/api_allowed.json | 7 +- .../consistent_type_error_test.dart | 203 ++++++++++++++++++ 5 files changed, 228 insertions(+), 24 deletions(-) create mode 100644 tests/compiler/dart2js_extra/consistent_type_error_test.dart diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart index 2804e1242ac..f8dabcf28c0 100644 --- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart +++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart @@ -176,20 +176,22 @@ class InstantiationStubGenerator { // For every call-selector generate a stub to the corresponding selector // with filled-in type arguments. - Set parameterStructures; - for (Selector selector in callSelectors.keys) { - CallStructure callStructure = selector.callStructure; - if (callStructure.typeArgumentCount != 0) continue; - CallStructure genericCallStructure = - callStructure.withTypeArgumentCount(typeArgumentCount); - parameterStructures ??= computeLiveParameterStructures(); - for (ParameterStructure parameterStructure in parameterStructures) { - if (genericCallStructure.signatureApplies(parameterStructure)) { - Selector genericSelector = - new Selector.call(selector.memberName, genericCallStructure); - stubs.add(_generateStub( - instantiationClass, functionField, selector, genericSelector)); - break; + if (callSelectors != null) { + Set parameterStructures; + for (Selector selector in callSelectors.keys) { + CallStructure callStructure = selector.callStructure; + if (callStructure.typeArgumentCount != 0) continue; + CallStructure genericCallStructure = + callStructure.withTypeArgumentCount(typeArgumentCount); + parameterStructures ??= computeLiveParameterStructures(); + for (ParameterStructure parameterStructure in parameterStructures) { + if (genericCallStructure.signatureApplies(parameterStructure)) { + Selector genericSelector = + new Selector.call(selector.memberName, genericCallStructure); + stubs.add(_generateStub( + instantiationClass, functionField, selector, genericSelector)); + break; + } } } } diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart index eb46c48b422..4a5831ce467 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart @@ -3407,13 +3407,13 @@ intTypeCast(value) { void propertyTypeError(value, property) { String name = isCheckPropertyToJsConstructorName(property); - throw new TypeErrorImplementation(value, name); + throw new TypeErrorImplementation(value, unminifyOrTag(name)); } void propertyTypeCastError(value, property) { // Cuts the property name to the class name. - String expectedType = property.substring(3, property.length); - throw new CastErrorImplementation(value, expectedType); + String name = isCheckPropertyToJsConstructorName(property); + throw new CastErrorImplementation(value, unminifyOrTag(name)); } /** @@ -3537,12 +3537,12 @@ stringSuperNativeTypeCast(value, property) { listTypeCheck(value) { if (value == null) return value; if (value is List) return value; - throw new TypeErrorImplementation(value, 'List'); + throw new TypeErrorImplementation(value, 'List'); } listTypeCast(value) { if (value is List || value == null) return value; - throw new CastErrorImplementation(value, 'List'); + throw new CastErrorImplementation(value, 'List'); } listSuperTypeCheck(value, property) { diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart index ae207fb6a40..b5e84fab0e5 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart @@ -463,7 +463,7 @@ String computeTypeName(String isField, List arguments) { // Extract the class name from the is field and append the textual // representation of the type arguments. return Primitives.formatType( - isCheckPropertyToJsConstructorName(isField), arguments); + unminifyOrTag(isCheckPropertyToJsConstructorName(isField)), arguments); } /// Called from generated code. diff --git a/tests/compiler/dart2js/analyses/api_allowed.json b/tests/compiler/dart2js/analyses/api_allowed.json index 322c7d9ed38..830ee49eb87 100644 --- a/tests/compiler/dart2js/analyses/api_allowed.json +++ b/tests/compiler/dart2js/analyses/api_allowed.json @@ -19,9 +19,8 @@ "Dynamic access of '_js_helper::_self'.": 1, "Dynamic access of '_js_helper::_target'.": 1, "Dynamic access of '_js_helper::_receiver'.": 1, - "Dynamic access of 'length'.": 3, - "Dynamic invocation of '>='.": 1, - "Dynamic invocation of 'substring'.": 1 + "Dynamic access of 'length'.": 2, + "Dynamic invocation of '>='.": 1 }, "org-dartlang-sdk:///sdk/lib/_internal/js_runtime/lib/string_helper.dart": { "Dynamic invocation of '<'.": 1, @@ -322,4 +321,4 @@ "Dynamic access of 'port'.": 1, "Dynamic invocation of 'dart._http::_toJSON'.": 1 } -} \ No newline at end of file +} diff --git a/tests/compiler/dart2js_extra/consistent_type_error_test.dart b/tests/compiler/dart2js_extra/consistent_type_error_test.dart new file mode 100644 index 00000000000..e687ba46736 --- /dev/null +++ b/tests/compiler/dart2js_extra/consistent_type_error_test.dart @@ -0,0 +1,203 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// 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. + +// Test that type checks give consistent errors for the same types. In minified +// mode this checks that the minified class names are consistently tagged. + +import 'package:expect/expect.dart'; + +class Plain {} + +class Foo {} + +class Test { + @pragma('dart2js:noInline') + asT(o) => o as T; + + @pragma('dart2js:noInline') + asFooT(o) => o as Foo; + + @pragma('dart2js:noInline') + testT(o) { + T result = o; + } + + @pragma('dart2js:noInline') + testFooT(o) { + Foo result = o; + } +} + +capture(action()) { + try { + action(); + } catch (e) { + print('$e'); + return '$e'; + } + Expect.fail('Action should have failed'); +} + +dynamic g; + +casts() { + g = Foo(); + + Expect.equals( + capture(() => Test>().asT(g)), + capture(() => g as Foo), + "C1", + ); + + Expect.equals( + capture(() => g as Foo), + capture(() => Test().asFooT(g)), + "C2", + ); + + Expect.equals( + capture(() => Test().asT(g)), + capture(() => g as Plain), + "C3", + ); + + g = Foo(); + + Expect.equals( + capture(() => Test>().asT(g)), + capture(() => g as Foo), + "C4", + ); + + Expect.equals( + capture(() => g as Foo), + capture(() => Test().asFooT(g)), + "C5", + ); + + g = Plain(); + + Expect.equals( + capture(() => Test().asT(g)), + capture(() => g as String), + "C6", + ); + + Expect.equals( + capture(() => Test().asT(g)), + capture(() => g as int), + "C7", + ); + + Expect.equals( + capture(() => Test().asT(g)), + capture(() => g as double), + "C8", + ); + + Expect.equals( + capture(() => Test().asT(g)), + capture(() => g as bool), + "C9", + ); + + Expect.equals( + capture(() => Test().asT(g)), + capture(() => g as List), + "C10", + ); +} + +tests() { + g = Foo(); + + Expect.equals( + capture(() => Test>().testT(g)), + capture(() { + Foo x = g; + }), + "T1", + ); + + Expect.equals( + capture(() { + Foo x = g; + }), + capture(() => Test().testFooT(g)), + "T2", + ); + + Expect.equals( + capture(() => Test().testT(g)), + capture(() { + Plain x = g; + }), + "T3", + ); + + g = Foo(); + + Expect.equals( + capture(() => Test>().testT(g)), + capture(() { + Foo x = g; + }), + "T4", + ); + + Expect.equals( + capture(() { + Foo x = g; + }), + capture(() => Test().testFooT(g)), + "T5", + ); + + g = Plain(); + + Expect.equals( + capture(() => Test().testT(g)), + capture(() { + String x = g; + }), + "T6", + ); + + Expect.equals( + capture(() => Test().testT(g)), + capture(() { + int x = g; + }), + "T7", + ); + + Expect.equals( + capture(() => Test().testT(g)), + capture(() { + double x = g; + }), + "T8", + ); + + Expect.equals( + capture(() => Test().testT(g)), + capture(() { + bool x = g; + }), + "T9", + ); + + Expect.equals( + capture(() => Test().testT(g)), + capture(() { + List x = g; + }), + "T10", + ); +} + +main() { + casts(); + tests(); +}