Skip to content

Commit a26f840

Browse files
nshahancommit-bot@chromium.org
authored andcommitted
[dartdevc] Branch the logic for FutureOr type tests when NNBD is enabled
Creates a baseline for the next change to show the new behavior in a small diff. Change-Id: Ic44ae702b677880ab245c4ae6abd799831cc4d87 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124287 Reviewed-by: Mark Zhou <markzipan@google.com> Commit-Queue: Nicholas Shahan <nshahan@google.com>
1 parent f9969cc commit a26f840

File tree

3 files changed

+123
-48
lines changed

3 files changed

+123
-48
lines changed

pkg/dev_compiler/lib/src/analyzer/code_generator.dart

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -893,29 +893,65 @@ class CodeGenerator extends Object
893893
return null;
894894
}
895895
if (classElem.library.isDartAsync && classElem == types.futureOrElement) {
896-
var typeParamT = getLegacyTypeParameterType(classElem.typeParameters[0]);
897-
var typeT = _emitType(typeParamT);
898-
var futureOfT = _emitType(types.futureType2(typeParamT));
899-
body.add(js.statement('''
900-
#.is = function is_FutureOr(o) {
901-
return #.is(o) || #.is(o);
902-
}
903-
''', [className, typeT, futureOfT]));
904-
// TODO(jmesserly): remove the fallback to `dart.as`. It's only for the
905-
// _ignoreTypeFailure logic.
906-
body.add(js.statement('''
907-
#.as = function as_FutureOr(o) {
908-
if (o == null || #.is(o) || #.is(o)) return o;
909-
return #.as(o, this, false);
910-
}
911-
''', [className, typeT, futureOfT, runtimeModule]));
912-
body.add(js.statement('''
913-
#._check = function check_FutureOr(o) {
914-
if (o == null || #.is(o) || #.is(o)) return o;
915-
return #.as(o, this, true);
916-
}
917-
''', [className, typeT, futureOfT, runtimeModule]));
918-
return null;
896+
// These methods are difficult to place in the runtime or patch files.
897+
// * They need to be callable from the class but they can't be static
898+
// methods on the FutureOr class in Dart because they reference the
899+
// generic type parameter.
900+
// * There isn't an obvious place in dart:_runtime were we could place a
901+
// method that adds these type tests (similar to addTypeTests()) because
902+
// in the bootstrap ordering the Future class hasn't been defined yet.
903+
if (options.nonNullableEnabled) {
904+
// TODO(nshahan) Update FutureOr type tests for NNBD.
905+
var typeParamT =
906+
getLegacyTypeParameterType(classElem.typeParameters[0]);
907+
var typeT = _emitType(typeParamT);
908+
var futureOfT = _emitType(types.futureType2(typeParamT));
909+
body.add(js.statement('''
910+
#.is = function is_FutureOr(o) {
911+
return #.is(o) || #.is(o);
912+
}
913+
''', [className, typeT, futureOfT]));
914+
// TODO(jmesserly): remove the fallback to `dart.as`. It's only for the
915+
// _ignoreTypeFailure logic.
916+
body.add(js.statement('''
917+
#.as = function as_FutureOr(o) {
918+
if (o == null || #.is(o) || #.is(o)) return o;
919+
return #.as(o, this, false);
920+
}
921+
''', [className, typeT, futureOfT, runtimeModule]));
922+
body.add(js.statement('''
923+
#._check = function check_FutureOr(o) {
924+
if (o == null || #.is(o) || #.is(o)) return o;
925+
return #.as(o, this, true);
926+
}
927+
''', [className, typeT, futureOfT, runtimeModule]));
928+
return null;
929+
} else {
930+
var typeParamT =
931+
getLegacyTypeParameterType(classElem.typeParameters[0]);
932+
var typeT = _emitType(typeParamT);
933+
var futureOfT = _emitType(types.futureType2(typeParamT));
934+
body.add(js.statement('''
935+
#.is = function is_FutureOr(o) {
936+
return #.is(o) || #.is(o);
937+
}
938+
''', [className, typeT, futureOfT]));
939+
// TODO(jmesserly): remove the fallback to `dart.as`. It's only for the
940+
// _ignoreTypeFailure logic.
941+
body.add(js.statement('''
942+
#.as = function as_FutureOr(o) {
943+
if (o == null || #.is(o) || #.is(o)) return o;
944+
return #.as(o, this, false);
945+
}
946+
''', [className, typeT, futureOfT, runtimeModule]));
947+
body.add(js.statement('''
948+
#._check = function check_FutureOr(o) {
949+
if (o == null || #.is(o) || #.is(o)) return o;
950+
return #.as(o, this, true);
951+
}
952+
''', [className, typeT, futureOfT, runtimeModule]));
953+
return null;
954+
}
919955
}
920956

921957
body.add(runtimeStatement('addTypeTests(#)', [className]));

