Version 2.18.0-274.0.dev
Merge commit 'bf19cfc8fe480308b1df8cdabecc5154298a935f' into 'dev'
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index cad822d..5cd9ec2 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -51,7 +51,7 @@
CompletionHandler(super.server, LspInitializationOptions options)
: suggestFromUnimportedLibraries = options.suggestFromUnimportedLibraries,
previewNotImportedCompletions = options.previewNotImportedCompletions {
- final budgetMs = options.notImportedCompletionBudgetMilliseconds;
+ final budgetMs = options.completionBudgetMilliseconds;
completionBudget = CompletionBudget(budgetMs != null
? Duration(milliseconds: budgetMs)
: CompletionBudget.defaultDuration);
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 6a1cc96..fd36e21 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -892,7 +892,7 @@
final bool closingLabels;
final bool outline;
final bool flutterOutline;
- final int? notImportedCompletionBudgetMilliseconds;
+ final int? completionBudgetMilliseconds;
LspInitializationOptions(dynamic options)
: onlyAnalyzeProjectsWithOpenFiles = options != null &&
@@ -908,8 +908,8 @@
closingLabels = options != null && options['closingLabels'] == true,
outline = options != null && options['outline'] == true,
flutterOutline = options != null && options['flutterOutline'] == true,
- notImportedCompletionBudgetMilliseconds = options != null
- ? options['notImportedCompletionBudgetMilliseconds'] as int?
+ completionBudgetMilliseconds = options != null
+ ? options['completionBudgetMilliseconds'] as int?
: null;
}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 44e901d..5a7c1e9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -1089,6 +1089,12 @@
}
super.visitForStatement(node);
}
+
+ @override
+ void visitFunctionExpression(FunctionExpression node) {
+ // Don't look inside function expressions as the presence of `await` inside
+ // a function expression does not mean the overall function is async.
+ }
}
class _HasReturnStatementVisitor extends RecursiveAstVisitor<void> {
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 6eb8824..86f2b06 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -36,7 +36,7 @@
'previewNotImportedCompletions': previewNotImportedCompletions,
// Default to a high budget for tests because everything is cold and
// may take longer to return.
- 'notImportedCompletionBudgetMilliseconds': 50000
+ 'completionBudgetMilliseconds': 50000
};
}
@@ -2305,7 +2305,7 @@
initializationOptions: {
...?defaultInitializationOptions,
// Set budget high to ensure it completes.
- 'notImportedCompletionBudgetMilliseconds': 100000,
+ 'completionBudgetMilliseconds': 100000,
},
workspaceCapabilities:
withApplyEditSupport(emptyWorkspaceClientCapabilities));
@@ -2330,7 +2330,7 @@
initializationOptions: {
...?defaultInitializationOptions,
// Set budget low to ensure we don't complete.
- 'notImportedCompletionBudgetMilliseconds': 0,
+ 'completionBudgetMilliseconds': 0,
},
workspaceCapabilities:
withApplyEditSupport(emptyWorkspaceClientCapabilities));
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index b6ae4c4..35cf422 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -2561,6 +2561,37 @@
''');
}
+ /// `await` in a nested function should not result in `await` at the call to
+ /// the new function.
+ Future<void> test_statements_hasAwait_functionExpression() async {
+ await indexTestUnit('''
+void g(Future<void> Function() func) {}
+void f() {
+// start
+ g(() async {
+ await null;
+ });
+// end
+}
+''');
+ _createRefactoringForStartEndComments();
+ // apply refactoring
+ return _assertSuccessfulRefactoring('''
+void g(Future<void> Function() func) {}
+void f() {
+// start
+ res();
+// end
+}
+
+void res() {
+ g(() async {
+ await null;
+ });
+}
+''');
+ }
+
Future<void> test_statements_hasAwait_voidReturnType() async {
await indexTestUnit('''
import 'dart:async';
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index ed10dc8..fbfd6cd 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -453,7 +453,7 @@
Object allocationNode,
MemberEntity allocationElement,
AbstractValue elementType,
- int length);
+ int? length);
/// Returns the element type of [value] if it represents a container value
/// at runtime. Returns [dynamicType] otherwise.
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
index 80bb03c..6eb60d8 100644
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ b/pkg/compiler/lib/src/inferrer/builder.dart
@@ -287,8 +287,7 @@
} else {
type = _types.nullType;
}
- _inferrer.setDefaultTypeOfParameter(local, type,
- isInstanceMember: _analyzedMember.isInstanceMember);
+ _inferrer.setDefaultTypeOfParameter(local, type);
}
}
diff --git a/pkg/compiler/lib/src/inferrer/engine.dart b/pkg/compiler/lib/src/inferrer/engine.dart
index 9e9a8d9..6cae1c6 100644
--- a/pkg/compiler/lib/src/inferrer/engine.dart
+++ b/pkg/compiler/lib/src/inferrer/engine.dart
@@ -33,6 +33,7 @@
import 'builder.dart';
import 'closure_tracer.dart';
import 'debug.dart' as debug;
+import 'engine_interfaces.dart' as interfaces;
import 'locals_handler.dart';
import 'list_tracer.dart';
import 'map_tracer.dart';
@@ -46,7 +47,7 @@
/// An inferencing engine that computes a call graph of [TypeInformation] nodes
/// by visiting the AST of the application, and then does the inferencing on the
/// graph.
-class InferrerEngine {
+class InferrerEngine implements interfaces.InferrerEngine {
/// A set of selector names that [List] implements, that we know return their
/// element type.
final Set<Selector> returnsListElementTypeSet = Set<Selector>.from(<Selector>[
@@ -61,13 +62,16 @@
]);
/// The [JClosedWorld] on which inference reasoning is based.
+ @override
final JsClosedWorld closedWorld;
final TypeSystem types;
final Map<ir.TreeNode, TypeInformation> concreteTypes = {};
final GlobalLocalsMap globalLocalsMap;
+ @override
final InferredDataBuilder inferredDataBuilder;
+ @override
final FunctionEntity mainElement;
final Map<Local, TypeInformation> _defaultTypeOfParameter = {};
@@ -101,12 +105,15 @@
ElementEnvironment get _elementEnvironment => closedWorld.elementEnvironment;
+ @override
AbstractValueDomain get abstractValueDomain =>
closedWorld.abstractValueDomain;
+ @override
CommonElements get commonElements => closedWorld.commonElements;
// TODO(johnniwinther): This should be part of [ClosedWorld] or
// [ClosureWorldRefiner].
+ @override
NoSuchMethodData get noSuchMethodData => closedWorld.noSuchMethodData;
InferrerEngine(
@@ -241,14 +248,17 @@
}
}
+ @override
bool returnsListElementType(Selector selector, AbstractValue mask) {
- return mask != null &&
- abstractValueDomain.isContainer(mask) &&
+ assert(mask != null);
+ return abstractValueDomain.isContainer(mask) &&
returnsListElementTypeSet.contains(selector);
}
+ @override
bool returnsMapValueType(Selector selector, AbstractValue mask) {
- return mask != null && abstractValueDomain.isMap(mask) && selector.isIndex;
+ assert(mask != null);
+ return abstractValueDomain.isMap(mask) && selector.isIndex;
}
void analyzeListAndEnqueue(ListTypeInformation info) {
@@ -813,8 +823,7 @@
/// mapping in `_defaultTypeOfParameter` already contains a type, it must be
/// a [PlaceholderTypeInformation], which will be replaced. All its uses are
/// updated.
- void setDefaultTypeOfParameter(Local parameter, TypeInformation type,
- {bool isInstanceMember}) {
+ void setDefaultTypeOfParameter(Local parameter, TypeInformation type) {
assert(
type != null, failedAt(parameter, "No default type for $parameter."));
TypeInformation existing = _defaultTypeOfParameter[parameter];
@@ -822,17 +831,7 @@
TypeInformation info = types.getInferredTypeOfParameter(parameter);
if (existing != null && existing is PlaceholderTypeInformation) {
// Replace references to [existing] to use [type] instead.
- if (isInstanceMember) {
- ParameterInputs inputs = info.inputs;
- inputs.replace(existing, type);
- } else {
- List<TypeInformation> inputs = info.inputs;
- for (int i = 0; i < inputs.length; i++) {
- if (inputs[i] == existing) {
- inputs[i] = type;
- }
- }
- }
+ info.inputs.replace(existing, type);
// Also forward all users.
type.addUsersOf(existing);
} else {
@@ -1290,8 +1289,13 @@
return ParameterTypeInformation.localFunction(
abstractValueDomain, memberTypeInformation, parameter, type, member);
} else if (member.isInstanceMember) {
- return ParameterTypeInformation.instanceMember(abstractValueDomain,
- memberTypeInformation, parameter, type, member, ParameterInputs());
+ return ParameterTypeInformation.instanceMember(
+ abstractValueDomain,
+ memberTypeInformation,
+ parameter,
+ type,
+ member,
+ ParameterInputs.instanceMember());
} else {
return ParameterTypeInformation.static(
abstractValueDomain, memberTypeInformation, parameter, type, member);
diff --git a/pkg/compiler/lib/src/inferrer/engine_interfaces.dart b/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
new file mode 100644
index 0000000..80c7d3e
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/engine_interfaces.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, 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 '../common/elements.dart';
+import '../elements/entities.dart';
+import '../js_backend/inferred_data.dart';
+import '../js_backend/no_such_method_registry_interfaces.dart';
+import '../universe/selector.dart';
+import '../world_interfaces.dart';
+import 'abstract_value_domain.dart';
+
+abstract class InferrerEngine {
+ AbstractValueDomain get abstractValueDomain;
+ JClosedWorld get closedWorld;
+ CommonElements get commonElements;
+ InferredDataBuilder get inferredDataBuilder;
+ FunctionEntity get mainElement;
+ NoSuchMethodData get noSuchMethodData;
+
+ bool returnsListElementType(Selector selector, AbstractValue mask);
+ bool returnsMapValueType(Selector selector, AbstractValue mask);
+}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index ea0f69f..8f28c04 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -39,7 +39,7 @@
/// changes.
abstract class TypeInformation {
Set<TypeInformation> users;
- var /* List|ParameterInputs */ _inputs;
+ ParameterInputs _inputs;
/// The type the inferrer has found for this [TypeInformation].
/// Initially empty.
@@ -51,7 +51,7 @@
/// The element this [TypeInformation] node belongs to.
MemberEntity get contextMember => context?.member;
- Iterable<TypeInformation> get inputs => _inputs;
+ ParameterInputs get inputs => _inputs;
/// We abandon inference in certain cases (complex cyclic flow, native
/// behaviours, etc.). In some case, we might resume inference in the
@@ -86,15 +86,15 @@
bool get isConcrete => false;
TypeInformation(this.type, this.context)
- : _inputs = <TypeInformation>[],
+ : _inputs = _BasicParameterInputs([]),
users = Setlet<TypeInformation>();
TypeInformation.noInputs(this.type, this.context)
- : _inputs = const <TypeInformation>[],
+ : _inputs = const _BasicParameterInputs([]),
users = Setlet<TypeInformation>();
TypeInformation.untracked(this.type)
- : _inputs = const <TypeInformation>[],
+ : _inputs = const _BasicParameterInputs([]),
users = const {},
context = null;
@@ -118,7 +118,7 @@
// The below is not a compile time constant to make it differentiable
// from other empty lists of [TypeInformation].
static final STOP_TRACKING_INPUTS_MARKER =
- List<TypeInformation>.filled(0, null);
+ _BasicParameterInputs(List.empty());
bool areInputsTracked() {
return inputs != STOP_TRACKING_INPUTS_MARKER;
@@ -220,8 +220,8 @@
/// Destroys information not needed after type inference.
void cleanup() {
- users = null;
- _inputs = null;
+ users = const {};
+ _inputs = const _BasicParameterInputs([]);
}
String toStructuredText(String indent) {
@@ -265,16 +265,50 @@
toString() => "Placeholder [$hashCode]";
}
+abstract class ParameterInputs implements Iterable<TypeInformation> {
+ factory ParameterInputs.instanceMember() => _InstanceMemberParameterInputs();
+ void add(TypeInformation input);
+ void remove(TypeInformation input);
+ void replace(TypeInformation old, TypeInformation replacement);
+}
+
+class _BasicParameterInputs extends IterableBase<TypeInformation>
+ implements ParameterInputs {
+ final List<TypeInformation> _baseList;
+
+ const _BasicParameterInputs(this._baseList);
+
+ @override
+ void replace(TypeInformation old, TypeInformation replacement) {
+ for (int i = 0; i < length; i++) {
+ if (_baseList[i] == old) {
+ _baseList[i] = replacement;
+ }
+ }
+ }
+
+ @override
+ void add(TypeInformation input) => _baseList.add(input);
+
+ @override
+ Iterator<TypeInformation> get iterator => _baseList.iterator;
+
+ @override
+ void remove(TypeInformation input) => _baseList.remove(input);
+}
+
/// Parameters of instance functions behave differently than other
/// elements because the inferrer may remove inputs. This happens
/// when the receiver of a dynamic call site can be refined
/// to a type where we know more about which instance method is being
/// called.
-class ParameterInputs extends IterableBase<TypeInformation> {
+class _InstanceMemberParameterInputs extends IterableBase<TypeInformation>
+ implements ParameterInputs {
final Map<TypeInformation, int> _inputs = Map<TypeInformation, int>();
+ @override
void remove(TypeInformation info) {
- int existing = _inputs[info];
+ final existing = _inputs[info];
if (existing == null) return;
if (existing == 1) {
_inputs.remove(info);
@@ -283,8 +317,9 @@
}
}
+ @override
void add(TypeInformation info) {
- int existing = _inputs[info];
+ final existing = _inputs[info];
if (existing == null) {
_inputs[info] = 1;
} else {
@@ -292,10 +327,11 @@
}
}
+ @override
void replace(TypeInformation old, TypeInformation replacement) {
- int existing = _inputs[old];
+ var existing = _inputs[old];
if (existing != null) {
- int other = _inputs[replacement];
+ final other = _inputs[replacement];
if (other != null) existing += other;
_inputs[replacement] = existing;
_inputs.remove(old);
@@ -383,13 +419,11 @@
/// This map contains the callers of [element]. It stores all unique call
/// sites to enable counting the global number of call sites of [element].
///
- /// A call site is either an AST [ast.Node], an [Element] (see uses of
- /// [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]) or an IR
- /// [ir.Node].
+ /// A call site is an [ir.Node].
///
/// The global information is summarized in [cleanup], after which [_callers]
/// is set to `null`.
- Map<MemberEntity, Setlet<Object>> _callers;
+ Map<MemberEntity, Setlet<ir.Node /*?*/ >> _callers;
MemberTypeInformation._internal(
AbstractValueDomain abstractValueDomain, this._member)
@@ -400,12 +434,12 @@
@override
String get debugName => '$member';
- void addCall(MemberEntity caller, Object node) {
- _callers ??= <MemberEntity, Setlet<Object>>{};
+ void addCall(MemberEntity caller, ir.Node /*?*/ node) {
+ _callers ??= <MemberEntity, Setlet<ir.Node /*?*/ >>{};
_callers.putIfAbsent(caller, () => Setlet()).add(node);
}
- void removeCall(MemberEntity caller, Object node) {
+ void removeCall(MemberEntity caller, ir.Node /*?*/ node) {
if (_callers == null) return;
Setlet calls = _callers[caller];
if (calls == null) return;
@@ -919,7 +953,7 @@
forIn,
}
-bool validCallType(CallType callType, Object call, Selector selector) {
+bool validCallType(CallType callType, ir.Node /*?*/ call, Selector selector) {
switch (callType) {
case CallType.access:
return call is ir.Node;
@@ -941,7 +975,7 @@
/// and [selector] and [receiver] fields for dynamic calls.
abstract class CallSiteTypeInformation extends TypeInformation
with ApplyableTypeInformation {
- final Object _call;
+ final ir.Node /*?*/ _call;
final MemberEntity caller;
final Selector selector;
final ArgumentsTypes arguments;
@@ -977,7 +1011,7 @@
StaticCallSiteTypeInformation(
AbstractValueDomain abstractValueDomain,
MemberTypeInformation context,
- Object call,
+ ir.Node /*?*/ call,
MemberEntity enclosing,
this.calledElement,
Selector selector,
@@ -1073,7 +1107,7 @@
IndirectDynamicCallSiteTypeInformation(
AbstractValueDomain abstractValueDomain,
MemberTypeInformation context,
- Object call,
+ ir.Node /*?*/ call,
this.dynamicCall,
MemberEntity enclosing,
Selector selector,
@@ -1157,7 +1191,8 @@
}
}
-class DynamicCallSiteTypeInformation<T> extends CallSiteTypeInformation {
+class DynamicCallSiteTypeInformation<T extends ir.Node>
+ extends CallSiteTypeInformation {
final CallType _callType;
final TypeInformation receiver;
final AbstractValue mask;
@@ -1407,9 +1442,11 @@
} else {
result = inferrer.types
.joinTypeMasks(_concreteTargets.map((MemberEntity element) {
- if (inferrer.returnsListElementType(selector, typeMask)) {
+ if (typeMask != null &&
+ inferrer.returnsListElementType(selector, typeMask)) {
return abstractValueDomain.getContainerElementType(receiver.type);
- } else if (inferrer.returnsMapValueType(selector, typeMask)) {
+ } else if (typeMask != null &&
+ inferrer.returnsMapValueType(selector, typeMask)) {
if (abstractValueDomain.isDictionary(typeMask)) {
AbstractValue arg = arguments.positional[0].type;
ConstantValue value = abstractValueDomain.getPrimitiveValue(arg);
@@ -1513,7 +1550,7 @@
ClosureCallSiteTypeInformation(
AbstractValueDomain abstractValueDomain,
MemberTypeInformation context,
- Object call,
+ ir.Node /*?*/ call,
MemberEntity enclosing,
Selector selector,
this.closure,
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 88afdee..26e081e 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -11,6 +11,7 @@
import '../inferrer/types.dart' show GlobalTypeInferenceResults;
import '../kernel/no_such_method_resolver.dart';
import '../serialization/serialization.dart';
+import 'no_such_method_registry_interfaces.dart' as interfaces;
/// [NoSuchMethodRegistry] and [NoSuchMethodData] categorizes `noSuchMethod`
/// implementations.
@@ -169,7 +170,7 @@
///
/// Post inference collected category `D` methods are into subcategories `D1`
/// and `D2`.
-class NoSuchMethodData {
+class NoSuchMethodData implements interfaces.NoSuchMethodData {
/// Tag used for identifying serialized [NoSuchMethodData] objects in a
/// debugging data stream.
static const String tag = 'no-such-method-data';
@@ -266,6 +267,7 @@
/// Returns [true] if the given element is a complex [noSuchMethod]
/// implementation. An implementation is complex if it falls into
/// category D, as described above.
+ @override
bool isComplex(FunctionEntity element) {
assert(element.name == Identifiers.noSuchMethod_);
return _otherImpls.contains(element);
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry_interfaces.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry_interfaces.dart
new file mode 100644
index 0000000..30e7dc3
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry_interfaces.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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 '../elements/entities.dart';
+
+abstract class NoSuchMethodData {
+ bool isComplex(FunctionEntity element);
+}
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index afdce46..6d039aa 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -485,14 +485,14 @@
@override
Iterable<MemberEntity> locateMembersInDomain(Selector selector,
- AbstractValue receiver, AbstractValueDomain abstractValueDomain) {
+ AbstractValue /*?*/ receiver, AbstractValueDomain abstractValueDomain) {
_ensureFunctionSet();
return _allFunctions.filter(selector, receiver, abstractValueDomain);
}
@override
Iterable<MemberEntity> locateMembers(
- Selector selector, AbstractValue receiver) {
+ Selector selector, AbstractValue /*?*/ receiver) {
return locateMembersInDomain(selector, receiver, abstractValueDomain);
}
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 2c723a3..17b39ec 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -40,7 +40,7 @@
/// noSuchMethod handlers that are potential targets indirectly through the
/// noSuchMethod mechanism.
Iterable<MemberEntity> filter(
- Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+ Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
return query(selector, receiver, domain).functions;
}
@@ -66,7 +66,7 @@
/// [selector] on a receiver constrained by [constraint] including
/// 'noSuchMethod' methods where applicable.
FunctionSetQuery query(
- Selector selector, AbstractValue receiver, AbstractValueDomain domain) {
+ Selector selector, AbstractValue? receiver, AbstractValueDomain domain) {
String name = selector.name;
SelectorMask selectorMask = _createSelectorMask(selector, receiver, domain);
SelectorMask noSuchMethodMask =
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 01cd61c..884cef6 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -43,17 +43,21 @@
BackendUsage get backendUsage;
+ @override
NativeData get nativeData;
InterceptorData get interceptorData;
JElementEnvironment get elementEnvironment;
+ @override
DartTypes get dartTypes;
+ @override
JCommonElements get commonElements;
/// Returns the [AbstractValueDomain] used in the global type inference.
+ @override
AbstractValueDomain get abstractValueDomain;
RuntimeTypesNeed get rtiNeed;
@@ -68,8 +72,10 @@
/// `extractTypeArguments` function.
Set<ClassEntity> get extractTypeArgumentsInterfacesNewRti;
+ @override
ClassHierarchy get classHierarchy;
+ @override
AnnotationsData get annotationsData;
ClosureData get closureDataLookup;
diff --git a/pkg/compiler/lib/src/world_interfaces.dart b/pkg/compiler/lib/src/world_interfaces.dart
index 86535bf..84c1a9d 100644
--- a/pkg/compiler/lib/src/world_interfaces.dart
+++ b/pkg/compiler/lib/src/world_interfaces.dart
@@ -2,16 +2,27 @@
// 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 'common/elements.dart';
import 'elements/entities.dart';
+import 'elements/types.dart';
import 'inferrer/abstract_value_domain.dart';
+import 'js_backend/annotations.dart';
+import 'js_backend/native_data.dart';
+import 'universe/class_hierarchy.dart';
import 'universe/selector.dart';
/// Common superinterface for [OpenWorld] and [JClosedWorld].
abstract class World {}
abstract class JClosedWorld implements World {
- bool includesClosureCall(Selector selector, AbstractValue receiver);
+ AbstractValueDomain get abstractValueDomain;
+ JCommonElements get commonElements;
+ ClassHierarchy get classHierarchy;
+ DartTypes get dartTypes;
+ NativeData get nativeData;
+ AnnotationsData get annotationsData;
+ bool includesClosureCall(Selector selector, AbstractValue? receiver);
Iterable<MemberEntity> locateMembers(
- Selector selector, AbstractValue receiver);
+ Selector selector, AbstractValue? receiver);
bool fieldNeverChanges(MemberEntity element);
}
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index 5d8fd47..107ef15 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -34,9 +34,7 @@
"Dynamic invocation of '[]'.": 2
},
"pkg/compiler/lib/src/inferrer/type_graph_nodes.dart": {
- "Dynamic access of 'type'.": 4,
- "Dynamic invocation of 'add'.": 1,
- "Dynamic invocation of 'remove'.": 1
+ "Dynamic access of 'type'.": 4
},
"pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart": {
"Dynamic access of 'forwardTo'.": 1,
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index 2d8e15c..043138d 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -15,8 +15,9 @@
/// {@category Core}
library dart.developer;
-import "dart:_internal" show checkNotNullable;
+import 'dart:_internal' show checkNotNullable;
import 'dart:async';
+import 'dart:collection';
import 'dart:convert';
import 'dart:isolate' show Isolate, RawReceivePort, SendPort;
diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart
index f238ae8..54bfd25 100644
--- a/sdk/lib/developer/profiler.dart
+++ b/sdk/lib/developer/profiler.dart
@@ -109,6 +109,9 @@
}
class Metrics {
+ /// The current set of registered [Metric]s.
+ static UnmodifiableMapView<String, Metric> get current =>
+ UnmodifiableMapView<String, Metric>(_metrics);
static final Map<String, Metric> _metrics = new Map<String, Metric>();
/// Register [Metric]s to make them visible to Observatory.
diff --git a/tests/lib/developer/metrics_test.dart b/tests/lib/developer/metrics_test.dart
index c836e96..9e5f80a 100644
--- a/tests/lib/developer/metrics_test.dart
+++ b/tests/lib/developer/metrics_test.dart
@@ -93,6 +93,8 @@
Metrics.register(counter);
var counter3 = new Counter('a.b.c.d', '');
Metrics.register(counter3);
+ Expect.isTrue(Metrics.current.containsKey('a.b.c.d'));
+ Expect.isTrue(Metrics.current.containsKey('a.b.c'));
}
testBadName() {
diff --git a/tests/lib_2/developer/metrics_test.dart b/tests/lib_2/developer/metrics_test.dart
index e91d3c2..8c529ea 100644
--- a/tests/lib_2/developer/metrics_test.dart
+++ b/tests/lib_2/developer/metrics_test.dart
@@ -95,6 +95,8 @@
Metrics.register(counter);
var counter3 = new Counter('a.b.c.d', '');
Metrics.register(counter3);
+ Expect.isTrue(Metrics.current.containsKey('a.b.c.d'));
+ Expect.isTrue(Metrics.current.containsKey('a.b.c'));
}
testBadName() {
diff --git a/tools/VERSION b/tools/VERSION
index e0bb2d6..2c1d3fb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 273
+PRERELEASE 274
PRERELEASE_PATCH 0
\ No newline at end of file