Skip to content

Commit d54e2bb

Browse files
Dmitry Stefantsovcommit-bot@chromium.org
Dmitry Stefantsov
authored andcommitted
[cfe,ddc,dart2js,vm] Add NullType
This CL is the sum of the following 5 CLs: * https://dart-review.googlesource.com/c/sdk/+/170342/ * https://dart-review.googlesource.com/c/sdk/+/170344/ * https://dart-review.googlesource.com/c/sdk/+/170345/ * https://dart-review.googlesource.com/c/sdk/+/170346/ * https://dart-review.googlesource.com/c/sdk/+/170347/ The reason for landing the 5 CLs as one CL is to prevent potential troubles with bisecting over the branch because the change is fully functional only with all 5 CLs. Closes #40122. TEST=Verified by changes in .expect files in pkg/vm/. Bug: #40122 Change-Id: Ib8197802fdc69694387ae47ac990c58b3aaab7a5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170689 Commit-Queue: Dmitry Stefantsov <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 1876c67 commit d54e2bb

File tree

621 files changed

+2532
-2393
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

621 files changed

+2532
-2393
lines changed

pkg/compiler/lib/src/ir/scope_visitor.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,10 @@ class ScopeModelBuilder extends ir.Visitor<EvaluationComplexity>
700700
EvaluationComplexity visitNeverType(ir.NeverType node) =>
701701
const EvaluationComplexity.lazy();
702702

703+
@override
704+
EvaluationComplexity visitNullType(ir.NullType node) =>
705+
const EvaluationComplexity.lazy();
706+
703707
@override
704708
EvaluationComplexity visitInvalidType(ir.InvalidType node) =>
705709
const EvaluationComplexity.lazy();

pkg/compiler/lib/src/ir/static_type.dart

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,12 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
195195
while (type is ir.TypeParameterType) {
196196
type = (type as ir.TypeParameterType).parameter.bound;
197197
}
198-
return type is ir.InterfaceType ? type : null;
198+
if (type is ir.InterfaceType) {
199+
return type;
200+
} else if (type is ir.NullType) {
201+
return typeEnvironment.coreTypes.deprecatedNullType;
202+
}
203+
return null;
199204
}
200205

