Version 2.15.0-122.0.dev
Merge commit 'a24d875ff6aa7caf00bb4bbc11975cc206d9265b' into 'dev'
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
index de7daf0..694ecfc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -168,6 +168,29 @@
''');
}
+ Future<void> test_functionTypedParameter_nullable() async {
+ await resolveTestCode('''
+abstract class A {
+ void forEach(int f(double p1, String p2)?);
+}
+
+class B extends A {
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ void forEach(int f(double p1, String p2)?);
+}
+
+class B extends A {
+ @override
+ void forEach(int Function(double p1, String p2)? f) {
+ // TODO: implement forEach
+ }
+}
+''');
+ }
+
Future<void> test_generics_typeArguments() async {
await resolveTestCode('''
class Iterator<T> {
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 8670eee..9f97db2 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -154,12 +154,12 @@
}
class FileGlobFilter extends LintFilter {
- Iterable<Glob> includes;
- Iterable<Glob> excludes;
+ List<Glob> includes;
+ List<Glob> excludes;
FileGlobFilter(Iterable<String> includeGlobs, Iterable<String> excludeGlobs)
- : includes = includeGlobs.map((glob) => Glob(glob)),
- excludes = excludeGlobs.map((glob) => Glob(glob));
+ : includes = includeGlobs.map((glob) => Glob(glob)).toList(),
+ excludes = excludeGlobs.map((glob) => Glob(glob)).toList();
@override
bool filter(AnalysisError lint) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 0738926..3a1b365 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1234,6 +1234,9 @@
writeTypeParameters(type.typeFormals,
methodBeingCopied: methodBeingCopied);
writeParameters(type.parameters, methodBeingCopied: methodBeingCopied);
+ if (type.nullabilitySuffix == NullabilitySuffix.question) {
+ write('?');
+ }
return true;
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index ac77675..c58eee8 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -48,6 +48,10 @@
expect(edit.replacement, equalsIgnoringWhitespace('required a'));
}
+ Future<void> test_writeType_function_nullable() async {
+ await _assertWriteType('int Function(double a, String b)?');
+ }
+
Future<void> test_writeType_Never_none() async {
await _assertWriteType('Never');
}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 69edbdd..605ac63 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -98,7 +98,7 @@
/// A stack of instructions.
///
/// We build the SSA graph by simulating a stack machine.
- List<HInstruction> stack = <HInstruction>[];
+ List<HInstruction> stack = [];
/// The count of nested loops we are currently building.
///
@@ -107,7 +107,7 @@
int loopDepth = 0;
/// A mapping from jump targets to their handlers.
- Map<JumpTarget, JumpHandler> jumpTargets = <JumpTarget, JumpHandler>{};
+ Map<JumpTarget, JumpHandler> jumpTargets = {};
final CompilerOptions options;
final DiagnosticReporter reporter;
@@ -126,7 +126,7 @@
/// for these nodes.
// TODO(karlklose): consider removing this and keeping the (substituted) types
// of the type variables in an environment (like the [LocalsHandler]).
- final List<InterfaceType> _currentImplicitInstantiations = <InterfaceType>[];
+ final List<InterfaceType> _currentImplicitInstantiations = [];
/// Used to report information about inlining (which occurs while building the
/// SSA graph), when dump-info is enabled.
@@ -144,7 +144,7 @@
/// this is a slow path.
bool _inExpressionOfThrow = false;
- final List<KernelInliningState> _inliningStack = <KernelInliningState>[];
+ final List<KernelInliningState> _inliningStack = [];
Local _returnLocal;
DartType _returnType;
@@ -258,7 +258,7 @@
HLocalValue lastAddedParameter;
- Map<Local, HInstruction> parameters = <Local, HInstruction>{};
+ Map<Local, HInstruction> parameters = {};
Set<Local> elidedParameters;
HBasicBlock addNewBlock() {
@@ -706,7 +706,7 @@
// Locals for function type parameters that can be forwarded, in argument
// position order.
- List<Local> _functionTypeParameterLocals = <Local>[];
+ List<Local> _functionTypeParameterLocals = [];
/// Builds a generative constructor.
///
@@ -752,13 +752,13 @@
ConstructorData constructorData = ConstructorData();
_buildInitializers(node, constructorData);
- List<HInstruction> constructorArguments = <HInstruction>[];
+ List<HInstruction> constructorArguments = [];
// Doing this instead of fieldValues.forEach because we haven't defined the
// order of the arguments here. We can define that with JElements.
bool isCustomElement = _nativeData.isNativeOrExtendsNative(cls) &&
!_nativeData.isJsInteropClass(cls);
InterfaceType thisType = _elementEnvironment.getThisType(cls);
- List<FieldEntity> fields = <FieldEntity>[];
+ List<FieldEntity> fields = [];
_elementEnvironment.forEachInstanceField(cls,
(ClassEntity enclosingClass, FieldEntity member) {
HInstruction value = constructorData.fieldValues[member];
@@ -824,7 +824,7 @@
for (ir.Constructor body in constructorData.constructorChain.reversed) {
if (_isEmptyStatement(body.function.body)) continue;
- List<HInstruction> bodyCallInputs = <HInstruction>[];
+ List<HInstruction> bodyCallInputs = [];
if (isCustomElement) {
if (interceptor == null) {
ConstantValue constant = InterceptorConstantValue(cls);
@@ -1067,7 +1067,7 @@
List<HInstruction> _normalizeAndBuildArguments(
ir.Member member, ir.FunctionNode function, ir.Arguments arguments) {
- var builtArguments = <HInstruction>[];
+ List<HInstruction> builtArguments = [];
var positionalIndex = 0;
function.positionalParameters.forEach((ir.VariableDeclaration parameter) {
if (positionalIndex < arguments.positional.length) {
@@ -1247,11 +1247,8 @@
.isDefinitelyTrue);
if (emptyParameters.length > 0) {
_addComment('${emptyParameters} inferred as [empty]');
- add(HInvokeStatic(
- _commonElements.assertUnreachableMethod,
- <HInstruction>[],
- _abstractValueDomain.dynamicType,
- const <DartType>[]));
+ add(HInvokeStatic(_commonElements.assertUnreachableMethod, [],
+ _abstractValueDomain.dynamicType, const []));
_closeFunction();
return;
}
@@ -1267,7 +1264,7 @@
// TODO(sra): Figure out how to keep comment anchored without effects.
void _addComment(String text) {
add(HForeignCode(js.js.statementTemplateYielding(js.Comment(text)),
- _abstractValueDomain.dynamicType, <HInstruction>[],
+ _abstractValueDomain.dynamicType, [],
isStatement: true));
}
@@ -1287,7 +1284,7 @@
var sourceInformation = _sourceInformationBuilder.buildAsyncBody();
// Forward all the parameters to the body.
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
if (graph.thisInstruction != null) {
inputs.add(graph.thisInstruction);
}
@@ -1471,7 +1468,7 @@
var sourceInformation = _sourceInformationBuilder.buildAssert(context);
_pushStaticInvocation(
_commonElements.assertHelper,
- <HInstruction>[pop()],
+ [pop()],
_typeInferenceMap.getReturnTypeOf(_commonElements.assertHelper),
const <DartType>[],
sourceInformation: sourceInformation);
@@ -1723,7 +1720,7 @@
// TODO(efortuna): Source information!
push(HInvokeStatic(
_commonElements.loadDeferredLibrary,
- <HInstruction>[graph.addConstantString(loadId, closedWorld)],
+ [graph.addConstantString(loadId, closedWorld)],
_abstractValueDomain.nonNullType,
const <DartType>[],
targetCanThrow: false));
@@ -2056,7 +2053,7 @@
_getStaticType(node.iterable),
receiverType,
Selectors.iterator,
- <HInstruction>[receiver],
+ [receiver],
const <DartType>[],
_sourceInformationBuilder.buildForInIterator(node));
iterator = pop();
@@ -2070,7 +2067,7 @@
iteratorType,
receiverType,
Selectors.moveNext,
- <HInstruction>[iterator],
+ [iterator],
const <DartType>[],
_sourceInformationBuilder.buildForInMoveNext(node));
return popBoolified();
@@ -2211,7 +2208,7 @@
// Set the runtime type information on the object.
FunctionEntity typeInfoSetterFn = _commonElements.setArrayType;
// TODO(efortuna): Insert source information in this static invocation.
- _pushStaticInvocation(typeInfoSetterFn, <HInstruction>[newObject, typeInfo],
+ _pushStaticInvocation(typeInfoSetterFn, [newObject, typeInfo],
_abstractValueDomain.dynamicType, const <DartType>[],
sourceInformation: sourceInformation);
@@ -2498,7 +2495,7 @@
node.condition.accept(this);
_pushStaticInvocation(
_commonElements.assertHelper,
- <HInstruction>[pop()],
+ [pop()],
_typeInferenceMap.getReturnTypeOf(_commonElements.assertHelper),
const <DartType>[],
sourceInformation: sourceInformation);
@@ -2511,7 +2508,7 @@
node.condition.accept(this);
_pushStaticInvocation(
_commonElements.assertTest,
- <HInstruction>[pop()],
+ [pop()],
_typeInferenceMap.getReturnTypeOf(_commonElements.assertTest),
const <DartType>[],
sourceInformation: sourceInformation);
@@ -2521,7 +2518,7 @@
node.message.accept(this);
_pushStaticInvocation(
_commonElements.assertThrow,
- <HInstruction>[pop()],
+ [pop()],
_typeInferenceMap.getReturnTypeOf(_commonElements.assertThrow),
const <DartType>[],
sourceInformation: sourceInformation);
@@ -2600,7 +2597,7 @@
SubGraph bodyGraph = SubGraph(newBlock, lastOpenedBlock);
HBasicBlock joinBlock = graph.addNewBlock();
- List<LocalsHandler> breakHandlers = <LocalsHandler>[];
+ List<LocalsHandler> breakHandlers = [];
handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
breakInstruction.block.addSuccessor(joinBlock);
breakHandlers.add(locals);
@@ -2626,8 +2623,7 @@
/// expressions to constants.
Map<ir.Expression, ConstantValue> _buildSwitchCaseConstants(
ir.SwitchStatement switchStatement) {
- Map<ir.Expression, ConstantValue> constants =
- Map<ir.Expression, ConstantValue>();
+ Map<ir.Expression, ConstantValue> constants = {};
for (ir.SwitchCase switchCase in switchStatement.cases) {
for (ir.Expression caseExpression in switchCase.expressions) {
ConstantValue constant =
@@ -2657,7 +2653,7 @@
// The switch case indices must match those computed in
// [KernelSwitchCaseJumpHandler].
bool hasContinue = false;
- Map<ir.SwitchCase, int> caseIndex = Map<ir.SwitchCase, int>();
+ Map<ir.SwitchCase, int> caseIndex = {};
int switchIndex = 1;
bool hasDefault = false;
for (ir.SwitchCase switchCase in node.cases) {
@@ -2699,7 +2695,7 @@
ir.SwitchStatement parentSwitch, ir.SwitchCase switchCase) {
Map<ir.Expression, ConstantValue> constantsLookup =
_buildSwitchCaseConstants(parentSwitch);
- List<ConstantValue> constantList = <ConstantValue>[];
+ List<ConstantValue> constantList = [];
if (switchCase != null) {
for (var expression in switchCase.expressions) {
constantList.add(constantsLookup[expression]);
@@ -2818,9 +2814,7 @@
List<ConstantValue> getConstants(
ir.SwitchStatement parentSwitch, ir.SwitchCase switchCase) {
- return <ConstantValue>[
- constant_system.createIntFromInt(caseIndex[switchCase])
- ];
+ return [constant_system.createIntFromInt(caseIndex[switchCase])];
}
void buildSwitchCase(ir.SwitchCase switchCase) {
@@ -2902,12 +2896,11 @@
return;
}
- HSwitch switchInstruction =
- HSwitch(_abstractValueDomain, <HInstruction>[expression]);
+ HSwitch switchInstruction = HSwitch(_abstractValueDomain, [expression]);
HBasicBlock expressionEnd = close(switchInstruction);
LocalsHandler savedLocals = localsHandler;
- List<HStatementInformation> statements = <HStatementInformation>[];
+ List<HStatementInformation> statements = [];
bool hasDefault = false;
for (ir.SwitchCase switchCase in switchCases) {
HBasicBlock block = graph.addNewBlock();
@@ -2951,7 +2944,7 @@
// If we never jump to the join block, [caseHandlers] will stay empty, and
// the join block is never added to the graph.
HBasicBlock joinBlock = HBasicBlock();
- List<LocalsHandler> caseHandlers = <LocalsHandler>[];
+ List<LocalsHandler> caseHandlers = [];
jumpHandler.forEachBreak((HBreak instruction, LocalsHandler locals) {
instruction.block.addSuccessor(joinBlock);
caseHandlers.add(locals);
@@ -3107,7 +3100,7 @@
listInstruction = graph.addConstant(
_elementMap.getConstantValue(_memberContextNode, node), closedWorld);
} else {
- List<HInstruction> elements = <HInstruction>[];
+ List<HInstruction> elements = [];
for (ir.Expression element in node.expressions) {
element.accept(this);
elements.add(pop());
@@ -3139,7 +3132,7 @@
}
// The set literal constructors take the elements as a List.
- List<HInstruction> elements = <HInstruction>[];
+ List<HInstruction> elements = [];
for (ir.Expression element in node.expressions) {
element.accept(this);
elements.add(pop());
@@ -3147,7 +3140,7 @@
// The constructor is a procedure because it's a factory.
FunctionEntity constructor;
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
if (elements.isEmpty) {
constructor = _commonElements.setLiteralConstructorEmpty;
} else {
@@ -3165,7 +3158,7 @@
ClassEntity cls = constructor.enclosingClass;
if (_rtiNeed.classNeedsTypeArguments(cls)) {
- List<HInstruction> typeInputs = <HInstruction>[];
+ List<HInstruction> typeInputs = [];
type.typeArguments.forEach((DartType argument) {
typeInputs
.add(_typeBuilder.analyzeTypeArgument(argument, sourceElement));
@@ -3218,7 +3211,7 @@
}
// The map literal constructors take the key-value pairs as a List
- List<HInstruction> constructorArgs = <HInstruction>[];
+ List<HInstruction> constructorArgs = [];
for (ir.MapLiteralEntry mapEntry in node.entries) {
mapEntry.key.accept(this);
constructorArgs.add(pop());
@@ -3228,7 +3221,7 @@
// The constructor is a procedure because it's a factory.
FunctionEntity constructor;
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
if (constructorArgs.isEmpty) {
constructor = _commonElements.mapLiteralConstructorEmpty;
} else {
@@ -3247,7 +3240,7 @@
ClassEntity cls = constructor.enclosingClass;
if (_rtiNeed.classNeedsTypeArguments(cls)) {
- List<HInstruction> typeInputs = <HInstruction>[];
+ List<HInstruction> typeInputs = [];
type.typeArguments.forEach((DartType argument) {
typeInputs
.add(_typeBuilder.analyzeTypeArgument(argument, sourceElement));
@@ -3320,7 +3313,7 @@
sourceInformation: sourceInformation);
_pushStaticInvocation(
_commonElements.createRuntimeType,
- <HInstruction>[value],
+ [value],
_typeInferenceMap.getReturnTypeOf(_commonElements.createRuntimeType),
const <DartType>[],
sourceInformation: sourceInformation);
@@ -3335,7 +3328,7 @@
staticTarget.kind == ir.ProcedureKind.Getter) {
FunctionEntity getter = _elementMap.getMember(staticTarget);
// Invoke the getter
- _pushStaticInvocation(getter, const <HInstruction>[],
+ _pushStaticInvocation(getter, const [],
_typeInferenceMap.getReturnTypeOf(getter), const <DartType>[],
sourceInformation: sourceInformation);
} else if (staticTarget is ir.Field) {
@@ -3400,7 +3393,7 @@
if (staticTarget is ir.Procedure) {
FunctionEntity setter = _elementMap.getMember(staticTarget);
// Invoke the setter
- _pushStaticInvocation(setter, <HInstruction>[value],
+ _pushStaticInvocation(setter, [value],
_typeInferenceMap.getReturnTypeOf(setter), const <DartType>[],
sourceInformation: _sourceInformationBuilder.buildSet(node));
pop();
@@ -3426,7 +3419,7 @@
_getStaticType(receiver),
_typeInferenceMap.receiverTypeOfGet(node),
Selector.getter(_elementMap.getName(name)),
- <HInstruction>[receiverInstruction],
+ [receiverInstruction],
const <DartType>[],
_sourceInformationBuilder.buildGet(node));
}
@@ -3477,7 +3470,7 @@
_getStaticType(receiver),
_typeInferenceMap.receiverTypeOfSet(node, _abstractValueDomain),
Selector.setter(_elementMap.getName(name)),
- <HInstruction>[receiverInstruction, valueInstruction],
+ [receiverInstruction, valueInstruction],
const <DartType>[],
_sourceInformationBuilder.buildAssignment(node));
@@ -3507,14 +3500,14 @@
// TODO(johnniwinther): Remove this when the CFE checks for missing
// concrete super targets.
_generateSuperNoSuchMethod(node, _elementMap.getSelector(node).name + "=",
- <HInstruction>[value], const <DartType>[], sourceInformation);
+ [value], const <DartType>[], sourceInformation);
} else {
MemberEntity member = _elementMap.getMember(target);
_buildInvokeSuper(
_elementMap.getSelector(node),
_elementMap.getClass(_containingClass(node)),
member,
- <HInstruction>[value],
+ [value],
const <DartType>[],
sourceInformation);
}
@@ -3595,7 +3588,7 @@
/// Extracts the list of instructions for the positional subset of arguments.
List<HInstruction> _visitPositionalArguments(ir.Arguments arguments) {
- List<HInstruction> result = <HInstruction>[];
+ List<HInstruction> result = [];
for (ir.Expression argument in arguments.positional) {
argument.accept(this);
result.add(pop());
@@ -3613,7 +3606,7 @@
List<HInstruction> values = _visitPositionalArguments(arguments);
if (arguments.named.isNotEmpty) {
- Map<String, HInstruction> namedValues = <String, HInstruction>{};
+ Map<String, HInstruction> namedValues = {};
for (ir.NamedExpression argument in arguments.named) {
argument.value.accept(this);
namedValues[argument.name] = pop();
@@ -3645,7 +3638,7 @@
if (function is ConstructorEntity && function.isFactoryConstructor) {
// TODO(sra): Have a "CompiledArguments" structure to just update with
// what values we have rather than creating a map and de-populating it.
- var namedValues = <String, HInstruction>{};
+ Map<String, HInstruction> namedValues = {};
for (ir.NamedExpression argument in arguments.named) {
argument.value.accept(this);
namedValues[argument.name] = pop();
@@ -3979,7 +3972,7 @@
List<HInstruction> arguments,
SourceInformation sourceInformation) {
// `List<T>()` is essentially the same as `<T>[]`.
- push(_buildLiteralList(<HInstruction>[]));
+ push(_buildLiteralList([]));
HInstruction allocation = pop();
var inferredType = globalInferenceResults.typeOfNewList(invocation);
if (inferredType != null) {
@@ -4036,8 +4029,7 @@
var resultType = globalInferenceResults.typeOfNewList(invocation) ??
_abstractValueDomain.fixedListType;
- HForeignCode foreign = HForeignCode(
- code, resultType, <HInstruction>[lengthInput],
+ HForeignCode foreign = HForeignCode(code, resultType, [lengthInput],
nativeBehavior: behavior,
throwBehavior:
canThrow ? NativeThrowBehavior.MAY : NativeThrowBehavior.NEVER)
@@ -4106,8 +4098,8 @@
HInstruction object = arguments[0];
HInstruction closure = arguments[1];
- List<HInstruction> inputs = <HInstruction>[closure];
- List<DartType> typeArguments = <DartType>[];
+ List<HInstruction> inputs = [closure];
+ List<DartType> typeArguments = [];
closedWorld.registerExtractTypeArguments(cls);
HInstruction instanceType =
@@ -4289,13 +4281,13 @@
constant_system.createSymbol(closedWorld.commonElements, name),
closedWorld);
- List<HInstruction> arguments = <HInstruction>[];
+ List<HInstruction> arguments = [];
for (ir.Expression argument in positionalArgumentsLiteral.expressions) {
argument.accept(this);
arguments.add(pop());
}
if (namedArguments.isNotEmpty) {
- Map<String, HInstruction> namedValues = <String, HInstruction>{};
+ Map<String, HInstruction> namedValues = {};
namedArguments.forEach((String name, ir.Expression value) {
value.accept(this);
namedValues[name] = pop();
@@ -4580,7 +4572,7 @@
return;
}
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
for (ir.Expression argument in arguments.skip(2)) {
argument.accept(this);
inputs.add(pop());
@@ -4753,7 +4745,7 @@
failedAt(_elementMap.getSpannable(targetElement, invocation),
"No NativeBehavior for $invocation"));
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
for (ir.Expression argument in invocation.arguments.positional.skip(2)) {
argument.accept(this);
inputs.add(pop());
@@ -4972,7 +4964,7 @@
}
HInstruction receiver = arguments.first;
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
selector ??= _elementMap.getSelector(node);
@@ -5024,8 +5016,8 @@
ConstructorEntity constructor = element;
int i = 0;
int positions = 0;
- var filteredArguments = <HInstruction>[];
- var parameterNameMap = Map<String, js.Expression>();
+ List<HInstruction> filteredArguments = [];
+ Map<String, js.Expression> parameterNameMap = {};
// Note: we don't use `constructor.parameterStructure` here because
// we don't elide parameters to js-interop external static targets
@@ -5105,7 +5097,7 @@
_closureDataLookup.getClosureInfo(node.parent);
ClassEntity closureClassEntity = closureInfo.closureClassEntity;
- List<HInstruction> capturedVariables = <HInstruction>[];
+ List<HInstruction> capturedVariables = [];
_elementEnvironment.forEachInstanceField(closureClassEntity,
(_, FieldEntity field) {
if (_fieldAnalysis.getFieldData(field).isElided) return;
@@ -5135,7 +5127,7 @@
@override
void visitInstantiation(ir.Instantiation node) {
- var arguments = <HInstruction>[];
+ List<HInstruction> arguments = [];
node.expression.accept(this);
arguments.add(pop());
StaticType expressionType = _getStaticType(node.expression);
@@ -5183,16 +5175,17 @@
receiver.accept(this);
HInstruction receiverInstruction = pop();
Selector selector = _elementMap.getSelector(node);
- List<DartType> typeArguments = <DartType>[];
+ List<DartType> typeArguments = [];
selector = _fillDynamicTypeArguments(selector, arguments, typeArguments);
_pushDynamicInvocation(
node,
_getStaticType(receiver),
_typeInferenceMap.receiverTypeOfInvocation(node, _abstractValueDomain),
selector,
- <HInstruction>[receiverInstruction]..addAll(
- _visitArgumentsForDynamicTarget(
- selector, arguments, typeArguments)),
+ [
+ receiverInstruction,
+ ..._visitArgumentsForDynamicTarget(selector, arguments, typeArguments)
+ ],
typeArguments,
_sourceInformationBuilder.buildCall(receiver, node));
}
@@ -5249,7 +5242,7 @@
_getStaticType(left),
_typeInferenceMap.receiverTypeOfInvocation(node, _abstractValueDomain),
Selectors.equals,
- <HInstruction>[leftInstruction, rightInstruction],
+ [leftInstruction, rightInstruction],
const <DartType>[],
_sourceInformationBuilder.buildCall(left, node));
}
@@ -5307,7 +5300,7 @@
var argumentsInstruction = _buildLiteralList(arguments);
add(argumentsInstruction);
- var argumentNames = <HInstruction>[];
+ List<HInstruction> argumentNames = [];
for (String argumentName in selector.namedArguments) {
ConstantValue argumentNameConstant =
constant_system.createString(argumentName);
@@ -5334,7 +5327,7 @@
sourceInformation: sourceInformation);
_buildInvokeSuper(Selectors.noSuchMethod_, containingClass, noSuchMethod,
- <HInstruction>[pop()], typeArguments, sourceInformation);
+ [pop()], typeArguments, sourceInformation);
}
HInstruction _buildInvokeSuper(
@@ -5347,7 +5340,7 @@
HInstruction receiver =
localsHandler.readThis(sourceInformation: sourceInformation);
- List<HInstruction> inputs = <HInstruction>[];
+ List<HInstruction> inputs = [];
bool isIntercepted =
closedWorld.interceptorData.isInterceptedSelector(selector);
if (isIntercepted) {
@@ -5454,7 +5447,7 @@
HInstruction methodNameInstruction =
graph.addConstantString(methodName, closedWorld);
FunctionEntity element = _commonElements.checkTypeBound;
- var inputs = <HInstruction>[
+ List<HInstruction> inputs = [
typeInstruction,
boundInstruction,
variableNameInstruction,
@@ -5485,7 +5478,7 @@
target.enclosingClass, node.arguments.types);
instanceType = localsHandler.substInContext(instanceType);
- List<HInstruction> arguments = <HInstruction>[];
+ List<HInstruction> arguments = [];
if (constructor.isGenerativeConstructor &&
_nativeData.isNativeOrExtendsNative(constructor.enclosingClass) &&
!_nativeData.isJsInteropMember(constructor)) {
@@ -6311,25 +6304,21 @@
String name = "${n(element.library)}:${n(element.enclosingClass)}."
"${n(element)}";
HConstant nameConstant = graph.addConstantString(name, closedWorld);
- add(HInvokeStatic(
- _commonElements.traceHelper,
- <HInstruction>[idConstant, nameConstant],
- _abstractValueDomain.dynamicType,
- const <DartType>[]));
+ add(HInvokeStatic(_commonElements.traceHelper, [idConstant, nameConstant],
+ _abstractValueDomain.dynamicType, const <DartType>[]));
}
}
/// Data collected to create a constructor.
class ConstructorData {
/// Inlined (super) constructors.
- final List<ir.Constructor> constructorChain = <ir.Constructor>[];
+ final List<ir.Constructor> constructorChain = [];
/// Initial values for all instance fields.
- final Map<FieldEntity, HInstruction> fieldValues =
- <FieldEntity, HInstruction>{};
+ final Map<FieldEntity, HInstruction> fieldValues = {};
/// Classes for which type variables have been prepared.
- final Set<ClassEntity> includedClasses = Set<ClassEntity>();
+ final Set<ClassEntity> includedClasses = {};
}
class KernelInliningState {
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index e4737ff..e7ec92f 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -223,17 +223,17 @@
final CodegenRegistry _registry;
final _CodegenMetrics _metrics;
- final Set<HInstruction> generateAtUseSite;
- final Set<HInstruction> controlFlowOperators;
- final Set<JumpTarget> breakAction;
- final Set<LabelDefinition> continueAction;
- final Set<JumpTarget> implicitContinueAction;
- final List<js.Parameter> parameters;
+ final Set<HInstruction> generateAtUseSite = {};
+ final Set<HInstruction> controlFlowOperators = {};
+ final Set<JumpTarget> breakAction = {};
+ final Set<LabelDefinition> continueAction = {};
+ final Set<JumpTarget> implicitContinueAction = {};
+ final List<js.Parameter> parameters = [];
- js.Block currentContainer;
+ js.Block currentContainer = js.Block.empty();
js.Block get body => currentContainer;
- List<js.Expression> expressionStack;
- List<js.Block> oldContainerStack;
+ List<js.Expression> expressionStack = [];
+ List<js.Block> oldContainerStack = [];
/// Contains the names of the instructions, as well as the parallel
/// copies to perform on block transitioning.
@@ -248,10 +248,10 @@
/// Instead we declare them at the start of the function. When minifying
/// we do this most of the time, because it reduces the size unless there
/// is only one variable.
- final Set<String> collectedVariableDeclarations;
+ final Set<String> collectedVariableDeclarations = {};
/// Set of variables and parameters that have already been declared.
- final Set<String> declaredLocals;
+ final Set<String> declaredLocals = {};
HGraph currentGraph;
@@ -275,19 +275,7 @@
this._namer,
this._tracer,
this._closedWorld,
- this._registry,
- {SourceInformation sourceInformation})
- : declaredLocals = Set<String>(),
- collectedVariableDeclarations = Set<String>(),
- currentContainer = js.Block.empty(),
- parameters = <js.Parameter>[],
- expressionStack = <js.Expression>[],
- oldContainerStack = <js.Block>[],
- generateAtUseSite = Set<HInstruction>(),
- controlFlowOperators = Set<HInstruction>(),
- breakAction = Set<JumpTarget>(),
- continueAction = Set<LabelDefinition>(),
- implicitContinueAction = Set<JumpTarget>();
+ this._registry);
JCommonElements get _commonElements => _closedWorld.commonElements;
@@ -617,7 +605,7 @@
bool oldIsGeneratingExpression = isGeneratingExpression;
isGeneratingExpression = true;
List<js.Expression> oldExpressionStack = expressionStack;
- List<js.Expression> sequenceElements = <js.Expression>[];
+ List<js.Expression> sequenceElements = [];
expressionStack = sequenceElements;
HSubExpressionBlockInformation expressionSubGraph = expression;
visitSubGraph(expressionSubGraph.subExpression);
@@ -711,9 +699,7 @@
js.VariableInitialization(decl, value);
pushExpressionAsStatement(
- js.VariableDeclarationList(
- <js.VariableInitialization>[initialization]),
- sourceInformation);
+ js.VariableDeclarationList([initialization]), sourceInformation);
} else {
// Otherwise we are just going to use it. If we have not already declared
// it then we make sure we will declare it later.
@@ -858,7 +844,7 @@
}
js.Expression key = pop();
bool handledDefault = false;
- List<js.SwitchClause> cases = <js.SwitchClause>[];
+ List<js.SwitchClause> cases = [];
HSwitch switchInstruction = info.expression.end.last;
List<HInstruction> inputs = switchInstruction.inputs;
List<HBasicBlock> successors = switchInstruction.block.successors;
@@ -1035,7 +1021,7 @@
js.Assignment assignment = expression;
if (assignment.leftHandSide is js.VariableUse &&
!assignment.isCompound) {
- if (assignments == null) assignments = <js.Assignment>[];
+ assignments ??= [];
assignments.add(expression);
return true;
}
@@ -1048,8 +1034,7 @@
}
if (allSimpleAssignments(jsInitialization)) {
- List<js.VariableInitialization> inits =
- <js.VariableInitialization>[];
+ List<js.VariableInitialization> inits = [];
for (js.Assignment assignment in assignments) {
String id = (assignment.leftHandSide as js.VariableUse).name;
js.Node declaration = js.VariableDeclaration(id);
@@ -1362,8 +1347,7 @@
String tempName,
void doAssignment(
String target, String source, SourceInformation sourceInformation)) {
- Map<String, SourceInformation> sourceInformationMap =
- <String, SourceInformation>{};
+ Map<String, SourceInformation> sourceInformationMap = {};
// Map the instructions to strings.
Iterable<Copy<String>> copies =
@@ -1377,20 +1361,20 @@
// Map to keep track of the current location (ie the variable that
// holds the initial value) of a variable.
- Map<String, String> currentLocation = Map<String, String>();
+ Map<String, String> currentLocation = {};
// Map to keep track of the initial value of a variable.
- Map<String, String> initialValue = Map<String, String>();
+ Map<String, String> initialValue = {};
// List of variables to assign a value.
- List<String> worklist = <String>[];
+ List<String> worklist = [];
// List of variables that we can assign a value to (ie are not
// being used anymore).
- List<String> ready = <String>[];
+ List<String> ready = [];
// Prune [copies] by removing self-copies.
- List<Copy<String>> prunedCopies = <Copy<String>>[];
+ List<Copy<String>> prunedCopies = [];
for (Copy<String> copy in copies) {
if (copy.source != copy.destination) {
prunedCopies.add(copy);
@@ -1879,7 +1863,7 @@
js.Name name = _namer.nameForGetInterceptor(node.interceptedClasses);
js.Expression isolate = _namer.readGlobalObjectForInterceptors();
use(node.receiver);
- List<js.Expression> arguments = <js.Expression>[pop()];
+ List<js.Expression> arguments = [pop()];
push(js
.propertyCall(isolate, name, arguments)
.withSourceInformation(node.sourceInformation));
@@ -2423,7 +2407,7 @@
visitForeignCode(HForeignCode node) {
List<HInstruction> inputs = node.inputs;
if (node.isJsStatement()) {
- List<js.Expression> interpolatedExpressions = <js.Expression>[];
+ List<js.Expression> interpolatedExpressions = [];
for (int i = 0; i < inputs.length; i++) {
use(inputs[i]);
interpolatedExpressions.add(pop());
@@ -2432,7 +2416,7 @@
.instantiate(interpolatedExpressions)
.withSourceInformation(node.sourceInformation));
} else {
- List<js.Expression> interpolatedExpressions = <js.Expression>[];
+ List<js.Expression> interpolatedExpressions = [];
for (int i = 0; i < inputs.length; i++) {
use(inputs[i]);
interpolatedExpressions.add(pop());
@@ -2469,7 +2453,7 @@
@override
visitCreateBox(HCreateBox node) {
- push(js.ObjectInitializer(<js.Property>[]));
+ push(js.ObjectInitializer([]));
}
js.Expression newLiteralBool(
@@ -2513,7 +2497,7 @@
}
static String mapRelationalOperator(String op, bool inverse) {
- Map<String, String> inverseOperator = const <String, String>{
+ Map<String, String> inverseOperator = const {
"==": "!=",
"!=": "==",
"===": "!==",
@@ -2840,8 +2824,8 @@
FieldEntity element = node.element;
_registry.registerStaticUse(StaticUse.staticInit(element));
js.Expression lazyGetter = _emitter.isolateLazyInitializerAccess(element);
- js.Call call = js.Call(lazyGetter, <js.Expression>[],
- sourceInformation: node.sourceInformation);
+ js.Call call =
+ js.Call(lazyGetter, [], sourceInformation: node.sourceInformation);
push(call);
}
@@ -2889,7 +2873,7 @@
StaticUse.staticInvoke(convertToString, CallStructure.ONE_ARG));
js.Expression jsHelper = _emitter.staticFunctionAccess(convertToString);
use(input);
- push(js.Call(jsHelper, <js.Expression>[pop()],
+ push(js.Call(jsHelper, [pop()],
sourceInformation: node.sourceInformation));
}
}
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 3305b11..0d27a96 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -809,8 +809,8 @@
// The expectedInputs list holds non-trivial instructions that may
// be generated at their use site, if they occur in the correct order.
- if (expectedInputs == null) expectedInputs = <HInstruction>[];
- if (pureInputs == null) pureInputs = Set<HInstruction>();
+ expectedInputs ??= [];
+ pureInputs ??= {};
// Pop instructions from expectedInputs until instruction is found.
// Return true if it is found, or false if not.
diff --git a/pkg/compiler/lib/src/ssa/jump_handler.dart b/pkg/compiler/lib/src/ssa/jump_handler.dart
index 24faf54..ff2911d 100644
--- a/pkg/compiler/lib/src/ssa/jump_handler.dart
+++ b/pkg/compiler/lib/src/ssa/jump_handler.dart
@@ -72,7 +72,7 @@
bool hasAnyBreak() => false;
@override
- List<LabelDefinition> get labels => const <LabelDefinition>[];
+ List<LabelDefinition> get labels => const [];
@override
JumpTarget get target => null;
}
@@ -85,11 +85,9 @@
final KernelSsaGraphBuilder builder;
@override
final JumpTarget target;
- final List<_JumpHandlerEntry> jumps;
+ final List<_JumpHandlerEntry> jumps = [];
- TargetJumpHandler(KernelSsaGraphBuilder builder, this.target)
- : this.builder = builder,
- jumps = <_JumpHandlerEntry>[] {
+ TargetJumpHandler(this.builder, this.target) {
assert(builder.jumpTargets[target] == null);
builder.jumpTargets[target] = this;
}
@@ -184,7 +182,7 @@
abstract class SwitchCaseJumpHandler extends TargetJumpHandler {
/// Map from switch case targets to indices used to encode the flow of the
/// switch case loop.
- final Map<JumpTarget, int> targetIndexMap = Map<JumpTarget, int>();
+ final Map<JumpTarget, int> targetIndexMap = {};
SwitchCaseJumpHandler(KernelSsaGraphBuilder builder, JumpTarget target)
: super(builder, target);
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index 37da289..2452f1a 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -32,16 +32,15 @@
/// iteration order a function only of insertions and not a function of
/// e.g. Element hash codes. I'd prefer to use a SortedMap but some elements
/// don't have source locations for [Elements.compareByPosition].
- Map<Local, HInstruction> directLocals = Map<Local, HInstruction>();
- Map<Local, FieldEntity> redirectionMapping = Map<Local, FieldEntity>();
+ Map<Local, HInstruction> directLocals = {};
+ Map<Local, FieldEntity> redirectionMapping = {};
final KernelSsaGraphBuilder builder;
MemberEntity _scopeInfoMember;
ScopeInfo _scopeInfo;
KernelToLocalsMap _localsMap;
- Map<TypeVariableEntity, TypeVariableLocal> typeVariableLocals =
- Map<TypeVariableEntity, TypeVariableLocal>();
+ Map<TypeVariableEntity, TypeVariableLocal> typeVariableLocals = {};
final Entity executableContext;
final MemberEntity memberContext;
@@ -594,7 +593,7 @@
// block. Since variable declarations are scoped the declared
// variable cannot be alive outside the block. Note: this is only
// true for nodes where we do joins.
- Map<Local, HInstruction> joinedLocals = Map<Local, HInstruction>();
+ Map<Local, HInstruction> joinedLocals = {};
otherLocals.directLocals.forEach((Local local, HInstruction instruction) {
// We know 'this' cannot be modified.
if (local == _scopeInfo.thisLocal) {
@@ -627,7 +626,7 @@
List<LocalsHandler> localsHandlers, HBasicBlock joinBlock) {
assert(localsHandlers.length > 0);
if (localsHandlers.length == 1) return localsHandlers.single;
- Map<Local, HInstruction> joinedLocals = Map<Local, HInstruction>();
+ Map<Local, HInstruction> joinedLocals = {};
HInstruction thisValue = null;
directLocals.forEach((Local local, HInstruction instruction) {
if (local != _scopeInfo.thisLocal) {
@@ -655,7 +654,7 @@
}
// Remove locals that are not in all handlers.
- directLocals = Map<Local, HInstruction>();
+ directLocals = {};
joinedLocals.forEach((Local local, HInstruction instruction) {
if (local != _scopeInfo.thisLocal &&
instruction.inputs.length != localsHandlers.length) {
@@ -688,8 +687,7 @@
return result;
}
- Map<FieldEntity, AbstractValue> cachedTypesOfCapturedVariables =
- Map<FieldEntity, AbstractValue>();
+ Map<FieldEntity, AbstractValue> cachedTypesOfCapturedVariables = {};
AbstractValue getTypeOfCapturedVariable(FieldEntity element) {
return cachedTypesOfCapturedVariables.putIfAbsent(element, () {
@@ -701,7 +699,7 @@
/// Variables stored in the current activation. These variables are
/// being updated in try/catch blocks, and should be
/// accessed indirectly through [HLocalGet] and [HLocalSet].
- Map<Local, HLocalValue> activationVariables = <Local, HLocalValue>{};
+ Map<Local, HLocalValue> activationVariables = {};
SyntheticLocal createLocal(String name) {
return SyntheticLocal(name, executableContext, memberContext);
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index a136378..6f187a3 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -235,18 +235,18 @@
bool calledInLoop = false;
bool isLazyInitializer = false;
- final List<HBasicBlock> blocks = <HBasicBlock>[];
+ final List<HBasicBlock> blocks = [];
/// Nodes containing list allocations for which there is a known fixed length.
// TODO(sigmund,sra): consider not storing this explicitly here (e.g. maybe
// store it on HInstruction, or maybe this can be computed on demand).
- final Set<HInstruction> allocatedFixedLists = Set<HInstruction>();
+ final Set<HInstruction> allocatedFixedLists = {};
SourceInformation sourceInformation;
// We canonicalize all constants used within a graph so we do not
// have to worry about them for global value numbering.
- Map<ConstantValue, HConstant> constants = Map<ConstantValue, HConstant>();
+ Map<ConstantValue, HConstant> constants = {};
HGraph() {
entry = addNewBlock();
@@ -746,27 +746,23 @@
static const int STATUS_CLOSED = 2;
int status = STATUS_NEW;
- HInstructionList phis;
+ HInstructionList phis = HInstructionList();
HLoopInformation loopInformation = null;
HBlockFlow blockFlow = null;
HBasicBlock parentLoopHeader = null;
bool isLive = true;
- final List<HBasicBlock> predecessors;
- List<HBasicBlock> successors;
+ final List<HBasicBlock> predecessors = [];
+ List<HBasicBlock> successors = const [];
HBasicBlock dominator = null;
- final List<HBasicBlock> dominatedBlocks;
+ final List<HBasicBlock> dominatedBlocks = [];
int dominatorDfsIn;
int dominatorDfsOut;
HBasicBlock() : this.withId(null);
- HBasicBlock.withId(this.id)
- : phis = HInstructionList(),
- predecessors = <HBasicBlock>[],
- successors = const <HBasicBlock>[],
- dominatedBlocks = <HBasicBlock>[];
+ HBasicBlock.withId(this.id);
@override
int get hashCode => id;
@@ -904,7 +900,7 @@
/// information on [to], and that dominates the user.
void rewriteWithBetterUser(HInstruction from, HInstruction to) {
// BUG(11841): Turn this method into a phase to be run after GVN phases.
- Link<HCheck> better = const Link<HCheck>();
+ Link<HCheck> better = const Link();
for (HInstruction user in to.usedBy) {
if (user == from || user is! HCheck) continue;
HCheck check = user;
@@ -1406,8 +1402,8 @@
// Two list of matching length holding (instruction, input-index) pairs for
// the dominated uses.
- final List<HInstruction> _instructions = <HInstruction>[];
- final List<int> _indexes = <int>[];
+ final List<HInstruction> _instructions = [];
+ final List<int> _indexes = [];
DominatedUses._(this._source);
@@ -1464,8 +1460,8 @@
bool excludeDominator, bool excludePhiOutEdges) {
// Keep track of all instructions that we have to deal with later and count
// the number of them that are in the current block.
- Set<HInstruction> users = Setlet<HInstruction>();
- Set<HInstruction> seen = Setlet<HInstruction>();
+ Set<HInstruction> users = Setlet();
+ Set<HInstruction> seen = Setlet();
int usersInCurrentBlock = 0;
HBasicBlock dominatorBlock = dominator.block;
@@ -1565,7 +1561,7 @@
/// the graph, instructions that depend on the check being done reference the
/// [HCheck] instruction instead of the input instruction.
abstract class HCheck extends HInstruction {
- HCheck(inputs, type) : super(inputs, type) {
+ HCheck(List<HInstruction> inputs, AbstractValue type) : super(inputs, type) {
setUseGvn();
}
@@ -1592,11 +1588,12 @@
/// Default is that all checks must be performed dynamically.
int staticChecks = FULL_CHECK;
- HBoundsCheck(length, index, array, type)
- : super(<HInstruction>[length, index, array], type);
+ HBoundsCheck(HInstruction index, HInstruction length, HInstruction array,
+ AbstractValue type)
+ : super([index, length, array], type);
- HInstruction get length => inputs[1];
HInstruction get index => inputs[0];
+ HInstruction get length => inputs[1];
HInstruction get array => inputs[2];
// There can be an additional fourth input which is the index to report to
// [ioore]. This is used by the expansion of [JSArray.removeLast].
@@ -1675,7 +1672,7 @@
// Allocates a box to hold mutated captured variables.
class HCreateBox extends HInstruction {
- HCreateBox(AbstractValue type) : super(<HInstruction>[], type);
+ HCreateBox(AbstractValue type) : super([], type);
@override
bool isAllocation(AbstractValueDomain domain) => true;
@@ -1881,7 +1878,7 @@
bool get isTearOff => element != null && element.isFunction;
@override
- List<DartType> get typeArguments => const <DartType>[];
+ List<DartType> get typeArguments => const [];
// There might be an interceptor input, so `inputs.last` is the dart receiver.
@override
@@ -1918,7 +1915,7 @@
accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this);
@override
- List<DartType> get typeArguments => const <DartType>[];
+ List<DartType> get typeArguments => const [];
@override
String toString() =>
@@ -1943,7 +1940,8 @@
List<InterfaceType> instantiatedTypes;
/// The first input must be the target.
- HInvokeStatic(this.element, inputs, AbstractValue type, this.typeArguments,
+ HInvokeStatic(this.element, List<HInstruction> inputs, AbstractValue type,
+ this.typeArguments,
{this.targetCanThrow = true, bool isIntercepted = false})
: super(inputs, type) {
isInterceptedCall = isIntercepted;
@@ -2012,7 +2010,7 @@
List<HInstruction> inputs,
AbstractValue type,
SourceInformation sourceInformation)
- : super(element, inputs, type, const <DartType>[]) {
+ : super(element, inputs, type, const []) {
this.sourceInformation = sourceInformation;
}
@@ -2033,7 +2031,7 @@
// creating the generator (T for new Completer<T>() inside the body).
HInvokeGeneratorBody(FunctionEntity element, List<HInstruction> inputs,
AbstractValue type, SourceInformation sourceInformation)
- : super(element, inputs, type, const <DartType>[]) {
+ : super(element, inputs, type, const []) {
this.sourceInformation = sourceInformation;
}
@@ -2058,9 +2056,8 @@
HFieldGet(FieldEntity element, HInstruction receiver, AbstractValue type,
SourceInformation sourceInformation,
{bool isAssignable})
- : this.isAssignable =
- (isAssignable != null) ? isAssignable : element.isAssignable,
- super(element, <HInstruction>[receiver], type) {
+ : this.isAssignable = isAssignable ?? element.isAssignable,
+ super(element, [receiver], type) {
this.sourceInformation = sourceInformation;
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
@@ -2109,7 +2106,7 @@
class HFieldSet extends HFieldAccess {
HFieldSet(AbstractValueDomain domain, FieldEntity element,
HInstruction receiver, HInstruction value)
- : super(element, <HInstruction>[receiver, value], domain.emptyType) {
+ : super(element, [receiver, value], domain.emptyType) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
sideEffects.setChangesInstanceProperty();
@@ -2160,9 +2157,8 @@
class HGetLength extends HInstruction {
final bool isAssignable;
- HGetLength(HInstruction receiver, AbstractValue type,
- {bool this.isAssignable})
- : super(<HInstruction>[receiver], type) {
+ HGetLength(HInstruction receiver, AbstractValue type, {this.isAssignable})
+ : super([receiver], type) {
assert(isAssignable != null);
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
@@ -2217,16 +2213,15 @@
HReadModifyWrite.assignOp(FieldEntity element, String jsOp,
HInstruction receiver, HInstruction operand, AbstractValue type)
- : this._(
- element, jsOp, ASSIGN_OP, <HInstruction>[receiver, operand], type);
+ : this._(element, jsOp, ASSIGN_OP, [receiver, operand], type);
HReadModifyWrite.preOp(FieldEntity element, String jsOp,
HInstruction receiver, AbstractValue type)
- : this._(element, jsOp, PRE_OP, <HInstruction>[receiver], type);
+ : this._(element, jsOp, PRE_OP, [receiver], type);
HReadModifyWrite.postOp(FieldEntity element, String jsOp,
HInstruction receiver, AbstractValue type)
- : this._(element, jsOp, POST_OP, <HInstruction>[receiver], type);
+ : this._(element, jsOp, POST_OP, [receiver], type);
HInstruction get receiver => inputs[0];
@@ -2267,7 +2262,7 @@
// access.
HLocalGet(Local variable, HLocalValue local, AbstractValue type,
SourceInformation sourceInformation)
- : super(variable, <HInstruction>[local], type) {
+ : super(variable, [local], type) {
this.sourceInformation = sourceInformation;
}
@@ -2283,7 +2278,7 @@
class HLocalSet extends HLocalAccess {
HLocalSet(AbstractValueDomain domain, Local variable, HLocalValue local,
HInstruction value)
- : super(variable, <HInstruction>[local, value], domain.emptyType);
+ : super(variable, [local, value], domain.emptyType);
@override
accept(HVisitor visitor) => visitor.visitLocalSet(this);
@@ -2489,7 +2484,7 @@
abstract class HInvokeBinary extends HInstruction {
HInvokeBinary(HInstruction left, HInstruction right, AbstractValue type)
- : super(<HInstruction>[left, right], type) {
+ : super([left, right], type) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
setUseGvn();
@@ -2713,7 +2708,7 @@
}
abstract class HInvokeUnary extends HInstruction {
- HInvokeUnary(HInstruction input, type) : super(<HInstruction>[input], type) {
+ HInvokeUnary(HInstruction input, type) : super([input], type) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
setUseGvn();
@@ -2770,7 +2765,7 @@
}
class HExit extends HControlFlow {
- HExit(AbstractValueDomain domain) : super(domain, const <HInstruction>[]);
+ HExit(AbstractValueDomain domain) : super(domain, const []);
@override
toString() => 'exit';
@override
@@ -2778,7 +2773,7 @@
}
class HGoto extends HControlFlow {
- HGoto(AbstractValueDomain domain) : super(domain, const <HInstruction>[]);
+ HGoto(AbstractValueDomain domain) : super(domain, const []);
@override
toString() => 'goto';
@override
@@ -2791,14 +2786,14 @@
HJump(AbstractValueDomain domain, this.target,
SourceInformation sourceInformation)
: label = null,
- super(domain, const <HInstruction>[]) {
+ super(domain, const []) {
this.sourceInformation = sourceInformation;
}
HJump.toLabel(AbstractValueDomain domain, LabelDefinition label,
SourceInformation sourceInformation)
: label = label,
target = label.target,
- super(domain, const <HInstruction>[]) {
+ super(domain, const []) {
this.sourceInformation = sourceInformation;
}
}
@@ -2811,7 +2806,7 @@
HBreak(AbstractValueDomain domain, JumpTarget target,
SourceInformation sourceInformation,
- {bool this.breakSwitchContinueLoop = false})
+ {this.breakSwitchContinueLoop = false})
: super(domain, target, sourceInformation);
HBreak.toLabel(AbstractValueDomain domain, LabelDefinition label,
@@ -2847,7 +2842,7 @@
HLocalValue exception;
HBasicBlock catchBlock;
HBasicBlock finallyBlock;
- HTry(AbstractValueDomain domain) : super(domain, const <HInstruction>[]);
+ HTry(AbstractValueDomain domain) : super(domain, const []);
@override
toString() => 'try';
@override
@@ -2861,7 +2856,7 @@
// leads to one of this instruction a predecessor of catch and
// finally.
class HExitTry extends HControlFlow {
- HExitTry(AbstractValueDomain domain) : super(domain, const <HInstruction>[]);
+ HExitTry(AbstractValueDomain domain) : super(domain, const []);
@override
toString() => 'exit try';
@override
@@ -2872,7 +2867,7 @@
class HIf extends HConditionalBranch {
HBlockFlow blockInformation = null;
HIf(AbstractValueDomain domain, HInstruction condition)
- : super(domain, <HInstruction>[condition]);
+ : super(domain, [condition]);
@override
toString() => 'if';
@override
@@ -2898,7 +2893,7 @@
final int kind;
HLoopBranch(AbstractValueDomain domain, HInstruction condition,
[this.kind = CONDITION_FIRST_LOOP])
- : super(domain, <HInstruction>[condition]);
+ : super(domain, [condition]);
@override
toString() => 'loop-branch';
@override
@@ -2908,7 +2903,7 @@
class HConstant extends HInstruction {
final ConstantValue constant;
HConstant.internal(this.constant, AbstractValue constantType)
- : super(<HInstruction>[], constantType);
+ : super([], constantType);
@override
toString() => 'literal: ${constant.toStructuredText(null)}';
@@ -2954,8 +2949,7 @@
}
class HNot extends HInstruction {
- HNot(HInstruction value, AbstractValue type)
- : super(<HInstruction>[value], type) {
+ HNot(HInstruction value, AbstractValue type) : super([value], type) {
setUseGvn();
}
@@ -2973,8 +2967,7 @@
/// first use must be in an HLocalSet. That is, [HParameterValue]s have a
/// value from the start, whereas [HLocalValue]s need to be initialized first.
class HLocalValue extends HInstruction {
- HLocalValue(Entity variable, AbstractValue type)
- : super(<HInstruction>[], type) {
+ HLocalValue(Entity variable, AbstractValue type) : super([], type) {
sourceElement = variable;
}
@@ -3058,10 +3051,9 @@
: super(inputs, type) {
sourceElement = variable;
}
- HPhi.noInputs(Local variable, AbstractValue type)
- : this(variable, <HInstruction>[], type);
+ HPhi.noInputs(Local variable, AbstractValue type) : this(variable, [], type);
HPhi.singleInput(Local variable, HInstruction input, AbstractValue type)
- : this(variable, <HInstruction>[input], type);
+ : this(variable, [input], type);
HPhi.manyInputs(Local variable, List<HInstruction> inputs, AbstractValue type)
: this(variable, inputs, type);
@@ -3183,7 +3175,7 @@
class HThrowExpression extends HInstruction {
HThrowExpression(AbstractValueDomain domain, HInstruction value,
SourceInformation sourceInformation)
- : super(<HInstruction>[value], domain.emptyType) {
+ : super([value], domain.emptyType) {
this.sourceInformation = sourceInformation;
}
@override
@@ -3195,8 +3187,7 @@
}
class HAwait extends HInstruction {
- HAwait(HInstruction value, AbstractValue type)
- : super(<HInstruction>[value], type);
+ HAwait(HInstruction value, AbstractValue type) : super([value], type);
@override
toString() => 'await';
@override
@@ -3211,7 +3202,7 @@
class HYield extends HInstruction {
HYield(AbstractValueDomain domain, HInstruction value, this.hasStar,
SourceInformation sourceInformation)
- : super(<HInstruction>[value], domain.emptyType) {
+ : super([value], domain.emptyType) {
this.sourceInformation = sourceInformation;
}
bool hasStar;
@@ -3230,7 +3221,7 @@
HThrow(AbstractValueDomain domain, HInstruction value,
SourceInformation sourceInformation,
{this.isRethrow = false})
- : super(domain, <HInstruction>[value]) {
+ : super(domain, [value]) {
this.sourceInformation = sourceInformation;
}
@override
@@ -3246,7 +3237,7 @@
final MemberEntity element;
HStatic(this.element, AbstractValue type, SourceInformation sourceInformation)
- : super(<HInstruction>[], type) {
+ : super([], type) {
assert(element != null);
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
@@ -3288,7 +3279,7 @@
//
HInterceptor(HInstruction receiver, AbstractValue type)
- : super(<HInstruction>[receiver], type) {
+ : super([receiver], type) {
this.sourceInformation = receiver.sourceInformation;
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
@@ -3362,7 +3353,7 @@
HLazyStatic(
this.element, AbstractValue type, SourceInformation sourceInformation)
- : super(<HInstruction>[], type) {
+ : super([], type) {
// TODO(4931): The first access has side-effects, but we afterwards we
// should be able to GVN.
sideEffects.setAllSideEffects();
@@ -3387,7 +3378,7 @@
class HStaticStore extends HInstruction {
MemberEntity element;
HStaticStore(AbstractValueDomain domain, this.element, HInstruction value)
- : super(<HInstruction>[value], domain.emptyType) {
+ : super([value], domain.emptyType) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
sideEffects.setChangesStaticProperty();
@@ -3425,7 +3416,7 @@
/// does not throw because we generate the checks explicitly.
class HIndex extends HInstruction {
HIndex(HInstruction receiver, HInstruction index, AbstractValue type)
- : super(<HInstruction>[receiver, index], type) {
+ : super([receiver, index], type) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
sideEffects.setDependsOnIndexStore();
@@ -3466,7 +3457,7 @@
class HIndexAssign extends HInstruction {
HIndexAssign(AbstractValueDomain domain, HInstruction receiver,
HInstruction index, HInstruction value)
- : super(<HInstruction>[receiver, index, value], domain.emptyType) {
+ : super([receiver, index, value], domain.emptyType) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
sideEffects.setChangesIndex();
@@ -3541,7 +3532,7 @@
HInstruction input, SourceInformation sourceInformation,
{this.receiverTypeCheckSelector})
: checkedType = type,
- super(<HInstruction>[input], type) {
+ super([input], type) {
assert(isReceiverTypeCheck == (receiverTypeCheckSelector != null));
this.sourceElement = input.sourceElement;
this.sourceInformation = sourceInformation;
@@ -3596,7 +3587,7 @@
// become unnecessary and should be removed.
class HBoolConversion extends HCheck {
HBoolConversion(HInstruction input, AbstractValue type)
- : super(<HInstruction>[input], type);
+ : super([input], type);
@override
bool isJsStatement() => false;
@@ -3639,7 +3630,7 @@
FieldEntity field;
HNullCheck(HInstruction input, AbstractValue type, {this.sticky = false})
- : super(<HInstruction>[input], type);
+ : super([input], type);
@override
bool isControlFlow() => true;
@@ -3679,16 +3670,13 @@
AbstractValue knownType;
final bool _isMovable;
- HTypeKnown.pinned(AbstractValue knownType, HInstruction input)
- : this.knownType = knownType,
- this._isMovable = false,
- super(<HInstruction>[input], knownType);
+ HTypeKnown.pinned(this.knownType, HInstruction input)
+ : this._isMovable = false,
+ super([input], knownType);
- HTypeKnown.witnessed(
- AbstractValue knownType, HInstruction input, HInstruction witness)
- : this.knownType = knownType,
- this._isMovable = true,
- super(<HInstruction>[input, witness], knownType);
+ HTypeKnown.witnessed(this.knownType, HInstruction input, HInstruction witness)
+ : this._isMovable = true,
+ super([input, witness], knownType);
@override
toString() => 'TypeKnown $knownType';
@@ -3732,8 +3720,7 @@
}
class HRangeConversion extends HCheck {
- HRangeConversion(HInstruction input, type)
- : super(<HInstruction>[input], type) {
+ HRangeConversion(HInstruction input, type) : super([input], type) {
sourceElement = input.sourceElement;
}
@@ -3746,7 +3733,7 @@
class HStringConcat extends HInstruction {
HStringConcat(HInstruction left, HInstruction right, AbstractValue type)
- : super(<HInstruction>[left, right], type) {
+ : super([left, right], type) {
// TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the
// concats bunched with stringified inputs for much better looking code with
// fewer temps.
@@ -3766,7 +3753,7 @@
/// into a String value.
class HStringify extends HInstruction {
HStringify(HInstruction input, AbstractValue resultType)
- : super(<HInstruction>[input], resultType) {
+ : super([input], resultType) {
sideEffects.setAllSideEffects();
sideEffects.setDependsOnSomething();
}
@@ -3780,21 +3767,19 @@
/// Non-block-based (aka. traditional) loop information.
class HLoopInformation {
final HBasicBlock header;
- final List<HBasicBlock> blocks;
- final List<HBasicBlock> backEdges;
+ final List<HBasicBlock> blocks = [];
+ final List<HBasicBlock> backEdges = [];
final List<LabelDefinition> labels;
final JumpTarget target;
/// Corresponding block information for the loop.
HLoopBlockInformation loopBlockInformation;
- HLoopInformation(this.header, this.target, this.labels)
- : blocks = <HBasicBlock>[],
- backEdges = <HBasicBlock>[];
+ HLoopInformation(this.header, this.target, this.labels);
void addBackEdge(HBasicBlock predecessor) {
backEdges.add(predecessor);
- List<HBasicBlock> workQueue = <HBasicBlock>[predecessor];
+ List<HBasicBlock> workQueue = [predecessor];
do {
HBasicBlock current = workQueue.removeLast();
addBlock(current, workQueue);
@@ -3931,7 +3916,7 @@
HLabeledBlockInformation.implicit(this.body, this.target,
{this.isContinue = false})
- : this.labels = const <LabelDefinition>[];
+ : this.labels = const [];
@override
HBasicBlock get start => body.start;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 5bbc0ec..501d09f 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -50,7 +50,7 @@
class SsaOptimizerTask extends CompilerTask {
final CompilerOptions _options;
- Map<HInstruction, Range> ranges = <HInstruction, Range>{};
+ Map<HInstruction, Range> ranges = {};
Map<MemberEntity, OptimizationTestLog> loggersForTesting;
@@ -86,7 +86,7 @@
}
measure(() {
- List<OptimizationPhase> phases = <OptimizationPhase>[
+ List<OptimizationPhase> phases = [
// Run trivial instruction simplification first to optimize
// some patterns useful for type conversion.
SsaInstructionSimplifier(globalInferenceResults, _options, closedWorld,
@@ -141,7 +141,7 @@
dce.eliminatedSideEffects ||
dce.newGvnCandidates ||
loadElimination.newGvnCandidates) {
- phases = <OptimizationPhase>[
+ phases = [
SsaTypePropagator(globalInferenceResults, closedWorld.commonElements,
closedWorld, log),
SsaGlobalValueNumberer(closedWorld.abstractValueDomain),
@@ -153,7 +153,7 @@
SsaDeadCodeEliminator(closedWorld, this),
];
} else {
- phases = <OptimizationPhase>[
+ phases = [
SsaTypePropagator(globalInferenceResults, closedWorld.commonElements,
closedWorld, log),
// Run the simplifier to remove unneeded type checks inserted by
@@ -408,7 +408,8 @@
return;
}
- // TODO(sra): Consider other simple diamonds, e.g. with the addition of a special instruction,
+ // TODO(sra): Consider other simple diamonds, e.g. with the addition of a
+ // special instruction,
//
// s == null ? "" : s ---> s || "".
return;
@@ -750,11 +751,8 @@
_abstractValueDomain.dynamicType);
node.block.addBefore(node, typeInfo);
- HInvokeStatic tagInstruction = HInvokeStatic(
- commonElements.setArrayType,
- <HInstruction>[splitInstruction, typeInfo],
- resultMask,
- const <DartType>[]);
+ HInvokeStatic tagInstruction = HInvokeStatic(commonElements.setArrayType,
+ [splitInstruction, typeInfo], resultMask, const <DartType>[]);
// 'Linear typing' trick: [tagInstruction] is the only use of the
// [splitInstruction], so it becomes the sole alias.
// TODO(sra): Build this knowledge into alias analysis.
@@ -839,8 +837,10 @@
insertionPoint = load;
}
Selector callSelector = Selector.callClosureFrom(node.selector);
- List<HInstruction> inputs = <HInstruction>[load]
- ..addAll(node.inputs.skip(node.isInterceptedCall ? 2 : 1));
+ List<HInstruction> inputs = [
+ load,
+ ...node.inputs.skip(node.isInterceptedCall ? 2 : 1)
+ ];
DartType fieldType =
_closedWorld.elementEnvironment.getFieldType(field);
HInstruction closureCall = HInvokeClosure(
@@ -1822,7 +1822,7 @@
if (_abstractValueDomain
.isInterceptor(input.instructionType)
.isDefinitelyFalse) {
- var inputs = <HInstruction>[input, input]; // [interceptor, receiver].
+ List<HInstruction> inputs = [input, input]; // [interceptor, receiver].
HInstruction result = HInvokeDynamicMethod(
selector,
input.instructionType, // receiver type.
@@ -2308,8 +2308,7 @@
final SsaOptimizerTask optimizer;
HGraph _graph;
SsaLiveBlockAnalyzer analyzer;
- Map<HInstruction, bool> trivialDeadStoreReceivers =
- Maplet<HInstruction, bool>();
+ Map<HInstruction, bool> trivialDeadStoreReceivers = Maplet();
bool eliminatedSideEffects = false;
bool newGvnCandidates = false;
@@ -2625,8 +2624,8 @@
class SsaLiveBlockAnalyzer extends HBaseVisitor {
final HGraph graph;
- final Set<HBasicBlock> live = Set<HBasicBlock>();
- final List<HBasicBlock> worklist = <HBasicBlock>[];
+ final Set<HBasicBlock> live = {};
+ final List<HBasicBlock> worklist = [];
final SsaOptimizerTask optimizer;
final JClosedWorld closedWorld;
@@ -2684,7 +2683,7 @@
IntValue upperValue = switchRange.upper;
BigInt lower = lowerValue.value;
BigInt upper = upperValue.value;
- Set<BigInt> liveLabels = Set<BigInt>();
+ Set<BigInt> liveLabels = {};
for (int pos = 1; pos < node.inputs.length; pos++) {
HConstant input = node.inputs[pos];
if (!input.isConstantInteger()) continue;
@@ -2711,9 +2710,9 @@
@override
void visitGraph(HGraph graph) {
- final List<HPhi> worklist = <HPhi>[];
+ final List<HPhi> worklist = [];
// A set to keep track of the live phis that we found.
- final Set<HPhi> livePhis = Set<HPhi>();
+ final Set<HPhi> livePhis = {};
// Add to the worklist all live phis: phis referenced by non-phi
// instructions.
@@ -2770,7 +2769,7 @@
@override
void visitGraph(HGraph graph) {
- final List<HPhi> worklist = <HPhi>[];
+ final List<HPhi> worklist = [];
// Add all phis in the worklist.
for (final block in graph.blocks) {
@@ -2828,20 +2827,18 @@
final AbstractValueDomain _abstractValueDomain;
@override
final String name = "SsaGlobalValueNumberer";
- final Set<int> visited;
+ final Set<int> visited = {};
List<int> blockChangesFlags;
List<int> loopChangesFlags;
- SsaGlobalValueNumberer(this._abstractValueDomain) : visited = Set<int>();
+ SsaGlobalValueNumberer(this._abstractValueDomain);
@override
void visitGraph(HGraph graph) {
computeChangesFlags(graph);
moveLoopInvariantCode(graph);
- List<GvnWorkItem> workQueue = <GvnWorkItem>[
- GvnWorkItem(graph.entry, ValueSet())
- ];
+ List<GvnWorkItem> workQueue = [GvnWorkItem(graph.entry, ValueSet())];
do {
GvnWorkItem item = workQueue.removeLast();
visitBasicBlock(item.block, item.valueSet, workQueue);
@@ -3203,8 +3200,8 @@
@override
void visitIsTest(HIsTest instruction) {
- List<HBasicBlock> trueTargets = <HBasicBlock>[];
- List<HBasicBlock> falseTargets = <HBasicBlock>[];
+ List<HBasicBlock> trueTargets = [];
+ List<HBasicBlock> falseTargets = [];
collectTargets(instruction, trueTargets, falseTargets);
@@ -3262,8 +3259,8 @@
return;
}
- List<HBasicBlock> trueTargets = <HBasicBlock>[];
- List<HBasicBlock> falseTargets = <HBasicBlock>[];
+ List<HBasicBlock> trueTargets = [];
+ List<HBasicBlock> falseTargets = [];
collectTargets(instruction, trueTargets, falseTargets);
@@ -3683,15 +3680,13 @@
// TODO(25544): Split length effects from other effects and model lengths
// separately.
final Map<Object /*MemberEntity|MemoryFeature*/,
- Map<HInstruction, HInstruction>>
- fieldValues = <Object, Map<HInstruction, HInstruction>>{};
+ Map<HInstruction, HInstruction>> fieldValues = {};
/// Maps a receiver to a map of keys to value.
- final Map<HInstruction, Map<HInstruction, HInstruction>> keyedValues =
- <HInstruction, Map<HInstruction, HInstruction>>{};
+ final Map<HInstruction, Map<HInstruction, HInstruction>> keyedValues = {};
/// Set of objects that we know don't escape the current function.
- final Setlet<HInstruction> nonEscapingReceivers = Setlet<HInstruction>();
+ final Setlet<HInstruction> nonEscapingReceivers = Setlet();
MemorySet(this.closedWorld);
@@ -3782,7 +3777,7 @@
// non-escaping set.
nonEscapingReceivers.remove(value.nonCheck());
Map<HInstruction, HInstruction> map =
- fieldValues.putIfAbsent(field, () => <HInstruction, HInstruction>{});
+ fieldValues.putIfAbsent(field, () => {});
bool isRedundant = map[receiver] == value;
map.forEach((key, value) {
if (mayAlias(receiver, key)) map[key] = null;
@@ -3801,7 +3796,7 @@
return; // TODO(14955): Remove this restriction?
}
Map<HInstruction, HInstruction> map =
- fieldValues.putIfAbsent(field, () => <HInstruction, HInstruction>{});
+ fieldValues.putIfAbsent(field, () => {});
map[receiver] = value;
}
@@ -3828,7 +3823,7 @@
if (instruction.sideEffects.changesInstanceProperty() ||
instruction.sideEffects.changesStaticProperty()) {
- List<HInstruction> receiversToRemove = <HInstruction>[];
+ List<HInstruction> receiversToRemove = [];
List<Object> fieldsToRemove;
fieldValues.forEach((Object element, map) {
@@ -3840,7 +3835,7 @@
});
if (receiversToRemove.length == map.length) {
// Remove them all by removing the entire map.
- (fieldsToRemove ??= <Object>[]).add(element);
+ (fieldsToRemove ??= []).add(element);
} else {
receiversToRemove.forEach(map.remove);
}
@@ -3871,7 +3866,7 @@
void registerKeyedValue(
HInstruction receiver, HInstruction index, HInstruction value) {
Map<HInstruction, HInstruction> map =
- keyedValues.putIfAbsent(receiver, () => <HInstruction, HInstruction>{});
+ keyedValues.putIfAbsent(receiver, () => {});
map[index] = value;
}
@@ -3897,7 +3892,7 @@
if (couldBeTypedArray(receiver)) return;
Map<HInstruction, HInstruction> map =
- keyedValues.putIfAbsent(receiver, () => <HInstruction, HInstruction>{});
+ keyedValues.putIfAbsent(receiver, () => {});
map[index] = value;
}
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 179b946..5b825ce 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -299,7 +299,7 @@
@override
Iterable<CompilerTask> get tasks {
- return <CompilerTask>[_builder, optimizer, generator];
+ return [_builder, optimizer, generator];
}
}
diff --git a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
index 76d72c0..df4e293 100644
--- a/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_branch_builder.dart
@@ -178,9 +178,7 @@
HConstant notIsAnd =
builder.graph.addConstantBool(!isAnd, builder.closedWorld);
HPhi result = HPhi.manyInputs(
- null,
- <HInstruction>[boolifiedRight, notIsAnd],
- _abstractValueDomain.dynamicType)
+ null, [boolifiedRight, notIsAnd], _abstractValueDomain.dynamicType)
..sourceInformation = sourceInformation;
builder.current.addPhi(result);
builder.stack.add(result);
@@ -206,8 +204,8 @@
if (isExpression) {
assert(thenValue != null && elseValue != null);
- HPhi phi = HPhi.manyInputs(null, <HInstruction>[thenValue, elseValue],
- _abstractValueDomain.dynamicType);
+ HPhi phi = HPhi.manyInputs(
+ null, [thenValue, elseValue], _abstractValueDomain.dynamicType);
joinBranch.block.addPhi(phi);
builder.stack.add(phi);
}
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index f6909df..bd8c259 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -30,10 +30,9 @@
// TODO(sra): The InvokeDynamicSpecializer should be consulted for better
// targeted conditioning checks.
class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
- final Map<int, HInstruction> workmap = Map<int, HInstruction>();
- final List<int> worklist = <int>[];
- final Map<HInstruction, Function> pendingOptimizations =
- Map<HInstruction, Function>();
+ final Map<int, HInstruction> workmap = {};
+ final List<int> worklist = [];
+ final Map<HInstruction, Function> pendingOptimizations = {};
final GlobalTypeInferenceResults results;
final CommonElements commonElements;
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 1c4c554..2b20fa4 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -637,11 +637,11 @@
/// List of [HRangeConversion] instructions created by the phase. We
/// save them here in order to remove them once the phase is done.
- final List<HRangeConversion> conversions = <HRangeConversion>[];
+ final List<HRangeConversion> conversions = [];
/// Value ranges for integer instructions. This map gets populated by
/// the dominator tree visit.
- final Map<HInstruction, Range> ranges = Map<HInstruction, Range>();
+ final Map<HInstruction, Range> ranges = {};
final JClosedWorld closedWorld;
final ValueRangeInfo info;
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index 4f90aa5..f4024bd 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -26,7 +26,7 @@
/// The id where the instruction is defined.
int start;
final List<LiveRange> ranges;
- LiveInterval() : ranges = <LiveRange>[];
+ LiveInterval() : ranges = [];
// We want [HCheck] instructions to have the same name as the
// instruction it checks, so both instructions should share the same
@@ -59,7 +59,7 @@
@override
String toString() {
- List<String> res = <String>[];
+ List<String> res = [];
for (final interval in ranges) res.add(interval.toString());
return '(${res.join(", ")})';
}
@@ -80,20 +80,18 @@
/// visited. The liveIn set of the loop header will be merged into this
/// environment. [loopMarkers] is a mapping from block header to the
/// end instruction id of the loop exit block.
- final Map<HBasicBlock, int> loopMarkers;
+ final Map<HBasicBlock, int> loopMarkers = {};
/// The instructions that are live in this basic block. The values of
/// the map contain the instruction ids where the instructions die.
/// It will be used when adding a range to the live interval of an
/// instruction.
- final Map<HInstruction, int> liveInstructions;
+ final Map<HInstruction, int> liveInstructions = {};
/// Map containing the live intervals of instructions.
final Map<HInstruction, LiveInterval> liveIntervals;
- LiveEnvironment(this.liveIntervals, this.endId)
- : liveInstructions = Map<HInstruction, int>(),
- loopMarkers = Map<HBasicBlock, int>();
+ LiveEnvironment(this.liveIntervals, this.endId);
/// Remove an instruction from the liveIn set. This method also
/// updates the live interval of [instruction] to contain the new
@@ -369,15 +367,11 @@
/// after executing all its instructions.
class CopyHandler {
/// The copies from an instruction to a phi of the successor.
- final List<Copy<HInstruction>> copies;
+ final List<Copy<HInstruction>> copies = [];
/// Assignments from an instruction that does not need a name (e.g. a
/// constant) to the phi of a successor.
- final List<Copy<HInstruction>> assignments;
-
- CopyHandler()
- : copies = <Copy<HInstruction>>[],
- assignments = <Copy<HInstruction>>[];
+ final List<Copy<HInstruction>> assignments = [];
void addCopy(HInstruction source, HInstruction destination) {
copies.add(Copy<HInstruction>(source, destination));
@@ -396,28 +390,22 @@
/// Contains the mapping between instructions and their names for code
/// generation, as well as the [CopyHandler] for each basic block.
class VariableNames {
- final Map<HInstruction, String> ownName;
- final Map<HBasicBlock, CopyHandler> copyHandlers;
+ final Map<HInstruction, String> ownName = {};
+ final Map<HBasicBlock, CopyHandler> copyHandlers = {};
// Used to control heuristic that determines how local variables are declared.
- final Set<String> allUsedNames;
+ final Set<String> allUsedNames = {};
- /// Name that is used as a temporary to break cycles in
- /// parallel copies. We make sure this name is not being used
- /// anywhere by reserving it when we allocate names for instructions.
- final String swapTemp;
+ /// Name that is used as a temporary to break cycles in parallel copies. We
+ /// make sure this name is not being used anywhere by reserving it when we
+ /// allocate names for instructions.
+ final String swapTemp = 't0';
String getSwapTemp() {
allUsedNames.add(swapTemp);
return swapTemp;
}
- VariableNames()
- : ownName = Map<HInstruction, String>(),
- copyHandlers = Map<HBasicBlock, CopyHandler>(),
- allUsedNames = Set<String>(),
- swapTemp = 't0';
-
int get numberOfVariables => allUsedNames.length;
String getName(HInstruction instruction) {
@@ -449,14 +437,12 @@
class VariableNamer {
final VariableNames names;
final ModularNamer _namer;
- final Set<String> usedNames;
- final List<String> freeTemporaryNames;
+ final Set<String> usedNames = {};
+ final List<String> freeTemporaryNames = [];
int temporaryIndex = 0;
static final RegExp regexp = RegExp('t[0-9]+');
- VariableNamer(LiveEnvironment environment, this.names, this._namer)
- : usedNames = Set<String>(),
- freeTemporaryNames = <String>[] {
+ VariableNamer(LiveEnvironment environment, this.names, this._namer) {
// [VariableNames.swapTemp] is used when there is a cycle in a copy handler.
// Therefore we make sure no one uses it.
usedNames.add(names.swapTemp);
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart
new file mode 100644
index 0000000..aa00557
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'package:test/test.dart';
+
+import 'expression_compiler_worker_shared.dart';
+
+void main() async {
+ group('amd module format -', () {
+ for (var soundNullSafety in [true, false]) {
+ group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
+ runTests('amd', soundNullSafety);
+ });
+ }
+ });
+}
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart
new file mode 100644
index 0000000..cc272c3
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'package:test/test.dart';
+
+import 'expression_compiler_worker_shared.dart';
+
+void main() async {
+ group('ddc module format -', () {
+ for (var soundNullSafety in [true, false]) {
+ group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
+ runTests('ddc', soundNullSafety);
+ });
+ }
+ });
+}
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart
similarity index 91%
rename from pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
rename to pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart
index 8bf3653..b1a4eac 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart
@@ -27,78 +27,68 @@
/// Verbose mode for debugging
bool get verbose => false;
-void main() async {
- for (var moduleFormat in ['amd', 'ddc']) {
- group('$moduleFormat module format -', () {
- for (var soundNullSafety in [true, false]) {
- group('${soundNullSafety ? "sound" : "unsound"} null safety -', () {
- group('expression compiler worker on startup', () {
- Directory tempDir;
- ReceivePort receivePort;
+void runTests(String moduleFormat, bool soundNullSafety) {
+ group('expression compiler worker on startup', () {
+ Directory tempDir;
+ ReceivePort receivePort;
- setUp(() async {
- tempDir = Directory.systemTemp.createTempSync('foo bar');
- receivePort = ReceivePort();
- });
+ setUp(() async {
+ tempDir = Directory.systemTemp.createTempSync('foo bar');
+ receivePort = ReceivePort();
+ });
- tearDown(() async {
- tempDir.deleteSync(recursive: true);
- receivePort.close();
- });
+ tearDown(() async {
+ tempDir.deleteSync(recursive: true);
+ receivePort.close();
+ });
- test('reports failure to consumer', () async {
- expect(
- receivePort,
- emitsInOrder([
- equals(isA<SendPort>()),
- equals({
- 'succeeded': false,
- 'stackTrace': isNotNull,
- 'exception': contains('Could not load SDK component'),
- }),
- ]));
+ test('reports failure to consumer', () async {
+ expect(
+ receivePort,
+ emitsInOrder([
+ equals(isA<SendPort>()),
+ equals({
+ 'succeeded': false,
+ 'stackTrace': isNotNull,
+ 'exception': contains('Could not load SDK component'),
+ }),
+ ]));
- try {
- var badPath = 'file:///path/does/not/exist';
- await ExpressionCompilerWorker.createAndStart(
- [
- '--libraries-file',
- badPath,
- '--dart-sdk-summary',
- badPath,
- '--module-format',
- moduleFormat,
- soundNullSafety
- ? '--sound-null-safety'
- : '--no-sound-null-safety',
- if (verbose) '--verbose',
- ],
- sendPort: receivePort.sendPort,
- );
- } catch (e) {
- throwsA(contains('Could not load SDK component'));
- }
- });
- });
-
- group('reading assets using standard file system - ', () {
- runExpressionCompilationTests(
- StandardFileSystemTestDriver(soundNullSafety, moduleFormat));
- });
-
- group('reading assets using multiroot file system - ', () {
- runExpressionCompilationTests(
- MultiRootFileSystemTestDriver(soundNullSafety, moduleFormat));
- });
-
- group('reading assets using asset file system -', () {
- runExpressionCompilationTests(
- AssetFileSystemTestDriver(soundNullSafety, moduleFormat));
- });
- });
+ try {
+ var badPath = 'file:///path/does/not/exist';
+ await ExpressionCompilerWorker.createAndStart(
+ [
+ '--libraries-file',
+ badPath,
+ '--dart-sdk-summary',
+ badPath,
+ '--module-format',
+ moduleFormat,
+ soundNullSafety ? '--sound-null-safety' : '--no-sound-null-safety',
+ if (verbose) '--verbose',
+ ],
+ sendPort: receivePort.sendPort,
+ );
+ } catch (e) {
+ throwsA(contains('Could not load SDK component'));
}
});
- }
+ });
+
+ group('reading assets using standard file system - ', () {
+ runExpressionCompilationTests(
+ StandardFileSystemTestDriver(soundNullSafety, moduleFormat));
+ });
+
+ group('reading assets using multiroot file system - ', () {
+ runExpressionCompilationTests(
+ MultiRootFileSystemTestDriver(soundNullSafety, moduleFormat));
+ });
+
+ group('reading assets using asset file system -', () {
+ runExpressionCompilationTests(
+ AssetFileSystemTestDriver(soundNullSafety, moduleFormat));
+ });
}
void runExpressionCompilationTests(TestDriver driver) {
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart
new file mode 100644
index 0000000..7292bb7
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'main_lib1.dart';
+import 'main_lib2.dart' as lib;
+
+void main() {
+ testUninitializedNonFinalInstanceField();
+ testUninitializedFinalInstanceField();
+ testInitializedNonFinalInstanceField();
+ testInitializedFinalInstanceField();
+
+ testNullableUninitializedNonFinalLocal();
+ testNonNullableUninitializedNonFinalLocal();
+ testNullableUninitializedFinalLocal();
+ testNonNullableUninitializedFinalLocal();
+ testNullableInitializedNonFinalLocal();
+ testNonNullableInitializedNonFinalLocal();
+ testNullableInitializedFinalLocal();
+ testNonNullableInitializedFinalLocal();
+
+ testUninitializedNonFinalStaticField();
+ testUninitializedFinalStaticField();
+ testInitializedNonFinalStaticField();
+ testInitializedFinalStaticField();
+ testUninitializedNonFinalTopLevelField();
+ testUninitializedFinalTopLevelField();
+ testInitializedNonFinalTopLevelField();
+ testInitializedFinalTopLevelField();
+}
+
+var c = C();
+
+void testUninitializedNonFinalInstanceField() {
+ print(c.a);
+ c.a = 42;
+ print(c.a);
+}
+
+void testUninitializedFinalInstanceField() {
+ print(c.b);
+ c.b = 42;
+ print(c.b);
+}
+
+void testInitializedNonFinalInstanceField() {
+ print(c.c);
+ c.c = 42;
+ print(c.c);
+}
+
+void testInitializedFinalInstanceField() {
+ print(c.d);
+}
+
+void testUninitializedNonFinalStaticField() {
+ print(Statics.a);
+ Statics.a = 42;
+ print(Statics.a);
+}
+
+void testUninitializedFinalStaticField() {
+ print(Statics.b);
+ Statics.b = 42;
+ print(Statics.b);
+}
+
+void testInitializedNonFinalStaticField() {
+ print(Statics.c);
+ Statics.c = 42;
+ print(Statics.c);
+}
+
+void testInitializedFinalStaticField() {
+ print(Statics.d);
+}
+
+void testUninitializedNonFinalTopLevelField() {
+ print(lib.a);
+ lib.a = 42;
+ print(lib.a);
+}
+
+void testUninitializedFinalTopLevelField() {
+ print(lib.b);
+ lib.b = 42;
+ print(lib.b);
+}
+
+void testInitializedNonFinalTopLevelField() {
+ print(lib.c);
+ lib.c = 42;
+ print(lib.c);
+}
+
+void testInitializedFinalTopLevelField() {
+ print(lib.d);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect
new file mode 100644
index 0000000..7cafb3b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.expect
@@ -0,0 +1,225 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+// Statics.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+// Statics.b = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+// lib.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+// lib.b = 42;
+// ^
+//
+import self as self;
+import "main_lib1.dart" as mai;
+import "dart:core" as core;
+import "main_lib2.dart" as mai2;
+
+import "org-dartlang-testcase:///main_lib1.dart";
+import "org-dartlang-testcase:///main_lib2.dart" as lib;
+
+static field mai::C c = new mai::C::•();
+static method main() → void {
+ self::testUninitializedNonFinalInstanceField();
+ self::testUninitializedFinalInstanceField();
+ self::testInitializedNonFinalInstanceField();
+ self::testInitializedFinalInstanceField();
+ mai::testNullableUninitializedNonFinalLocal();
+ mai::testNonNullableUninitializedNonFinalLocal();
+ mai::testNullableUninitializedFinalLocal();
+ mai::testNonNullableUninitializedFinalLocal();
+ mai::testNullableInitializedNonFinalLocal();
+ mai::testNonNullableInitializedNonFinalLocal();
+ mai::testNullableInitializedFinalLocal();
+ mai::testNonNullableInitializedFinalLocal();
+ self::testUninitializedNonFinalStaticField();
+ self::testUninitializedFinalStaticField();
+ self::testInitializedNonFinalStaticField();
+ self::testInitializedFinalStaticField();
+ self::testUninitializedNonFinalTopLevelField();
+ self::testUninitializedFinalTopLevelField();
+ self::testInitializedNonFinalTopLevelField();
+ self::testInitializedFinalTopLevelField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::a}{core::int});
+ self::c.{mai::C::a} = 42;
+ core::print(self::c.{mai::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::b}{core::int});
+ self::c.{mai::C::b} = 42;
+ core::print(self::c.{mai::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::c}{core::int});
+ self::c.{mai::C::c} = 42;
+ core::print(self::c.{mai::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::d}{core::int});
+}
+static method testUninitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+ Statics.a = 42;
+ ^";
+ core::print(mai::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+ core::print(mai::Statics::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+ Statics.b = 42;
+ ^";
+ core::print(mai::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::c);
+ mai::Statics::c = 42;
+ core::print(mai::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+ core::print(mai::Statics::d);
+}
+static method testUninitializedNonFinalTopLevelField() → void {
+ core::print(mai2::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+ lib.a = 42;
+ ^";
+ core::print(mai2::a);
+}
+static method testUninitializedFinalTopLevelField() → void {
+ core::print(mai2::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+ lib.b = 42;
+ ^";
+ core::print(mai2::b);
+}
+static method testInitializedNonFinalTopLevelField() → void {
+ core::print(mai2::c);
+ mai2::c = 42;
+ core::print(mai2::c);
+}
+static method testInitializedFinalTopLevelField() → void {
+ core::print(mai2::d);
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+import "dart:_late_helper" as _la;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+ field core::int _#C#a = _in::createSentinel<core::int>();
+ field core::int _#C#b = _in::createSentinel<core::int>();
+ field core::int _#C#c = _in::createSentinel<core::int>();
+ field core::int _#C#d = _in::createSentinel<core::int>();
+ synthetic constructor •() → mai::C
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::C
+ return new mai::C::•();
+ get a() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+ set a(core::int value) → void
+ this.{mai::C::_#C#a} = value;
+ get b() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+ set b(core::int value) → void {
+ _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
+ this.{mai::C::_#C#b} = value;
+ }
+ get c() → core::int {
+ core::int value = this.{mai::C::_#C#c}{core::int};
+ if(_in::isSentinel(value))
+ value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+ return value;
+ }
+ set c(core::int value) → void
+ this.{mai::C::_#C#c} = value;
+ get d() → core::int {
+ core::int value = this.{mai::C::_#C#d}{core::int};
+ if(_in::isSentinel(value)) {
+ final core::int result = 1.{core::int::unary-}(){() → core::int};
+ _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
+ value = this.{mai::C::_#C#d} = result;
+ }
+ return value;
+ }
+}
+class Statics extends core::Object {
+ static final field _la::_Cell a = new _la::_Cell::named("a");
+ static final field _la::_Cell b = new _la::_Cell::named("b");
+ late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+ late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
+ synthetic constructor •() → mai::Statics
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::Statics
+ return new mai::Statics::•();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::read}<core::int?>(){() → core::int?});
+ y.{_la::_InitializedCell::value} = 42;
+ core::print(y.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int>(){() → core::int});
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai2;
+import "dart:_late_helper" as _la;
+import "dart:core" as core;
+
+static final field _la::_Cell a = new _la::_Cell::named("a");
+static final field _la::_Cell b = new _la::_Cell::named("b");
+late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..62953b9
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.strong.transformed.expect
@@ -0,0 +1,239 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+// Statics.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+// Statics.b = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+// lib.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+// lib.b = 42;
+// ^
+//
+import self as self;
+import "main_lib1.dart" as mai;
+import "dart:core" as core;
+import "main_lib2.dart" as mai2;
+
+import "org-dartlang-testcase:///main_lib1.dart";
+import "org-dartlang-testcase:///main_lib2.dart" as lib;
+
+static field mai::C c = new mai::C::•();
+static method main() → void {
+ self::testUninitializedNonFinalInstanceField();
+ self::testUninitializedFinalInstanceField();
+ self::testInitializedNonFinalInstanceField();
+ self::testInitializedFinalInstanceField();
+ mai::testNullableUninitializedNonFinalLocal();
+ mai::testNonNullableUninitializedNonFinalLocal();
+ mai::testNullableUninitializedFinalLocal();
+ mai::testNonNullableUninitializedFinalLocal();
+ mai::testNullableInitializedNonFinalLocal();
+ mai::testNonNullableInitializedNonFinalLocal();
+ mai::testNullableInitializedFinalLocal();
+ mai::testNonNullableInitializedFinalLocal();
+ self::testUninitializedNonFinalStaticField();
+ self::testUninitializedFinalStaticField();
+ self::testInitializedNonFinalStaticField();
+ self::testInitializedFinalStaticField();
+ self::testUninitializedNonFinalTopLevelField();
+ self::testUninitializedFinalTopLevelField();
+ self::testInitializedNonFinalTopLevelField();
+ self::testInitializedFinalTopLevelField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::a}{core::int});
+ self::c.{mai::C::a} = 42;
+ core::print(self::c.{mai::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::b}{core::int});
+ self::c.{mai::C::b} = 42;
+ core::print(self::c.{mai::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::c}{core::int});
+ self::c.{mai::C::c} = 42;
+ core::print(self::c.{mai::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::d}{core::int});
+}
+static method testUninitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+ Statics.a = 42;
+ ^";
+ core::print(mai::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+ core::print(mai::Statics::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+ Statics.b = 42;
+ ^";
+ core::print(mai::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::c);
+ mai::Statics::c = 42;
+ core::print(mai::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+ core::print(mai::Statics::d);
+}
+static method testUninitializedNonFinalTopLevelField() → void {
+ core::print(mai2::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+ lib.a = 42;
+ ^";
+ core::print(mai2::a);
+}
+static method testUninitializedFinalTopLevelField() → void {
+ core::print(mai2::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+ lib.b = 42;
+ ^";
+ core::print(mai2::b);
+}
+static method testInitializedNonFinalTopLevelField() → void {
+ core::print(mai2::c);
+ mai2::c = 42;
+ core::print(mai2::c);
+}
+static method testInitializedFinalTopLevelField() → void {
+ core::print(mai2::d);
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+import "dart:_late_helper" as _la;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+ field core::int _#C#a = _in::createSentinel<core::int>();
+ field core::int _#C#b = _in::createSentinel<core::int>();
+ field core::int _#C#c = _in::createSentinel<core::int>();
+ field core::int _#C#d = _in::createSentinel<core::int>();
+ synthetic constructor •() → mai::C
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::C
+ return new mai::C::•();
+ get a() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+ set a(core::int value) → void
+ this.{mai::C::_#C#a} = value;
+ get b() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+ set b(core::int value) → void {
+ _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
+ this.{mai::C::_#C#b} = value;
+ }
+ get c() → core::int {
+ core::int value = this.{mai::C::_#C#c}{core::int};
+ if(_in::isSentinel(value))
+ value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+ return value;
+ }
+ set c(core::int value) → void
+ this.{mai::C::_#C#c} = value;
+ get d() → core::int {
+ core::int value = this.{mai::C::_#C#d}{core::int};
+ if(_in::isSentinel(value)) {
+ final core::int result = 1.{core::int::unary-}(){() → core::int};
+ _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
+ value = this.{mai::C::_#C#d} = result;
+ }
+ return value;
+ }
+}
+class Statics extends core::Object {
+ static final field _la::_Cell a = new _la::_Cell::named("a");
+ static final field _la::_Cell b = new _la::_Cell::named("b");
+ late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+ late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
+ synthetic constructor •() → mai::Statics
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::Statics
+ return new mai::Statics::•();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::read}<core::int?>(){() → core::int?});
+ y.{_la::_InitializedCell::value} = 42;
+ core::print(y.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int>(){() → core::int});
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai2;
+import "dart:_late_helper" as _la;
+import "dart:core" as core;
+
+static final field _la::_Cell a = new _la::_Cell::named("a");
+static final field _la::_Cell b = new _la::_Cell::named("b");
+late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:8:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:9:22 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:15:23 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:16:29 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:44:17 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:56:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:63:23 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:71:22 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:7:14 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:8:20 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 205, effectively constant: 10
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.textual_outline.expect
new file mode 100644
index 0000000..ff4b4dc
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import 'main_lib1.dart';
+import 'main_lib2.dart' as lib;
+
+void main() {}
+var c = C();
+void testUninitializedNonFinalInstanceField() {}
+void testUninitializedFinalInstanceField() {}
+void testInitializedNonFinalInstanceField() {}
+void testInitializedFinalInstanceField() {}
+void testUninitializedNonFinalStaticField() {}
+void testUninitializedFinalStaticField() {}
+void testInitializedNonFinalStaticField() {}
+void testInitializedFinalStaticField() {}
+void testUninitializedNonFinalTopLevelField() {}
+void testUninitializedFinalTopLevelField() {}
+void testInitializedNonFinalTopLevelField() {}
+void testInitializedFinalTopLevelField() {}
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..92b8923
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+import 'main_lib1.dart';
+import 'main_lib2.dart' as lib;
+
+var c = C();
+void main() {}
+void testInitializedFinalInstanceField() {}
+void testInitializedFinalStaticField() {}
+void testInitializedFinalTopLevelField() {}
+void testInitializedNonFinalInstanceField() {}
+void testInitializedNonFinalStaticField() {}
+void testInitializedNonFinalTopLevelField() {}
+void testUninitializedFinalInstanceField() {}
+void testUninitializedFinalStaticField() {}
+void testUninitializedFinalTopLevelField() {}
+void testUninitializedNonFinalInstanceField() {}
+void testUninitializedNonFinalStaticField() {}
+void testUninitializedNonFinalTopLevelField() {}
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect
new file mode 100644
index 0000000..7cafb3b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.expect
@@ -0,0 +1,225 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+// Statics.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+// Statics.b = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+// lib.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+// lib.b = 42;
+// ^
+//
+import self as self;
+import "main_lib1.dart" as mai;
+import "dart:core" as core;
+import "main_lib2.dart" as mai2;
+
+import "org-dartlang-testcase:///main_lib1.dart";
+import "org-dartlang-testcase:///main_lib2.dart" as lib;
+
+static field mai::C c = new mai::C::•();
+static method main() → void {
+ self::testUninitializedNonFinalInstanceField();
+ self::testUninitializedFinalInstanceField();
+ self::testInitializedNonFinalInstanceField();
+ self::testInitializedFinalInstanceField();
+ mai::testNullableUninitializedNonFinalLocal();
+ mai::testNonNullableUninitializedNonFinalLocal();
+ mai::testNullableUninitializedFinalLocal();
+ mai::testNonNullableUninitializedFinalLocal();
+ mai::testNullableInitializedNonFinalLocal();
+ mai::testNonNullableInitializedNonFinalLocal();
+ mai::testNullableInitializedFinalLocal();
+ mai::testNonNullableInitializedFinalLocal();
+ self::testUninitializedNonFinalStaticField();
+ self::testUninitializedFinalStaticField();
+ self::testInitializedNonFinalStaticField();
+ self::testInitializedFinalStaticField();
+ self::testUninitializedNonFinalTopLevelField();
+ self::testUninitializedFinalTopLevelField();
+ self::testInitializedNonFinalTopLevelField();
+ self::testInitializedFinalTopLevelField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::a}{core::int});
+ self::c.{mai::C::a} = 42;
+ core::print(self::c.{mai::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::b}{core::int});
+ self::c.{mai::C::b} = 42;
+ core::print(self::c.{mai::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::c}{core::int});
+ self::c.{mai::C::c} = 42;
+ core::print(self::c.{mai::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::d}{core::int});
+}
+static method testUninitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+ Statics.a = 42;
+ ^";
+ core::print(mai::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+ core::print(mai::Statics::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+ Statics.b = 42;
+ ^";
+ core::print(mai::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::c);
+ mai::Statics::c = 42;
+ core::print(mai::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+ core::print(mai::Statics::d);
+}
+static method testUninitializedNonFinalTopLevelField() → void {
+ core::print(mai2::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+ lib.a = 42;
+ ^";
+ core::print(mai2::a);
+}
+static method testUninitializedFinalTopLevelField() → void {
+ core::print(mai2::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+ lib.b = 42;
+ ^";
+ core::print(mai2::b);
+}
+static method testInitializedNonFinalTopLevelField() → void {
+ core::print(mai2::c);
+ mai2::c = 42;
+ core::print(mai2::c);
+}
+static method testInitializedFinalTopLevelField() → void {
+ core::print(mai2::d);
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+import "dart:_late_helper" as _la;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+ field core::int _#C#a = _in::createSentinel<core::int>();
+ field core::int _#C#b = _in::createSentinel<core::int>();
+ field core::int _#C#c = _in::createSentinel<core::int>();
+ field core::int _#C#d = _in::createSentinel<core::int>();
+ synthetic constructor •() → mai::C
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::C
+ return new mai::C::•();
+ get a() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+ set a(core::int value) → void
+ this.{mai::C::_#C#a} = value;
+ get b() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+ set b(core::int value) → void {
+ _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
+ this.{mai::C::_#C#b} = value;
+ }
+ get c() → core::int {
+ core::int value = this.{mai::C::_#C#c}{core::int};
+ if(_in::isSentinel(value))
+ value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+ return value;
+ }
+ set c(core::int value) → void
+ this.{mai::C::_#C#c} = value;
+ get d() → core::int {
+ core::int value = this.{mai::C::_#C#d}{core::int};
+ if(_in::isSentinel(value)) {
+ final core::int result = 1.{core::int::unary-}(){() → core::int};
+ _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
+ value = this.{mai::C::_#C#d} = result;
+ }
+ return value;
+ }
+}
+class Statics extends core::Object {
+ static final field _la::_Cell a = new _la::_Cell::named("a");
+ static final field _la::_Cell b = new _la::_Cell::named("b");
+ late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+ late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
+ synthetic constructor •() → mai::Statics
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::Statics
+ return new mai::Statics::•();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::read}<core::int?>(){() → core::int?});
+ y.{_la::_InitializedCell::value} = 42;
+ core::print(y.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int>(){() → core::int});
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai2;
+import "dart:_late_helper" as _la;
+import "dart:core" as core;
+
+static final field _la::_Cell a = new _la::_Cell::named("a");
+static final field _la::_Cell b = new _la::_Cell::named("b");
+late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect
new file mode 100644
index 0000000..b904ea6
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.outline.expect
@@ -0,0 +1,106 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "main_lib1.dart" as mai;
+
+import "org-dartlang-testcase:///main_lib1.dart";
+import "org-dartlang-testcase:///main_lib2.dart" as lib;
+
+static field mai::C c;
+static method main() → void
+ ;
+static method testUninitializedNonFinalInstanceField() → void
+ ;
+static method testUninitializedFinalInstanceField() → void
+ ;
+static method testInitializedNonFinalInstanceField() → void
+ ;
+static method testInitializedFinalInstanceField() → void
+ ;
+static method testUninitializedNonFinalStaticField() → void
+ ;
+static method testUninitializedFinalStaticField() → void
+ ;
+static method testInitializedNonFinalStaticField() → void
+ ;
+static method testInitializedFinalStaticField() → void
+ ;
+static method testUninitializedNonFinalTopLevelField() → void
+ ;
+static method testUninitializedFinalTopLevelField() → void
+ ;
+static method testInitializedNonFinalTopLevelField() → void
+ ;
+static method testInitializedFinalTopLevelField() → void
+ ;
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+import "dart:_late_helper" as _la;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+ field core::int _#C#a = _in::createSentinel<core::int>();
+ field core::int _#C#b = _in::createSentinel<core::int>();
+ field core::int _#C#c = _in::createSentinel<core::int>();
+ field core::int _#C#d = _in::createSentinel<core::int>();
+ synthetic constructor •() → mai::C
+ ;
+ static method _#new#tearOff() → mai::C
+ return new mai::C::•();
+ get a() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+ set a(core::int value) → void
+ this.{mai::C::_#C#a} = value;
+ get b() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+ set b(core::int value) → void {
+ _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
+ this.{mai::C::_#C#b} = value;
+ }
+ get c() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#c}{core::int}, "c");
+ set c(core::int value) → void
+ this.{mai::C::_#C#c} = value;
+ get d() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#d}{core::int}, "d");
+ set d(core::int value) → void {
+ _la::_lateWriteOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
+ this.{mai::C::_#C#d} = value;
+ }
+}
+class Statics extends core::Object {
+ static final field _la::_Cell a = new _la::_Cell::named("a");
+ static final field _la::_Cell b = new _la::_Cell::named("b");
+ static final field _la::_Cell c = new _la::_Cell::named("c");
+ static final field _la::_Cell d = new _la::_Cell::named("d");
+ synthetic constructor •() → mai::Statics
+ ;
+ static method _#new#tearOff() → mai::Statics
+ return new mai::Statics::•();
+}
+static method testNullableUninitializedNonFinalLocal() → void
+ ;
+static method testNonNullableUninitializedNonFinalLocal() → void
+ ;
+static method testNullableUninitializedFinalLocal() → void
+ ;
+static method testNonNullableUninitializedFinalLocal() → void
+ ;
+static method testNullableInitializedNonFinalLocal() → void
+ ;
+static method testNonNullableInitializedNonFinalLocal() → void
+ ;
+static method testNullableInitializedFinalLocal() → void
+ ;
+static method testNonNullableInitializedFinalLocal() → void
+ ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:_late_helper" as _la;
+
+static final field _la::_Cell a = new _la::_Cell::named("a");
+static final field _la::_Cell b = new _la::_Cell::named("b");
+static final field _la::_Cell c = new _la::_Cell::named("c");
+static final field _la::_Cell d = new _la::_Cell::named("d");
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..62953b9
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main.dart.weak.transformed.expect
@@ -0,0 +1,239 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+// Statics.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+// Statics.b = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+// lib.a = 42;
+// ^
+//
+// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+// lib.b = 42;
+// ^
+//
+import self as self;
+import "main_lib1.dart" as mai;
+import "dart:core" as core;
+import "main_lib2.dart" as mai2;
+
+import "org-dartlang-testcase:///main_lib1.dart";
+import "org-dartlang-testcase:///main_lib2.dart" as lib;
+
+static field mai::C c = new mai::C::•();
+static method main() → void {
+ self::testUninitializedNonFinalInstanceField();
+ self::testUninitializedFinalInstanceField();
+ self::testInitializedNonFinalInstanceField();
+ self::testInitializedFinalInstanceField();
+ mai::testNullableUninitializedNonFinalLocal();
+ mai::testNonNullableUninitializedNonFinalLocal();
+ mai::testNullableUninitializedFinalLocal();
+ mai::testNonNullableUninitializedFinalLocal();
+ mai::testNullableInitializedNonFinalLocal();
+ mai::testNonNullableInitializedNonFinalLocal();
+ mai::testNullableInitializedFinalLocal();
+ mai::testNonNullableInitializedFinalLocal();
+ self::testUninitializedNonFinalStaticField();
+ self::testUninitializedFinalStaticField();
+ self::testInitializedNonFinalStaticField();
+ self::testInitializedFinalStaticField();
+ self::testUninitializedNonFinalTopLevelField();
+ self::testUninitializedFinalTopLevelField();
+ self::testInitializedNonFinalTopLevelField();
+ self::testInitializedFinalTopLevelField();
+}
+static method testUninitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::a}{core::int});
+ self::c.{mai::C::a} = 42;
+ core::print(self::c.{mai::C::a}{core::int});
+}
+static method testUninitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::b}{core::int});
+ self::c.{mai::C::b} = 42;
+ core::print(self::c.{mai::C::b}{core::int});
+}
+static method testInitializedNonFinalInstanceField() → void {
+ core::print(self::c.{mai::C::c}{core::int});
+ self::c.{mai::C::c} = 42;
+ core::print(self::c.{mai::C::c}{core::int});
+}
+static method testInitializedFinalInstanceField() → void {
+ core::print(self::c.{mai::C::d}{core::int});
+}
+static method testUninitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
+ Statics.a = 42;
+ ^";
+ core::print(mai::Statics::a);
+}
+static method testUninitializedFinalStaticField() → void {
+ core::print(mai::Statics::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
+ Statics.b = 42;
+ ^";
+ core::print(mai::Statics::b);
+}
+static method testInitializedNonFinalStaticField() → void {
+ core::print(mai::Statics::c);
+ mai::Statics::c = 42;
+ core::print(mai::Statics::c);
+}
+static method testInitializedFinalStaticField() → void {
+ core::print(mai::Statics::d);
+}
+static method testUninitializedNonFinalTopLevelField() → void {
+ core::print(mai2::a);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
+ lib.a = 42;
+ ^";
+ core::print(mai2::a);
+}
+static method testUninitializedFinalTopLevelField() → void {
+ core::print(mai2::b);
+ invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
+ lib.b = 42;
+ ^";
+ core::print(mai2::b);
+}
+static method testInitializedNonFinalTopLevelField() → void {
+ core::print(mai2::c);
+ mai2::c = 42;
+ core::print(mai2::c);
+}
+static method testInitializedFinalTopLevelField() → void {
+ core::print(mai2::d);
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai;
+import "dart:core" as core;
+import "dart:_late_helper" as _la;
+import "dart:_internal" as _in;
+
+class C extends core::Object {
+ field core::int _#C#a = _in::createSentinel<core::int>();
+ field core::int _#C#b = _in::createSentinel<core::int>();
+ field core::int _#C#c = _in::createSentinel<core::int>();
+ field core::int _#C#d = _in::createSentinel<core::int>();
+ synthetic constructor •() → mai::C
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::C
+ return new mai::C::•();
+ get a() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#a}{core::int}, "a");
+ set a(core::int value) → void
+ this.{mai::C::_#C#a} = value;
+ get b() → core::int
+ return _la::_lateReadCheck<core::int>(this.{mai::C::_#C#b}{core::int}, "b");
+ set b(core::int value) → void {
+ _la::_lateWriteOnceCheck(this.{mai::C::_#C#b}{core::int}, "b");
+ this.{mai::C::_#C#b} = value;
+ }
+ get c() → core::int {
+ core::int value = this.{mai::C::_#C#c}{core::int};
+ if(_in::isSentinel(value))
+ value = this.{mai::C::_#C#c} = 1.{core::int::unary-}(){() → core::int};
+ return value;
+ }
+ set c(core::int value) → void
+ this.{mai::C::_#C#c} = value;
+ get d() → core::int {
+ core::int value = this.{mai::C::_#C#d}{core::int};
+ if(_in::isSentinel(value)) {
+ final core::int result = 1.{core::int::unary-}(){() → core::int};
+ _la::_lateInitializeOnceCheck(this.{mai::C::_#C#d}{core::int}, "d");
+ value = this.{mai::C::_#C#d} = result;
+ }
+ return value;
+ }
+}
+class Statics extends core::Object {
+ static final field _la::_Cell a = new _la::_Cell::named("a");
+ static final field _la::_Cell b = new _la::_Cell::named("b");
+ late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+ late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
+ synthetic constructor •() → mai::Statics
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → mai::Statics
+ return new mai::Statics::•();
+}
+static method testNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedNonFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::value} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNonNullableUninitializedFinalLocal() → void {
+ final _la::_Cell x = new _la::_Cell::named("x");
+ x.{_la::_Cell::finalLocalValue} = 42;
+ core::print(x.{_la::_Cell::readLocal}<core::int>(){() → core::int});
+}
+static method testNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::read}<core::int?>(){() → core::int?});
+ y.{_la::_InitializedCell::value} = 42;
+ core::print(y.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNonNullableInitializedNonFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+ x.{_la::_InitializedCell::value} = 42;
+ core::print(x.{_la::_InitializedCell::read}<core::int>(){() → core::int});
+}
+static method testNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int? => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+ final _la::_InitializedCell y = new _la::_InitializedCell::named("y", () → core::int? => null);
+ core::print(y.{_la::_InitializedCell::readFinal}<core::int?>(){() → core::int?});
+}
+static method testNonNullableInitializedFinalLocal() → void {
+ final _la::_InitializedCell x = new _la::_InitializedCell::named("x", () → core::int => 1.{core::int::unary-}(){() → core::int});
+ core::print(x.{_la::_InitializedCell::readFinal}<core::int>(){() → core::int});
+}
+
+library /*isNonNullableByDefault*/;
+import self as mai2;
+import "dart:_late_helper" as _la;
+import "dart:core" as core;
+
+static final field _la::_Cell a = new _la::_Cell::named("a");
+static final field _la::_Cell b = new _la::_Cell::named("b");
+late static field core::int c = 1.{core::int::unary-}(){() → core::int};
+late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
+
+
+Extra constant evaluation status:
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:8:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:9:22 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:15:23 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:16:29 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:44:17 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:56:16 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:63:23 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:71:22 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:7:14 -> DoubleConstant(-1.0)
+Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:8:20 -> DoubleConstant(-1.0)
+Extra constant evaluation: evaluated: 205, effectively constant: 10
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main_lib1.dart b/pkg/front_end/testcases/dart2js/late_from_dill/main_lib1.dart
new file mode 100644
index 0000000..7f668da
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main_lib1.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {
+ late int a;
+ late final int b;
+ late int c = -1;
+ late final int d = -1;
+}
+
+class Statics {
+ static late int a;
+ static late final int b;
+ static late int c = -1;
+ static late final int d = -1;
+}
+
+void testNullableUninitializedNonFinalLocal() {
+ late int? x;
+ x = 42;
+ print(x);
+}
+
+void testNonNullableUninitializedNonFinalLocal() {
+ late int x;
+ x = 42;
+ print(x);
+}
+
+void testNullableUninitializedFinalLocal() {
+ late final int? x;
+ x = 42;
+ print(x);
+}
+
+void testNonNullableUninitializedFinalLocal() {
+ late final int x;
+ x = 42;
+ print(x);
+}
+
+void testNullableInitializedNonFinalLocal() {
+ late int? x = -1;
+ print(x);
+ x = 42;
+ print(x);
+
+ late int? y = null;
+ print(y);
+ y = 42;
+ print(y);
+}
+
+void testNonNullableInitializedNonFinalLocal() {
+ late int x = -1;
+ print(x);
+ x = 42;
+ print(x);
+}
+
+void testNullableInitializedFinalLocal() {
+ late final int? x = -1;
+ print(x);
+
+ late final int? y = null;
+ print(y);
+}
+
+void testNonNullableInitializedFinalLocal() {
+ late final int x = -1;
+ print(x);
+}
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/main_lib2.dart b/pkg/front_end/testcases/dart2js/late_from_dill/main_lib2.dart
new file mode 100644
index 0000000..853ea39
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/main_lib2.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+late int a;
+late final int b;
+late int c = -1;
+late final int d = -1;
diff --git a/pkg/front_end/testcases/dart2js/late_from_dill/test.options b/pkg/front_end/testcases/dart2js/late_from_dill/test.options
new file mode 100644
index 0000000..207c58e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/late_from_dill/test.options
@@ -0,0 +1,2 @@
+main_lib1.dart
+main_lib2.dart
\ No newline at end of file
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index aaa0ee4..783f21a 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -219,6 +219,11 @@
if (!_hasTimeline) return;
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(name, 'name');
+ if (!_isDartStreamEnabled()) {
+ // Push a null onto the stack and return.
+ _stack.add(null);
+ return;
+ }
var block = new _AsyncBlock._(name, _taskId);
_stack.add(block);
// TODO(39115): Spurious error about collection literal ambiguity.
@@ -242,6 +247,10 @@
if (!_hasTimeline) return;
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(name, 'name');
+ if (!_isDartStreamEnabled()) {
+ // Stream is disabled.
+ return;
+ }
Map? instantArguments;
if (arguments != null) {
instantArguments = new Map.from(arguments);
@@ -269,6 +278,10 @@
}
// Pop top item off of stack.
var block = _stack.removeLast();
+ if (block == null) {
+ // Dart stream was disabled when start was called.
+ return;
+ }
block._finish(arguments);
}
@@ -288,7 +301,7 @@
final TimelineTask? _parent;
final String? _filterKey;
final int _taskId;
- final List<_AsyncBlock> _stack = [];
+ final List<_AsyncBlock?> _stack = [];
}
/// An asynchronous block of time on the timeline. This block can be kept
diff --git a/tools/VERSION b/tools/VERSION
index f1f0b56..f1fb2e6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 121
+PRERELEASE 122
PRERELEASE_PATCH 0
\ No newline at end of file