[dart2wasm] Handle extension types that wrap allowed types on external members

Users are allowed to have extension types on types that we allow
on external methods e.g. String. For most types, this doesn't make a
difference as we jsify for parameters and dartify and cast for return
types. The one place it does matter is when we check the static type
to do int conversions. Here, we should use the erased type instead.

Change-Id: Ibfcb0acc7f2c8a1ba3b52aa42000640982f11962
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/335120
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Srujan Gaddam 2023-11-09 21:58:33 +00:00 committed by Commit Queue
parent c050c8ac22
commit a700d5f902
2 changed files with 31 additions and 2 deletions

View file

@ -124,8 +124,8 @@ class CoreTypesUtil {
// an `int` we check that the double is an integer, and then insert a
// cast. We also let static interop types flow through without
// conversion, both as arguments, and as the return type.
expression = convertAndCast(
returnType, invokeOneArg(dartifyRawTarget, invocation));
expression = convertAndCast(returnType.extensionTypeErasure,
invokeOneArg(dartifyRawTarget, invocation));
}
return expression;
}

View file

@ -2,6 +2,7 @@
// 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.
// SharedOptions=--enable-experiment=inline-class
// Requirements=nnbd-strong
// Test that external members returning numbers have correct semantics.
@ -14,6 +15,10 @@ import 'dart:js_interop';
import 'package:expect/expect.dart';
import 'package:expect/minitest.dart';
extension type IntE(int _) {}
extension type NullableIntE(int? _) {}
@JS()
external void eval(String code);
@ -22,6 +27,9 @@ external void eval(String code);
@JS('integer')
external int get integerAsInt;
@JS('integer')
external IntE get integerAsIntE;
@JS('integer')
external double get integerAsDouble;
@ -36,6 +44,9 @@ external JSNumber get integerAsJSNumber;
@JS('integer')
external int? get integerAsNullInt;
@JS('integer')
external NullableIntE get integerAsNullableIntE;
@JS('integer')
external double? get integerAsNullDouble;
@ -50,6 +61,9 @@ external JSNumber? get integerAsNullJSNumber;
@JS('float')
external int get floatAsInt;
@JS('float')
external IntE get floatAsIntE;
@JS('float')
external double get floatAsDouble;
@ -64,6 +78,9 @@ external JSNumber get floatAsJSNumber;
@JS('float')
external int? get floatAsNullInt;
@JS('float')
external NullableIntE get floatAsNullableIntE;
@JS('float')
external double? get floatAsNullDouble;
@ -78,6 +95,9 @@ external JSNumber? get floatAsNullJSNumber;
@JS('nullVal')
external int get nullAsInt;
@JS('nullVal')
external IntE get nullAsIntE;
@JS('nullVal')
external double get nullAsDouble;
@ -92,6 +112,9 @@ external JSNumber get nullAsJSNumber;
@JS('nullVal')
external int? get nullAsNullInt;
@JS('nullVal')
external NullableIntE get nullAsNullableIntE;
@JS('nullVal')
external double? get nullAsNullDouble;
@ -109,35 +132,41 @@ void main() {
''');
expect(integerAsInt, 0);
expect(integerAsIntE, 0);
expect(integerAsDouble, 0.0);
expect(integerAsNum, 0);
expect(integerAsJSNumber.toDartDouble, 0.0);
expect(integerAsJSNumber.toDartInt, 0);
expect(integerAsNullInt, 0);
expect(integerAsNullableIntE, 0);
expect(integerAsNullDouble, 0.0);
expect(integerAsNullNum, 0);
expect(integerAsNullJSNumber!.toDartDouble, 0.0);
expect(integerAsNullJSNumber!.toDartInt, 0);
Expect.throws(() => floatAsInt);
Expect.throws(() => floatAsIntE);
expect(floatAsDouble, 0.5);
expect(floatAsNum, 0.5);
expect(floatAsJSNumber.toDartDouble, 0.5);
Expect.throws(() => floatAsJSNumber.toDartInt);
Expect.throws(() => floatAsNullInt);
Expect.throws(() => floatAsNullableIntE);
expect(floatAsNullDouble, 0.5);
expect(floatAsNullNum, 0.5);
expect(floatAsNullJSNumber!.toDartDouble, 0.5);
Expect.throws(() => floatAsNullJSNumber!.toDartInt);
Expect.throws(() => nullAsInt);
Expect.throws(() => nullAsIntE);
Expect.throws(() => nullAsDouble);
Expect.throws(() => nullAsNum);
Expect.throws(() => nullAsJSNumber);
expect(nullAsNullInt, null);
expect(nullAsNullableIntE, null);
expect(nullAsNullDouble, null);
expect(nullAsNullNum, null);
expect(nullAsNullJSNumber, null);