201206
/// Returns the static type of the expression as an instantiation of
@@ -222,7 +227,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
222227
while (type is ir.TypeParameterType) {
223228
type = (type as ir.TypeParameterType).parameter.bound;
224229
}
225-
if (type == typeEnvironment.nullType) {
230+
if (type is ir.NullType) {
226231
return typeEnvironment.coreTypes
227232
.bottomInterfaceType(superclass, currentLibrary.nullable);
228233
}
@@ -711,7 +716,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
711716
ir.DartType promotedType = typeMap.typeOf(node, typeEnvironment);
712717
assert(
713718
node.promotedType == null ||
714-
promotedType == typeEnvironment.nullType ||
719+
promotedType is ir.NullType ||
715720
promotedType is ir.FutureOrType ||
716721
typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
717722
ir.SubtypeCheckMode.ignoringNullabilities),
@@ -1003,7 +1008,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
10031008
ir.DartType visitNullCheck(ir.NullCheck node) {
10041009
ir.DartType operandType = visitNode(node.operand);
10051010
handleNullCheck(node, operandType);
1006-
ir.DartType resultType = operandType == typeEnvironment.nullType
1011+
ir.DartType resultType = operandType is ir.NullType
10071012
? const ir.NeverType(ir.Nullability.nonNullable)
10081013
: operandType.withDeclaredNullability(ir.Nullability.nonNullable);
10091014
_staticTypeCache._expressionTypes[node] = resultType;
@@ -1502,13 +1507,13 @@ class TypeHolder {
15021507
for (ir.DartType type in falseTypes) {
15031508
if (typeEnvironment.isSubtypeOf(
15041509
declaredType, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
1505-
return typeEnvironment.nullType;
1510+
return const ir.NullType();
15061511
}
15071512
}
15081513
}
15091514
if (trueTypes != null) {
15101515
for (ir.DartType type in trueTypes) {
1511-
if (type == typeEnvironment.nullType) {
1516+
if (type is ir.NullType) {
15121517
return type;
15131518
}
15141519
if (typeEnvironment.isSubtypeOf(
@@ -1770,9 +1775,9 @@ class TargetInfo {
17701775
if (candidate == null) {
17711776
candidate = type;
17721777
} else {
1773-
if (type == typeEnvironment.nullType) {
1778+
if (type is ir.NullType) {
17741779
// Keep the current candidate.
1775-
} else if (candidate == typeEnvironment.nullType) {
1780+
} else if (candidate is ir.NullType) {
17761781
candidate = type;
17771782
} else if (typeEnvironment.isSubtypeOf(
17781783
candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {

pkg/compiler/lib/src/ir/static_type_base.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ abstract class StaticTypeBase extends ir.Visitor<ir.DartType> {
121121
}
122122

123123
@override
124-
ir.DartType visitNullLiteral(ir.NullLiteral node) => typeEnvironment.nullType;
124+
ir.DartType visitNullLiteral(ir.NullLiteral node) => const ir.NullType();
125125

126126
@override
127127
ir.DartType visitIntLiteral(ir.IntLiteral node) =>

pkg/compiler/lib/src/ir/util.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ class _FreeVariableVisitor implements ir.DartTypeVisitor<bool> {
221221
@override
222222
bool visitNeverType(ir.NeverType node) => false;
223223

224+
@override
225+
bool visitNullType(ir.NullType node) => false;
226+
224227
@override
225228
bool visitVoidType(ir.VoidType node) => false;
226229

pkg/compiler/lib/src/ir/visitors.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
181181
DartType visitNeverType(ir.NeverType node) {
182182
return _convertNullability(_dartTypes.neverType(), node.nullability);
183183
}
184+
185+
@override
186+
DartType visitNullType(ir.NullType node) {
187+
return elementMap.commonElements.nullType;
188+
}
184189
}
185190

186191
class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
141141
if (receiverType is ir.InterfaceType) {
142142
return new StrongModeConstraint(commonElements, _nativeBasicData,
143143
elementMap.getClass(receiverType.classNode), relation);
144+
} else if (receiverType is ir.NullType) {
145+
return new StrongModeConstraint(
146+
commonElements,
147+
_nativeBasicData,
148+
elementMap.getClass(typeEnvironment.coreTypes.deprecatedNullClass),
149+
relation);
144150
}
145151
return null;
146152
}

pkg/compiler/lib/src/serialization/abstract_source.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ abstract class AbstractDataSource extends DataSourceMixin
276276
ir.Nullability nullability = readEnum(ir.Nullability.values);
277277
ir.DartType typeArgument = _readDartTypeNode(functionTypeVariables);
278278
return new ir.FutureOrType(typeArgument, nullability);
279+
case DartTypeNodeKind.nullType:
280+
return const ir.NullType();
279281
}
280282
throw new UnsupportedError("Unexpected DartTypeKind $kind");
281283
}

pkg/compiler/lib/src/serialization/helpers.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ enum DartTypeNodeKind {
120120
doesNotComplete,
121121
neverType,
122122
futureOrType,
123+
nullType,
123124
}
124125

125126
const String functionTypeNodeTag = 'function-type-node';
@@ -180,6 +181,12 @@ class DartTypeNodeWriter
180181
_sink.writeEnum(node.nullability);
181182
}
182183

184+
@override
185+
void visitNullType(
186+
ir.NullType node, List<ir.TypeParameter> functionTypeVariables) {
187+
_sink.writeEnum(DartTypeNodeKind.nullType);
188+
}
189+
183190
@override
184191
void visitInterfaceType(
185192
ir.InterfaceType node, List<ir.TypeParameter> functionTypeVariables) {

pkg/compiler/test/analyses/analysis_helper.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ class DynamicVisitor extends StaticTypeVisitorBase {
311311
ir.DartType staticType = node?.accept(this);
312312
assert(
313313
node is! ir.Expression ||
314-
staticType == typeEnvironment.nullType ||
314+
staticType is ir.NullType ||
315315
staticType is ir.FutureOrType ||
316316
typeEnvironment.isSubtypeOf(
317317
staticType,

pkg/compiler/test/helpers/ir_types.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ class TypeTextVisitor implements ir.DartTypeVisitor1<void, StringBuffer> {
118118
sb.write('Never');
119119
}
120120

121+
@override
122+
void visitNullType(ir.NullType node, StringBuffer sb) {
123+
sb.write('Null');
124+
}
125+
121126
@override
122127
void visitVoidType(ir.VoidType node, StringBuffer sb) {
123128
sb.write('void');

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
10701070
c == _coreTypes.stringClass ||
10711071
c == _coreTypes.functionClass ||
10721072
c == _coreTypes.intClass ||
1073-
c == _coreTypes.nullClass ||
1073+
c == _coreTypes.deprecatedNullClass ||
10741074
c == _coreTypes.numClass ||
10751075
c == _coreTypes.doubleClass ||
10761076
c == _coreTypes.boolClass)) {
@@ -2567,12 +2567,16 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
25672567

25682568
@override
25692569
js_ast.Expression visitBottomType(BottomType type) =>
2570-
_emitType(_types.nullType);
2570+
_emitType(const NullType());
2571+
2572+
@override
2573+
js_ast.Expression visitNullType(NullType type) =>
2574+
_emitInterfaceType(_coreTypes.deprecatedNullType);
25712575

25722576
@override
25732577
js_ast.Expression visitNeverType(NeverType type) =>
25742578
type.nullability == Nullability.nullable
2575-
? visitInterfaceType(_coreTypes.nullType)
2579+
? visitNullType(const NullType())
25762580
: _emitNullabilityWrapper(runtimeCall('Never'), type.nullability);
25772581

25782582
/// Normalizes `FutureOr` types and emits the normalized version.
@@ -2605,8 +2609,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
26052609
// FutureOr<Never> --> Future<Never>
26062610
return _emitInterfaceType(InterfaceType(
26072611
_coreTypes.futureClass, futureOr.nullability, [typeArgument]));
2608-
} else if (typeArgument is InterfaceType &&
2609-
typeArgument.classNode == _coreTypes.nullClass) {
2612+
} else if (typeArgument is NullType) {
26102613
// FutureOr<Null> --> Future<Null>?
26112614
return _emitInterfaceType(InterfaceType(
26122615
_coreTypes.futureClass, Nullability.nullable, [typeArgument]));
@@ -2690,7 +2693,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
26902693
// * The types were written in JS context or as part of the dart:_runtime
26912694
// library.
26922695
if (!emitNullability ||
2693-
type == _coreTypes.nullType ||
2696+
type == _coreTypes.deprecatedNullType ||
26942697
// TODO(38701) Remove these once the SDK has unforked and is running
26952698
// "opted-in"
26962699
!coreLibrary.isNonNullableByDefault &&
@@ -5134,8 +5137,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
51345137
importUri.path == 'html_common');
51355138

51365139
bool _isNull(Expression expr) =>
5137-
expr is NullLiteral ||
5138-
expr.getStaticType(_staticTypeContext) == _coreTypes.nullType;
5140+
expr is NullLiteral || expr.getStaticType(_staticTypeContext) is NullType;
51395141

51405142
bool _doubleEqIsIdentity(Expression left, Expression right) {
51415143
// If we statically know LHS or RHS is null we can use ==.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ class JSTypeRep extends SharedJSTypeRep<DartType> {
3939

4040
// Note that this should be changed if Dart gets non-nullable types
4141
if (type == const BottomType()) return JSType.jsNull;
42+
if (type == const NullType()) return JSType.jsNull;
4243

4344
if (type is InterfaceType) {
4445
var c = type.classNode;
45-
if (c == coreTypes.nullClass) return JSType.jsNull;
4646
if (c == coreTypes.numClass ||
4747
c == coreTypes.intClass ||
4848
c == coreTypes.doubleClass ||

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ bool isKnownDartTypeImplementor(DartType t) {
336336
t is InterfaceType ||
337337
t is InvalidType ||
338338
t is NeverType ||
339+
t is NullType ||
339340
t is TypeParameterType ||
340341
t is TypedefType ||
341342
t is VoidType;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class _CacheTable {
119119
if (type is VoidType) return 'void';
120120
if (type is NeverType) return 'Never$nullability';
121121
if (type is BottomType) return 'bottom';
122+
if (type is NullType) return 'Null';
122123
return 'invalid';
123124
}
124125

pkg/dev_compiler/test/nullable_inference_test.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void main() {
5252
});
5353
test('Map', () async {
5454
await expectNotNull('main() { print({"x": null}); }',
55-
'<dart.core::String*, dart.core::Null?>{"x": null}, "x"');
55+
'<dart.core::String*, Null>{"x": null}, "x"');
5656
});
5757

5858
test('Symbol', () async {
@@ -258,7 +258,7 @@ void main() {
258258

259259
test('function expression', () async {
260260
await expectNotNull(
261-
'main() { () => null; f() {}; f; }', 'dart.core::Null? () => null, f');
261+
'main() { () => null; f() {}; f; }', 'Null () => null, f');
262262
});
263263

264264
test('cascades (kernel BlockExpression)', () async {
@@ -399,7 +399,7 @@ void main() {
399399
await expectNotNull('''main() {
400400
var x = () => 42;
401401
var y = (() => x = null);
402-
}''', 'dart.core::int* () => 42, 42, dart.core::Null? () => x = null');
402+
}''', 'dart.core::int* () => 42, 42, Null () => x = null');
403403
});
404404
test('do not depend on unrelated variables', () async {
405405
await expectNotNull('''main() {

pkg/front_end/lib/src/fasta/builder/class_builder.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'package:kernel/ast.dart'
1616
InterfaceType,
1717
Member,
1818
Name,
19+
NullType,
1920
Nullability,
2021
Supertype,
2122
TypeParameter,
@@ -538,7 +539,7 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
538539
Nullability nullability, List<DartType> arguments) {
539540
assert(arguments == null || cls.typeParameters.length == arguments.length);
540541
if (isNullClass) {
541-
nullability = Nullability.nullable;
542+
return const NullType();
542543
}
543544
if (name == "FutureOr") {
544545
LibraryBuilder parentLibrary = parent;
@@ -781,7 +782,7 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
781782
InterfaceType requiredInterface =
782783
substitution.substituteSupertype(constraint).asInterfaceType;
783784
InterfaceType implementedInterface = hierarchy.getTypeAsInstanceOf(
784-
supertype, requiredInterface.classNode, library.library, coreTypes);
785+
supertype, requiredInterface.classNode, library.library);
785786
if (implementedInterface == null ||
786787
!typeEnvironment.areMutualSubtypes(
787788
implementedInterface,

pkg/front_end/lib/src/fasta/builder/library_builder.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ abstract class LibraryBuilder implements ModifierBuilder {
157157

158158
void addSyntheticDeclarationOfNever();
159159

160+
void addSyntheticDeclarationOfNull();
161+
160162
/// Lookups the member [name] declared in this library.
161163
///
162164
/// If [required] is `true` and no member is found an internal problem is
@@ -387,6 +389,9 @@ abstract class LibraryBuilderImpl extends ModifierBuilderImpl
387389
if (scope.lookupLocalMember("Never", setter: false) == null) {
388390
addSyntheticDeclarationOfNever();
389391
}
392+
if (scope.lookupLocalMember("Null", setter: false) == null) {
393+
addSyntheticDeclarationOfNull();
394+
}
390395
}
391396

392397
@override

0 commit comments

Comments
 (0)