Closed
Description
The code below, compiled with
sdk/bin/dart2js --package-root=out/ReleaseX64/packages ~/play1/bug6j1a.dart \
--trust-type-annotations --dump-info
contains an interceptor call for externalUrl.startsWith('#')
, i.e.
J.startsWith$1$s(externalUrl, "#")
The dumpinfo output shows AA.x is [null|exact=JSString]
, so global type inference does not determine externalUrl cannot be null
.
Further, SSA type propagation does not clean up the type.
So both 'passes' fail to be precise enough.
Changing the first 'if' to two 'if' statements generates the expected code for the return expression:
if (externalUrl == null) return '';
if (externalUrl.isEmpty) return '';
out.js:
encodeSecureHref: [function(externalUrl) {
if (externalUrl == null || externalUrl.length === 0)
return "";
T.AA(externalUrl);
return J.startsWith$1$s(externalUrl, "#") ||
C.JSString_methods.startsWith$1(externalUrl.toLowerCase(), "mailto:")
? externalUrl
: "http://app/" +
P._Uri__uriEncode(C.List_nxB, externalUrl, C.Utf8Codec_false, true);
}, "call$1", "bug6j1a__encodeSecureHref$closure", 2, 0, 0]
bug6j1a.dart:
import 'package:expect/expect.dart';
const String _SECURE_LINK_PREFIX = 'http://app/';
String encodeSecureHref(String externalUrl) {
if (externalUrl == null || externalUrl.isEmpty) {
return '';
}
AA(externalUrl);
return (externalUrl.startsWith('#') ||
externalUrl.toLowerCase().startsWith('mailto:')) ?
externalUrl :
_SECURE_LINK_PREFIX + Uri.encodeQueryComponent(externalUrl);
}
@NoInline()
AA(x) => x;
var f = (x) => x * 2;
main() {
print(encodeSecureHref('#foo'));
print(encodeSecureHref('foo'));
print(encodeSecureHref(null));
print(encodeSecureHref(''));
print(f(100));
f = encodeSecureHref;
print(encodeSecureHref);
}