mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
fix #31781, fromEnvironment constants in DDK
Change-Id: I5915677204c0b02321e8db6a34e870b6ac63179d Reviewed-on: https://dart-review.googlesource.com/32681 Commit-Queue: Jenny Messerly <jmesserly@google.com> Reviewed-by: Vijay Menon <vsm@google.com>
This commit is contained in:
parent
7434bf6b73
commit
0add93f98e
|
@ -118,6 +118,7 @@ class ModuleCompiler {
|
|||
// TODO(vsm): Should this be hardcoded?
|
||||
context.declaredVariables.define('dart.library.html', 'true');
|
||||
context.declaredVariables.define('dart.library.io', 'false');
|
||||
context.declaredVariables.define('dart.library.ui', 'false');
|
||||
|
||||
if (!context.analysisOptions.strongMode) {
|
||||
throw new ArgumentError('AnalysisContext must be strong mode');
|
||||
|
|
|
@ -153,7 +153,8 @@ Future<CompilerResult> _compile(List<String> args,
|
|||
.toList();
|
||||
|
||||
var sdkSummaryPath = argResults['dart-sdk-summary'] ??
|
||||
path.absolute(ddcPath, 'gen', 'sdk', 'ddc_sdk.dill');
|
||||
path.join(path.dirname(path.dirname(Platform.resolvedExecutable)), 'lib',
|
||||
'_internal', 'ddc_sdk.dill');
|
||||
|
||||
var packageFile =
|
||||
argResults['packages'] ?? path.absolute(ddcPath, '..', '..', '.packages');
|
||||
|
@ -367,5 +368,14 @@ Map<String, String> parseAndRemoveDeclaredVariables(List<String> args) {
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add platform defined variables
|
||||
declaredVariables['dart.isVM'] = 'false';
|
||||
|
||||
// TODO(vsm): Should this be hardcoded?
|
||||
declaredVariables['dart.library.html'] = 'true';
|
||||
declaredVariables['dart.library.io'] = 'false';
|
||||
declaredVariables['dart.library.ui'] = 'false';
|
||||
|
||||
return declaredVariables;
|
||||
}
|
||||
|
|
|
@ -4336,56 +4336,64 @@ class ProgramCompiler
|
|||
|
||||
@override
|
||||
visitConstructorInvocation(ConstructorInvocation node) {
|
||||
var target = node.target;
|
||||
var targetName = target.name;
|
||||
var ctor = node.target;
|
||||
var args = node.arguments;
|
||||
var ctorClass = ctor.enclosingClass;
|
||||
if (_isObjectLiteral(ctorClass)) return _emitObjectLiteral(args);
|
||||
|
||||
var enclosingClass = target.enclosingClass;
|
||||
if (node.isConst &&
|
||||
targetName.name == 'fromEnvironment' &&
|
||||
target.enclosingLibrary == coreTypes.coreLibrary &&
|
||||
args.positional.length == 1) {
|
||||
var varName = (args.positional[0] as StringLiteral).value;
|
||||
var value = declaredVariables[varName];
|
||||
var defaultArg = args.named.isNotEmpty ? args.named[0].value : null;
|
||||
if (enclosingClass == coreTypes.stringClass) {
|
||||
value ??= (defaultArg as StringLiteral)?.value;
|
||||
return value != null ? js.escapedString(value) : new JS.LiteralNull();
|
||||
} else if (enclosingClass == coreTypes.intClass) {
|
||||
var intValue = int.parse(value ?? '',
|
||||
onError: (_) => (defaultArg as IntLiteral)?.value);
|
||||
return intValue != null ? js.number(intValue) : new JS.LiteralNull();
|
||||
} else if (enclosingClass == coreTypes.boolClass) {
|
||||
if (value == "true") return js.boolean(true);
|
||||
if (value == "false") return js.boolean(false);
|
||||
return js
|
||||
.boolean(defaultArg != null && (defaultArg as BoolLiteral)?.value);
|
||||
} else {
|
||||
return _emitInvalidNode(
|
||||
node, '${enclosingClass}.fromEnvironment constant');
|
||||
}
|
||||
JS.Expression emitNew() {
|
||||
return new JS.New(_emitConstructorName(node.constructedType, ctor),
|
||||
_emitArgumentList(args, types: false));
|
||||
}
|
||||
return _emitConstructorInvocation(
|
||||
target, node.constructedType, args, node.isConst);
|
||||
|
||||
return node.isConst ? _emitConst(emitNew) : emitNew();
|
||||
}
|
||||
|
||||
JS.Expression _emitFactoryInvocation(StaticInvocation node) {
|
||||
var args = node.arguments;
|
||||
var target = node.target;
|
||||
var c = target.enclosingClass;
|
||||
var type =
|
||||
c.typeParameters.isEmpty ? c.rawType : new InterfaceType(c, args.types);
|
||||
var ctor = node.target;
|
||||
var ctorClass = ctor.enclosingClass;
|
||||
var type = ctorClass.typeParameters.isEmpty
|
||||
? ctorClass.rawType
|
||||
: new InterfaceType(ctorClass, args.types);
|
||||
|
||||
if (node.isConst &&
|
||||
ctor.name.name == 'fromEnvironment' &&
|
||||
ctor.enclosingLibrary == coreTypes.coreLibrary &&
|
||||
args.positional.length == 1 &&
|
||||
// TODO(jmesserly): this does not correctly handle when the arguments to
|
||||
// fromEnvironment are constant non-literal values.
|
||||
args.positional[0] is BasicLiteral &&
|
||||
(args.named.isEmpty || args.named[0].value is BasicLiteral)) {
|
||||
var varName = (args.positional[0] as StringLiteral).value;
|
||||
var value = declaredVariables[varName];
|
||||
var defaultArg = args.named.isNotEmpty ? args.named[0].value : null;
|
||||
if (ctorClass == coreTypes.stringClass) {
|
||||
if (value != null) return js.escapedString(value);
|
||||
return _visitExpression(defaultArg) ?? new JS.LiteralNull();
|
||||
} else if (ctorClass == coreTypes.intClass) {
|
||||
var intValue = int.parse(value ?? '', onError: (_) => null);
|
||||
if (intValue != null) return js.number(intValue);
|
||||
return _visitExpression(defaultArg) ?? new JS.LiteralNull();
|
||||
} else if (ctorClass == coreTypes.boolClass) {
|
||||
if (value == "true") return js.boolean(true);
|
||||
if (value == "false") return js.boolean(false);
|
||||
return _visitExpression(defaultArg) ?? js.boolean(false);
|
||||
} else {
|
||||
return _emitInvalidNode(node, '$ctorClass.fromEnvironment constant');
|
||||
}
|
||||
}
|
||||
if (args.positional.isEmpty &&
|
||||
args.named.isEmpty &&
|
||||
c.enclosingLibrary.importUri.scheme == 'dart') {
|
||||
ctorClass.enclosingLibrary.importUri.scheme == 'dart') {
|
||||
// Skip the slow SDK factory constructors when possible.
|
||||
switch (c.name) {
|
||||
switch (ctorClass.name) {
|
||||
case 'Map':
|
||||
case 'HashMap':
|
||||
case 'LinkedHashMap':
|
||||
if (target.name == '') {
|
||||
if (ctor.name == '') {
|
||||
return js.call('new #.new()', _emitMapImplType(type));
|
||||
} else if (target.name == 'identity') {
|
||||
} else if (ctor.name == 'identity') {
|
||||
return js.call(
|
||||
'new #.new()', _emitMapImplType(type, identity: true));
|
||||
}
|
||||
|
@ -4393,15 +4401,15 @@ class ProgramCompiler
|
|||
case 'Set':
|
||||
case 'HashSet':
|
||||
case 'LinkedHashSet':
|
||||
if (target.name == '') {
|
||||
if (ctor.name == '') {
|
||||
return js.call('new #.new()', _emitSetImplType(type));
|
||||
} else if (target.name == 'identity') {
|
||||
} else if (ctor.name == 'identity') {
|
||||
return js.call(
|
||||
'new #.new()', _emitSetImplType(type, identity: true));
|
||||
}
|
||||
break;
|
||||
case 'List':
|
||||
if (target.name == '' && type is InterfaceType) {
|
||||
if (ctor.name == '' && type is InterfaceType) {
|
||||
return _emitList(type.typeArguments[0], []);
|
||||
}
|
||||
break;
|
||||
|
@ -4410,28 +4418,13 @@ class ProgramCompiler
|
|||
|
||||
JS.Expression emitNew() {
|
||||
// Native factory constructors are JS constructors - use new here.
|
||||
return new JS.Call(_emitConstructorName(type, target),
|
||||
return new JS.Call(_emitConstructorName(type, ctor),
|
||||
_emitArgumentList(args, types: false));
|
||||
}
|
||||
|
||||
return node.isConst ? _emitConst(emitNew) : emitNew();
|
||||
}
|
||||
|
||||
JS.Expression _emitConstructorInvocation(
|
||||
Constructor ctor, InterfaceType type, Arguments arguments, bool isConst) {
|
||||
var enclosingClass = ctor.enclosingClass;
|
||||
if (_isObjectLiteral(enclosingClass)) {
|
||||
return _emitObjectLiteral(arguments);
|
||||
}
|
||||
|
||||
JS.Expression emitNew() {
|
||||
return new JS.New(_emitConstructorName(type, ctor),
|
||||
_emitArgumentList(arguments, types: false));
|
||||
}
|
||||
|
||||
return isConst ? _emitConst(emitNew) : emitNew();
|
||||
}
|
||||
|
||||
JS.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
|
||||
var typeArgs = type.typeArguments;
|
||||
if (typeArgs.isEmpty) return _emitType(type);
|
||||
|
|
|
@ -737,7 +737,6 @@ truncdiv_test: RuntimeError # Issue 29920
|
|||
callable_test/none: RuntimeError # Expect.throws(TypeError) fails: Did not throw
|
||||
conditional_import_string_test: RuntimeError # Unsupported operation: String.fromEnvironment can only be used as a const constructor
|
||||
conditional_import_test: RuntimeError # Unsupported operation: bool.fromEnvironment can only be used as a const constructor
|
||||
constant_string_interpolation2_test: RuntimeError # TypeError: Cannot read property 'Symbol(dartx.toString)' of null
|
||||
cyclic_type_test/00: RuntimeError # Expect.equals(expected: <Derived>, actual: <dynamic>) fails.
|
||||
cyclic_type_test/01: RuntimeError # Expect.equals(at index 0: Expected <Derived<Derived<int>>...>, Found: <dynamic>) fails.
|
||||
deferred_closurize_load_library_test: RuntimeError # NoSuchMethodError: method not found: 'then'
|
||||
|
|
Loading…
Reference in a new issue