Skip to content

Commit 04d4be0

Browse files
author
Olivier Chafik
committed
Less dart.notNull checks for local vars using flow-insensitive nullability inference.
Within some AST context (at library granularity, for convenience), we collect all the assignments to local vars: - Declaration with no initializer amounts to `null` assignment - Assignment ops are expanded naively: `x++` yield an assigned value of `x + 1`, etc We detect "trivially nullable" variables (e.g. `var x;`, `x = breaking.out;`) by spotting assigned values that are nullable under the optimistic assumption that all known variables are non-nullable. Then we build a nullability dependency graph in linear time: whenever we see `x = y;`, we know that "y is nullable" implies "x is nullable". Finally, we propagate "trivial nullabilities" through that graph: any variable that wasn't reached is deemed not-nullable. (this is similar to mark and sweep garbage collection, where the roots are the "trivially nullable" variables; credits to leafpetersen@ for linear solution)
1 parent 00f49b6 commit 04d4be0

40 files changed

+2954
-2373
lines changed

pkg/dev_compiler/lib/runtime/dart/_debugger.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,12 +420,12 @@ dart_library.library('dart/_debugger', null, /* Imports */[
420420
let ret = dart.list([], NameValuePair);
421421
let i = 0;
422422
for (let entry of iterable) {
423-
if (dart.notNull(i) > dart.notNull(exports.maxIterableChildrenToDisplay)) {
423+
if (i > dart.notNull(exports.maxIterableChildrenToDisplay)) {
424424
ret[dartx.add](new NameValuePair({name: 'Warning', value: 'Truncated Iterable display'}));
425425
break;
426426
}
427427
ret[dartx.add](new NameValuePair({name: dart.toString(i), value: entry}));
428-
i = dart.notNull(i) + 1;
428+
i++;
429429
}
430430
this.addMetadataChildren(object, ret);
431431
return ret;

pkg/dev_compiler/lib/runtime/dart/_interceptors.js

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
127127
}
128128
[dartx.remove](element) {
129129
this[dartx.checkGrowable]('remove');
130-
for (let i = 0; dart.notNull(i) < dart.notNull(this[dartx.length]); i = dart.notNull(i) + 1) {
130+
for (let i = 0; i < dart.notNull(this[dartx.length]); i++) {
131131
if (dart.equals(this[dartx.get](i), element)) {
132132
this.splice(i, 1);
133133
return true;
@@ -163,7 +163,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
163163
[dartx.forEach](f) {
164164
dart.as(f, dart.functionType(dart.void, [E]));
165165
let length = this[dartx.length];
166-
for (let i = 0; dart.notNull(i) < dart.notNull(length); i = dart.notNull(i) + 1) {
166+
for (let i = 0; i < dart.notNull(length); i++) {
167167
f(dart.as(this[i], E));
168168
if (length != this[dartx.length]) {
169169
dart.throw(new core.ConcurrentModificationError(this));
@@ -177,7 +177,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
177177
[dartx.join](separator) {
178178
if (separator === void 0) separator = "";
179179
let list = core.List.new(this[dartx.length]);
180-
for (let i = 0; dart.notNull(i) < dart.notNull(this[dartx.length]); i = dart.notNull(i) + 1) {
180+
for (let i = 0; i < dart.notNull(this[dartx.length]); i++) {
181181
list[dartx.set](i, `${this[dartx.get](i)}`);
182182
}
183183
return list.join(separator);
@@ -312,7 +312,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
312312
return _internal.IterableMixinWorkaround.lastIndexOfList(this, element, start);
313313
}
314314
[dartx.contains](other) {
315-
for (let i = 0; dart.notNull(i) < dart.notNull(this[dartx.length]); i = dart.notNull(i) + 1) {
315+
for (let i = 0; i < dart.notNull(this[dartx.length]); i++) {
316316
if (dart.equals(this[dartx.get](i), other)) return true;
317317
}
318318
return false;
@@ -659,7 +659,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
659659
let exponent = +dart.dindex(match, 3);
660660
if (dart.dindex(match, 2) != null) {
661661
result = result + dart.dindex(match, 2);
662-
exponent = dart.notNull(exponent) - dart.dindex(match, 2).length;
662+
exponent = exponent - dart.dindex(match, 2).length;
663663
}
664664
return dart.notNull(result) + "0"[dartx['*']](exponent);
665665
}
@@ -696,11 +696,11 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
696696
_js_helper.checkNull(other);
697697
let result = this % other;
698698
if (result == 0) return 0;
699-
if (dart.notNull(result) > 0) return result;
699+
if (result > 0) return result;
700700
if (other < 0) {
701-
return dart.notNull(result) - other;
701+
return result - other;
702702
} else {
703-
return dart.notNull(result) + other;
703+
return result + other;
704704
}
705705
}
706706
[_isInt32](value) {
@@ -773,12 +773,12 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
773773
}
774774
[dartx.toSigned](width) {
775775
let signMask = 1 << dart.notNull(width) - 1;
776-
return (this & dart.notNull(signMask) - 1) - (this & dart.notNull(signMask));
776+
return (this & signMask - 1) - (this & signMask);
777777
}
778778
get [dartx.bitLength]() {
779779
let nonneg = this < 0 ? -this - 1 : this;
780-
if (dart.notNull(nonneg) >= 4294967296) {
781-
nonneg = (dart.notNull(nonneg) / 4294967296)[dartx.truncate]();
780+
if (nonneg >= 4294967296) {
781+
nonneg = (nonneg / 4294967296)[dartx.truncate]();
782782
return dart.notNull(JSNumber._bitCount(JSNumber._spread(nonneg))) + 32;
783783
}
784784
return JSNumber._bitCount(JSNumber._spread(nonneg));
@@ -934,8 +934,8 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
934934
dart.throw(new core.RangeError.range(start, 0, string[dartx.length]));
935935
}
936936
if (dart.notNull(start) + dart.notNull(this[dartx.length]) > dart.notNull(string[dartx.length])) return null;
937-
for (let i = 0; dart.notNull(i) < dart.notNull(this[dartx.length]); i = dart.notNull(i) + 1) {
938-
if (string[dartx.codeUnitAt](dart.notNull(start) + dart.notNull(i)) != this[dartx.codeUnitAt](i)) {
937+
for (let i = 0; i < dart.notNull(this[dartx.length]); i++) {
938+
if (string[dartx.codeUnitAt](dart.notNull(start) + i) != this[dartx.codeUnitAt](i)) {
939939
return null;
940940
}
941941
}
@@ -998,7 +998,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
998998
result[dartx.add](this[dartx.substring](start, end));
999999
start = matchEnd;
10001000
}
1001-
if (dart.notNull(start) < dart.notNull(this[dartx.length]) || dart.notNull(length) > 0) {
1001+
if (dart.notNull(start) < dart.notNull(this[dartx.length]) || length > 0) {
10021002
result[dartx.add](this[dartx.substring](start));
10031003
}
10041004
return result;
@@ -1013,7 +1013,7 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
10131013
let other = pattern;
10141014
let otherLength = other[dartx.length];
10151015
let endIndex = dart.notNull(index) + dart.notNull(otherLength);
1016-
if (dart.notNull(endIndex) > dart.notNull(this[dartx.length])) return false;
1016+
if (endIndex > dart.notNull(this[dartx.length])) return false;
10171017
return other == this.substring(index, endIndex);
10181018
}
10191019
return pattern[dartx.matchAsPrefix](this, index) != null;
@@ -1173,23 +1173,23 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
11731173
let result = '';
11741174
let s = this;
11751175
while (true) {
1176-
if ((dart.notNull(times) & 1) == 1) result = dart.notNull(s) + dart.notNull(result);
1176+
if ((dart.notNull(times) & 1) == 1) result = s + result;
11771177
times = times >>> 1;
11781178
if (times == 0) break;
1179-
s = dart.notNull(s) + dart.notNull(s);
1179+
s = s + s;
11801180
}
11811181
return result;
11821182
}
11831183
[dartx.padLeft](width, padding) {
11841184
if (padding === void 0) padding = ' ';
11851185
let delta = dart.notNull(width) - dart.notNull(this[dartx.length]);
1186-
if (dart.notNull(delta) <= 0) return this;
1186+
if (delta <= 0) return this;
11871187
return padding[dartx['*']](delta) + this;
11881188
}
11891189
[dartx.padRight](width, padding) {
11901190
if (padding === void 0) padding = ' ';
11911191
let delta = dart.notNull(width) - dart.notNull(this[dartx.length]);
1192-
if (dart.notNull(delta) <= 0) return this;
1192+
if (delta <= 0) return this;
11931193
return this[dartx['+']](padding[dartx['*']](delta));
11941194
}
11951195
get [dartx.codeUnits]() {
@@ -1263,14 +1263,14 @@ dart_library.library('dart/_interceptors', null, /* Imports */[
12631263
}
12641264
get hashCode() {
12651265
let hash = 0;
1266-
for (let i = 0; dart.notNull(i) < dart.notNull(this[dartx.length]); i = dart.notNull(i) + 1) {
1267-
hash = 536870911 & dart.notNull(hash) + this.charCodeAt(i);
1268-
hash = 536870911 & dart.notNull(hash) + ((524287 & dart.notNull(hash)) << 10);
1266+
for (let i = 0; i < dart.notNull(this[dartx.length]); i++) {
1267+
hash = 536870911 & hash + this.charCodeAt(i);
1268+
hash = 536870911 & hash + ((524287 & hash) << 10);
12691269
hash = hash ^ hash >> 6;
12701270
}
1271-
hash = 536870911 & dart.notNull(hash) + ((67108863 & dart.notNull(hash)) << 3);
1271+
hash = 536870911 & hash + ((67108863 & hash) << 3);
12721272
hash = hash ^ hash >> 11;
1273-
return 536870911 & dart.notNull(hash) + ((16383 & dart.notNull(hash)) << 15);
1273+
return 536870911 & hash + ((16383 & hash) << 15);
12741274
}
12751275
get runtimeType() {
12761276
return core.String;

0 commit comments

Comments
 (0)