pkg/dev_compiler/lib/src/compiler/shared_command.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ class SharedCompilerOptions {
196196
// that build systems do not depend on passing windows-style paths here.
197197
return p.toUri(moduleName).toString();
198198
}
199+
200+
// TODO(nshahan) Cleanup when NNBD graduates experimental status.
201+
bool get nonNullableEnabled => experiments['non-nullable'] ?? false;
199202
}
200203

201204
/// Finds explicit module names of the form `path=name` in [summaryPaths],

pkg/dev_compiler/lib/src/kernel/compiler.dart

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -983,31 +983,67 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
983983

984984
if (c.enclosingLibrary == _coreTypes.asyncLibrary &&
985985
c == _coreTypes.futureOrClass) {
986-
var typeParam =
987-
TypeParameterType(c.typeParameters[0], Nullability.legacy);
988-
var typeT = visitTypeParameterType(typeParam);
989-
var futureOfT = visitInterfaceType(InterfaceType(
990-
_coreTypes.futureClass, Nullability.legacy, [typeParam]));
991-
body.add(js.statement('''
992-
#.is = function is_FutureOr(o) {
993-
return #.is(o) || #.is(o);
994-
}
995-
''', [className, typeT, futureOfT]));
996-
// TODO(jmesserly): remove the fallback to `dart.as`. It's only for the
997-
// _ignoreTypeFailure logic.
998-
body.add(js.statement('''
999-
#.as = function as_FutureOr(o) {
1000-
if (o == null || #.is(o) || #.is(o)) return o;
1001-
return #.as(o, this, false);
1002-
}
1003-
''', [className, typeT, futureOfT, runtimeModule]));
1004-
body.add(js.statement('''
1005-
#._check = function check_FutureOr(o) {
1006-
if (o == null || #.is(o) || #.is(o)) return o;
1007-
return #.as(o, this, true);
1008-
}
1009-
''', [className, typeT, futureOfT, runtimeModule]));
1010-
return null;
986+
// These methods are difficult to place in the runtime or patch files.
987+
// * They need to be callable from the class but they can't be static
988+
// methods on the FutureOr class in Dart because they reference the
989+
// generic type parameter.
990+
// * There isn't an obvious place in dart:_runtime were we could place a
991+
// method that adds these type tests (similar to addTypeTests()) because
992+
// in the bootstrap ordering the Future class hasn't been defined yet.
993+
if (_options.nonNullableEnabled) {
994+
// TODO(nshahan) Update FutureOr type tests for NNBD
995+
var typeParam =
996+
TypeParameterType(c.typeParameters[0], Nullability.legacy);
997+
var typeT = visitTypeParameterType(typeParam);
998+
var futureOfT = visitInterfaceType(InterfaceType(
999+
_coreTypes.futureClass, Nullability.legacy, [typeParam]));
1000+
body.add(js.statement('''
1001+
#.is = function is_FutureOr(o) {
1002+
return #.is(o) || #.is(o);
1003+
}
1004+
''', [className, typeT, futureOfT]));
1005+
// TODO(jmesserly): remove the fallback to `dart.as`. It's only for the
1006+
// _ignoreTypeFailure logic.
1007+
body.add(js.statement('''
1008+
#.as = function as_FutureOr(o) {
1009+
if (o == null || #.is(o) || #.is(o)) return o;
1010+
return #.as(o, this, false);
1011+
}
1012+
''', [className, typeT, futureOfT, runtimeModule]));
1013+
body.add(js.statement('''
1014+
#._check = function check_FutureOr(o) {
1015+
if (o == null || #.is(o) || #.is(o)) return o;
1016+
return #.as(o, this, true);
1017+
}
1018+
''', [className, typeT, futureOfT, runtimeModule]));
1019+
return null;
1020+
} else {
1021+
var typeParam =
1022+
TypeParameterType(c.typeParameters[0], Nullability.legacy);
1023+
var typeT = visitTypeParameterType(typeParam);
1024+
var futureOfT = visitInterfaceType(InterfaceType(
1025+
_coreTypes.futureClass, Nullability.legacy, [typeParam]));
1026+
body.add(js.statement('''
1027+
#.is = function is_FutureOr(o) {
1028+
return #.is(o) || #.is(o);
1029+
}
1030+
''', [className, typeT, futureOfT]));
1031+
// TODO(jmesserly): remove the fallback to `dart.as`. It's only for the
1032+
// _ignoreTypeFailure logic.
1033+
body.add(js.statement('''
1034+
#.as = function as_FutureOr(o) {
1035+
if (o == null || #.is(o) || #.is(o)) return o;
1036+
return #.as(o, this, false);
1037+
}
1038+
''', [className, typeT, futureOfT, runtimeModule]));
1039+
body.add(js.statement('''
1040+
#._check = function check_FutureOr(o) {
1041+
if (o == null || #.is(o) || #.is(o)) return o;
1042+
return #.as(o, this, true);
1043+
}
1044+
''', [className, typeT, futureOfT, runtimeModule]));
1045+
return null;
1046+
}
10111047
}
10121048

10131049
body.add(runtimeStatement('addTypeTests(#)', [className]));

0 commit comments

Comments
 (0)