Version 2.18.0-39.0.dev
Merge commit 'f26c0e205654e1a97d1a7fc0b048b2100088bebf' into 'dev'
diff --git a/compile_output.txt b/compile_output.txt
deleted file mode 100644
index c3420dd..0000000
--- a/compile_output.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Info: The --categories flag is deprecated, see the usage for details.
-Info: Compiling with sound null safety
-Error: Error when reading 'benchmarks-internal/DeltaBlueBase/dart2/deltablue.dart': Error reading 'benchmarks-internal/DeltaBlueBase/dart2/deltablue.dart' (No such file or directory)
-Error: No 'main' method found.
-Error: Compilation failed.
-real 1.14
-user 0.59
-sys 0.84
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
index 4a20a40..57b3a31 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
@@ -179,7 +179,7 @@
StringLiteral(_getExtensionMemberName(node)),
ListLiteral(function.positionalParameters
.sublist(1)
- .map((argument) => VariableGet(argument))
+ .map<Expression>((argument) => VariableGet(argument))
.toList())
], types: [
function.returnType
@@ -294,8 +294,8 @@
}
// Lower arguments in other kinds of Lists.
- var callUncheckedArguments;
- var entryType;
+ List<Expression> callUncheckedArguments;
+ DartType entryType;
if (argumentsList is ListLiteral) {
if (argumentsList.expressions.length >= callUncheckedTargets.length) {
return node;
@@ -309,7 +309,7 @@
return node;
}
callUncheckedArguments = argumentsListConstant.entries
- .map((constant) => ConstantExpression(
+ .map<Expression>((constant) => ConstantExpression(
constant, constant.getType(_staticTypeContext)))
.toList();
entryType = argumentsListConstant.typeArgument;
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 8f6c48b..8c638be 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -6,30 +6,15 @@
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/domain_abstract.dart';
-import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
import 'package:analysis_server/src/handler/legacy/completion_get_suggestion_details.dart';
import 'package:analysis_server/src/handler/legacy/completion_get_suggestion_details2.dart';
-import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/fuzzy_filter_sort.dart';
-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
-import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
-import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
-import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analysis_server/src/handler/legacy/completion_get_suggestions.dart';
+import 'package:analysis_server/src/handler/legacy/completion_get_suggestions2.dart';
+import 'package:analysis_server/src/handler/legacy/completion_set_subscriptions.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/util/file_paths.dart' as file_paths;
-import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:collection/collection.dart';
/// Instances of the class [CompletionDomainHandler] implement a
/// [RequestHandler] that handles requests in the completion domain.
@@ -37,223 +22,6 @@
/// Initialize a new request handler for the given [server].
CompletionDomainHandler(super.server);
- /// Compute completion results for the given request and append them to the
- /// stream. Clients should not call this method directly as it is
- /// automatically called when a client listens to the stream returned by
- /// [results]. Subclasses should override this method, append at least one
- /// result to the [controller], and close the controller stream once complete.
- Future<List<CompletionSuggestionBuilder>> computeSuggestions({
- required CompletionBudget budget,
- required OperationPerformanceImpl performance,
- required DartCompletionRequest request,
- Set<ElementKind>? includedElementKinds,
- Set<String>? includedElementNames,
- List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
- NotImportedSuggestions? notImportedSuggestions,
- }) async {
- //
- // Allow plugins to start computing fixes.
- //
- var requestToPlugins = performance.run('askPlugins', (_) {
- return _sendRequestToPlugins(request);
- });
-
- //
- // Compute completions generated by server.
- //
- var suggestions = <CompletionSuggestionBuilder>[];
- await performance.runAsync('computeSuggestions', (performance) async {
- var manager = DartCompletionManager(
- budget: budget,
- includedElementKinds: includedElementKinds,
- includedElementNames: includedElementNames,
- includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
- notImportedSuggestions: notImportedSuggestions,
- );
-
- suggestions.addAll(
- await manager.computeSuggestions(request, performance),
- );
- });
- // TODO (danrubel) if request is obsolete (processAnalysisRequest returns
- // false) then send empty results
-
- //
- // Add the completions produced by plugins to the server-generated list.
- //
- if (requestToPlugins != null) {
- await performance.runAsync('waitForPlugins', (_) async {
- await _addPluginSuggestions(budget, requestToPlugins, suggestions);
- });
- }
-
- return suggestions;
- }
-
- /// Return the suggestions that should be presented in the YAML [file] at the
- /// given [offset].
- YamlCompletionResults computeYamlSuggestions(String file, int offset) {
- var provider = server.resourceProvider;
- var pathContext = provider.pathContext;
- if (file_paths.isAnalysisOptionsYaml(pathContext, file)) {
- var generator = AnalysisOptionsGenerator(provider);
- return generator.getSuggestions(file, offset);
- } else if (file_paths.isFixDataYaml(pathContext, file)) {
- var generator = FixDataGenerator(provider);
- return generator.getSuggestions(file, offset);
- } else if (file_paths.isPubspecYaml(pathContext, file)) {
- var generator = PubspecGenerator(provider, server.pubPackageService);
- return generator.getSuggestions(file, offset);
- }
- return const YamlCompletionResults.empty();
- }
-
- /// Implement the 'completion.getSuggestions2' request.
- void getSuggestions2(Request request) async {
- var params = CompletionGetSuggestions2Params.fromRequest(request);
- var file = params.file;
- var offset = params.offset;
-
- var timeoutMilliseconds = params.timeout;
- var budget = CompletionBudget(
- timeoutMilliseconds != null
- ? Duration(milliseconds: timeoutMilliseconds)
- : server.completionState.budgetDuration,
- );
-
- var provider = server.resourceProvider;
- var pathContext = provider.pathContext;
-
- if (file.endsWith('.yaml')) {
- final suggestions = computeYamlSuggestions(file, offset);
- server.sendResponse(
- CompletionGetSuggestions2Result(
- suggestions.replacementOffset,
- suggestions.replacementLength,
- suggestions.suggestions,
- false,
- ).toResponse(request.id),
- );
- return;
- }
-
- if (!file_paths.isDart(pathContext, file)) {
- server.sendResponse(
- CompletionGetSuggestions2Result(offset, 0, [], false)
- .toResponse(request.id),
- );
- return;
- }
-
- var performance = OperationPerformanceImpl('<root>');
- performance.runAsync(
- 'request',
- (performance) async {
- var resolvedUnit = await performance.runAsync(
- 'resolveForCompletion',
- (performance) {
- return server.resolveForCompletion(
- path: file,
- offset: offset,
- performance: performance,
- );
- },
- );
- if (resolvedUnit == null) {
- server.sendResponse(Response.fileNotAnalyzed(request, file));
- return;
- }
-
- if (offset < 0 || offset > resolvedUnit.content.length) {
- server.sendResponse(Response.invalidParameter(
- request,
- 'params.offset',
- 'Expected offset between 0 and source length inclusive,'
- ' but found $offset'));
- return;
- }
-
- final completionPerformance = CompletionPerformance(
- operation: performance,
- path: file,
- content: resolvedUnit.content,
- offset: offset,
- );
- server.completionState.performanceList.add(completionPerformance);
-
- var analysisSession = resolvedUnit.analysisSession;
- var enclosingNode =
- resolvedUnit.resolvedNodes.lastOrNull ?? resolvedUnit.parsedUnit;
-
- var completionRequest = DartCompletionRequest(
- analysisSession: analysisSession,
- filePath: resolvedUnit.path,
- fileContent: resolvedUnit.content,
- unitElement: resolvedUnit.unitElement,
- enclosingNode: enclosingNode,
- offset: offset,
- dartdocDirectiveInfo:
- server.getDartdocDirectiveInfoForSession(analysisSession),
- documentationCache:
- server.getDocumentationCacheForSession(analysisSession),
- );
- setNewRequest(completionRequest);
-
- var notImportedSuggestions = NotImportedSuggestions();
- var suggestionBuilders = <CompletionSuggestionBuilder>[];
- try {
- suggestionBuilders = await computeSuggestions(
- budget: budget,
- performance: performance,
- request: completionRequest,
- notImportedSuggestions: notImportedSuggestions,
- );
- } on AbortCompletion {
- return server.sendResponse(
- CompletionGetSuggestions2Result(
- completionRequest.replacementOffset,
- completionRequest.replacementLength,
- [],
- true,
- ).toResponse(request.id),
- );
- }
-
- performance.run('filter', (performance) {
- performance.getDataInt('count').add(suggestionBuilders.length);
- suggestionBuilders = fuzzyFilterSort(
- pattern: completionRequest.targetPrefix,
- suggestions: suggestionBuilders,
- );
- performance.getDataInt('matchCount').add(suggestionBuilders.length);
- });
-
- var lengthRestricted =
- suggestionBuilders.take(params.maxResults).toList();
- completionPerformance.computedSuggestionCount =
- suggestionBuilders.length;
- completionPerformance.transmittedSuggestionCount =
- lengthRestricted.length;
-
- var suggestions = lengthRestricted.map((e) => e.build()).toList();
-
- var isIncomplete = notImportedSuggestions.isIncomplete ||
- lengthRestricted.length < suggestionBuilders.length;
-
- performance.run('sendResponse', (_) {
- server.sendResponse(
- CompletionGetSuggestions2Result(
- completionRequest.replacementOffset,
- completionRequest.replacementLength,
- suggestions,
- isIncomplete,
- ).toResponse(request.id),
- );
- });
- },
- );
- }
-
@override
Response? handleRequest(
Request request, CancellationToken cancellationToken) {
@@ -279,13 +47,17 @@
.handle();
return Response.DELAYED_RESPONSE;
} else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
- processRequest(request);
+ CompletionGetSuggestionsHandler(server, request, cancellationToken)
+ .handle();
return Response.DELAYED_RESPONSE;
} else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS2) {
- getSuggestions2(request);
+ CompletionGetSuggestions2Handler(server, request, cancellationToken)
+ .handle();
return Response.DELAYED_RESPONSE;
} else if (requestName == COMPLETION_REQUEST_SET_SUBSCRIPTIONS) {
- return setSubscriptions(request);
+ CompletionSetSubscriptionsHandler(server, request, cancellationToken)
+ .handle();
+ return Response.DELAYED_RESPONSE;
}
return null;
}, (exception, stackTrace) {
@@ -296,330 +68,4 @@
stackTrace));
});
}
-
- void ifMatchesRequestClear(DartCompletionRequest request) {
- if (server.completionState.currentRequest == request) {
- server.completionState.currentRequest = null;
- }
- }
-
- /// Process a `completion.getSuggestions` request.
- Future<void> processRequest(Request request) async {
- var budget = CompletionBudget(server.completionState.budgetDuration);
-
- // extract and validate params
- var params = CompletionGetSuggestionsParams.fromRequest(request);
- var file = params.file;
- var offset = params.offset;
-
- if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
- return;
- }
-
- var performance = OperationPerformanceImpl('<root>');
- performance.runAsync(
- 'request',
- (performance) async {
- if (file.endsWith('.yaml')) {
- // Return the response without results.
- var completionId =
- (server.completionState.nextCompletionId++).toString();
- server.sendResponse(CompletionGetSuggestionsResult(completionId)
- .toResponse(request.id));
- // Send a notification with results.
- final suggestions = computeYamlSuggestions(file, offset);
- sendCompletionNotification(
- completionId,
- suggestions.replacementOffset,
- suggestions.replacementLength,
- suggestions.suggestions,
- null,
- null,
- null,
- null,
- );
- return;
- } else if (!file.endsWith('.dart')) {
- // Return the response without results.
- var completionId =
- (server.completionState.nextCompletionId++).toString();
- server.sendResponse(CompletionGetSuggestionsResult(completionId)
- .toResponse(request.id));
- // Send a notification with results.
- sendCompletionNotification(
- completionId, offset, 0, [], null, null, null, null);
- return;
- }
-
- var resolvedUnit = await server.getResolvedUnit(file);
- if (resolvedUnit == null) {
- server.sendResponse(Response.fileNotAnalyzed(request, file));
- return;
- }
-
- server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
-
- if (offset < 0 || offset > resolvedUnit.content.length) {
- server.sendResponse(Response.invalidParameter(
- request,
- 'params.offset',
- 'Expected offset between 0 and source length inclusive,'
- ' but found $offset'));
- return;
- }
-
- final completionPerformance = CompletionPerformance(
- operation: performance,
- path: file,
- content: resolvedUnit.content,
- offset: offset,
- );
- server.completionState.performanceList.add(completionPerformance);
-
- var declarationsTracker = server.declarationsTracker;
- if (declarationsTracker == null) {
- server.sendResponse(Response.unsupportedFeature(
- request.id, 'Completion is not enabled.'));
- return;
- }
-
- var completionRequest = DartCompletionRequest.forResolvedUnit(
- resolvedUnit: resolvedUnit,
- offset: offset,
- dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
- resolvedUnit,
- ),
- documentationCache: server.getDocumentationCacheFor(resolvedUnit),
- );
-
- var completionId =
- (server.completionState.nextCompletionId++).toString();
-
- setNewRequest(completionRequest);
-
- // initial response without results
- server.sendResponse(CompletionGetSuggestionsResult(completionId)
- .toResponse(request.id));
-
- // If the client opted into using available suggestion sets,
- // create the kinds set, so signal the completion manager about opt-in.
- Set<ElementKind>? includedElementKinds;
- Set<String>? includedElementNames;
- List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
- if (server.completionState.subscriptions
- .contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
- includedElementKinds = <ElementKind>{};
- includedElementNames = <String>{};
- includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
- }
-
- // Compute suggestions in the background
- try {
- var suggestionBuilders = <CompletionSuggestionBuilder>[];
- try {
- suggestionBuilders = await computeSuggestions(
- budget: budget,
- performance: performance,
- request: completionRequest,
- includedElementKinds: includedElementKinds,
- includedElementNames: includedElementNames,
- includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
- );
- } on AbortCompletion {
- // Continue with empty suggestions list.
- }
- String? libraryFile;
- var includedSuggestionSets = <IncludedSuggestionSet>[];
- if (includedElementKinds != null && includedElementNames != null) {
- libraryFile = resolvedUnit.libraryElement.source.fullName;
- server.sendNotification(
- createExistingImportsNotification(resolvedUnit),
- );
- computeIncludedSetList(
- declarationsTracker,
- completionRequest,
- includedSuggestionSets,
- includedElementNames,
- );
- }
-
- const SEND_NOTIFICATION_TAG = 'send notification';
- performance.run(SEND_NOTIFICATION_TAG, (_) {
- sendCompletionNotification(
- completionId,
- completionRequest.replacementOffset,
- completionRequest.replacementLength,
- suggestionBuilders.map((e) => e.build()).toList(),
- libraryFile,
- includedSuggestionSets,
- includedElementKinds?.toList(),
- includedSuggestionRelevanceTags,
- );
- });
-
- completionPerformance.computedSuggestionCount =
- suggestionBuilders.length;
- completionPerformance.transmittedSuggestionCount =
- suggestionBuilders.length;
- } finally {
- ifMatchesRequestClear(completionRequest);
- }
- },
- );
- }
-
- /// Send completion notification results.
- void sendCompletionNotification(
- String completionId,
- int replacementOffset,
- int replacementLength,
- List<CompletionSuggestion> results,
- String? libraryFile,
- List<IncludedSuggestionSet>? includedSuggestionSets,
- List<ElementKind>? includedElementKinds,
- List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
- ) {
- server.sendNotification(
- CompletionResultsParams(
- completionId,
- replacementOffset,
- replacementLength,
- results,
- true,
- libraryFile: libraryFile,
- includedSuggestionSets: includedSuggestionSets,
- includedElementKinds: includedElementKinds,
- includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
- ).toNotification(),
- );
- }
-
- void setNewRequest(DartCompletionRequest request) {
- _abortCurrentRequest();
- server.completionState.currentRequest = request;
- }
-
- /// Implement the 'completion.setSubscriptions' request.
- Response setSubscriptions(Request request) {
- var params = CompletionSetSubscriptionsParams.fromRequest(request);
-
- var subscriptions = server.completionState.subscriptions;
- subscriptions.clear();
- subscriptions.addAll(params.subscriptions);
-
- var data = server.declarationsTrackerData;
- if (data != null) {
- if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
- var soFarLibraries = data.startListening((change) {
- server.sendNotification(
- createCompletionAvailableSuggestionsNotification(
- change.changed,
- change.removed,
- ),
- );
- });
- server.sendNotification(
- createCompletionAvailableSuggestionsNotification(
- soFarLibraries,
- [],
- ),
- );
- } else {
- data.stopListening();
- }
- }
- return CompletionSetSubscriptionsResult().toResponse(request.id);
- }
-
- /// Abort the current completion request, if any.
- void _abortCurrentRequest() {
- var currentRequest = server.completionState.currentRequest;
- if (currentRequest != null) {
- currentRequest.abort();
- server.completionState.currentRequest = null;
- }
- }
-
- /// Add the completions produced by plugins to the server-generated list.
- Future<void> _addPluginSuggestions(
- CompletionBudget budget,
- _RequestToPlugins requestToPlugins,
- List<CompletionSuggestionBuilder> suggestionBuilders,
- ) async {
- var responses = await waitForResponses(
- requestToPlugins.futures,
- requestParameters: requestToPlugins.parameters,
- timeout: budget.left,
- );
- for (var response in responses) {
- var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
- if (result.results.isNotEmpty) {
- var completionRequest = requestToPlugins.completionRequest;
- if (completionRequest.replacementOffset != result.replacementOffset &&
- completionRequest.replacementLength != result.replacementLength) {
- server.instrumentationService
- .logError('Plugin completion-results dropped due to conflicting'
- ' replacement offset/length: ${result.toJson()}');
- continue;
- }
- suggestionBuilders.addAll(
- result.results.map(
- (suggestion) => ValueCompletionSuggestionBuilder(suggestion),
- ),
- );
- }
- }
- }
-
- /// Send the completion request to plugins, so that they work in other
- /// isolates in parallel with the server isolate.
- _RequestToPlugins? _sendRequestToPlugins(
- DartCompletionRequest completionRequest,
- ) {
- var pluginRequestParameters = plugin.CompletionGetSuggestionsParams(
- completionRequest.path,
- completionRequest.offset,
- );
-
- return _RequestToPlugins(
- completionRequest: completionRequest,
- parameters: pluginRequestParameters,
- futures: server.pluginManager.broadcastRequest(
- pluginRequestParameters,
- contextRoot: completionRequest.analysisContext.contextRoot,
- ),
- );
- }
-}
-
-/// The result of computing suggestions for code completion.
-class CompletionResult {
- /// The length of the text to be replaced if the remainder of the identifier
- /// containing the cursor is to be replaced when the suggestion is applied
- /// (that is, the number of characters in the existing identifier).
- final int replacementLength;
-
- /// The offset of the start of the text to be replaced. This will be different
- /// than the offset used to request the completion suggestions if there was a
- /// portion of an identifier before the original offset. In particular, the
- /// replacementOffset will be the offset of the beginning of said identifier.
- final int replacementOffset;
-
- /// The suggested completions.
- final List<CompletionSuggestion> suggestions;
-
- CompletionResult(
- this.replacementOffset, this.replacementLength, this.suggestions);
-}
-
-class _RequestToPlugins {
- final DartCompletionRequest completionRequest;
- final plugin.CompletionGetSuggestionsParams parameters;
- final Map<PluginInfo, Future<plugin.Response>> futures;
-
- _RequestToPlugins({
- required this.completionRequest,
- required this.parameters,
- required this.futures,
- });
}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions.dart
new file mode 100644
index 0000000..459c089
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions.dart
@@ -0,0 +1,195 @@
+// 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 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/handler/legacy/completion_get_suggestions2.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+
+/// The handler for the `completion.getSuggestions` request.
+class CompletionGetSuggestionsHandler extends CompletionGetSuggestions2Handler {
+ /// Initialize a newly created handler to be able to service requests for the
+ /// [server].
+ CompletionGetSuggestionsHandler(
+ super.server, super.request, super.cancellationToken);
+
+ @override
+ Future<void> handle() async {
+ var budget = CompletionBudget(server.completionState.budgetDuration);
+
+ // extract and validate params
+ var params = CompletionGetSuggestionsParams.fromRequest(request);
+ var file = params.file;
+ var offset = params.offset;
+
+ if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+ return;
+ }
+
+ var performance = OperationPerformanceImpl('<root>');
+ performance.runAsync(
+ 'request',
+ (performance) async {
+ if (file.endsWith('.yaml')) {
+ // Return the response without results.
+ var completionId =
+ (server.completionState.nextCompletionId++).toString();
+ server.sendResponse(CompletionGetSuggestionsResult(completionId)
+ .toResponse(request.id));
+ // Send a notification with results.
+ final suggestions = computeYamlSuggestions(file, offset);
+ sendCompletionNotification(
+ completionId,
+ suggestions.replacementOffset,
+ suggestions.replacementLength,
+ suggestions.suggestions,
+ null,
+ null,
+ null,
+ null,
+ );
+ return;
+ } else if (!file.endsWith('.dart')) {
+ // Return the response without results.
+ var completionId =
+ (server.completionState.nextCompletionId++).toString();
+ server.sendResponse(CompletionGetSuggestionsResult(completionId)
+ .toResponse(request.id));
+ // Send a notification with results.
+ sendCompletionNotification(
+ completionId, offset, 0, [], null, null, null, null);
+ return;
+ }
+
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit == null) {
+ server.sendResponse(Response.fileNotAnalyzed(request, file));
+ return;
+ }
+
+ server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
+
+ if (offset < 0 || offset > resolvedUnit.content.length) {
+ server.sendResponse(Response.invalidParameter(
+ request,
+ 'params.offset',
+ 'Expected offset between 0 and source length inclusive,'
+ ' but found $offset'));
+ return;
+ }
+
+ final completionPerformance = CompletionPerformance(
+ operation: performance,
+ path: file,
+ content: resolvedUnit.content,
+ offset: offset,
+ );
+ server.completionState.performanceList.add(completionPerformance);
+
+ var declarationsTracker = server.declarationsTracker;
+ if (declarationsTracker == null) {
+ server.sendResponse(Response.unsupportedFeature(
+ request.id, 'Completion is not enabled.'));
+ return;
+ }
+
+ var completionRequest = DartCompletionRequest.forResolvedUnit(
+ resolvedUnit: resolvedUnit,
+ offset: offset,
+ dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
+ resolvedUnit,
+ ),
+ documentationCache: server.getDocumentationCacheFor(resolvedUnit),
+ );
+
+ var completionId =
+ (server.completionState.nextCompletionId++).toString();
+
+ setNewRequest(completionRequest);
+
+ // initial response without results
+ server.sendResponse(CompletionGetSuggestionsResult(completionId)
+ .toResponse(request.id));
+
+ // If the client opted into using available suggestion sets,
+ // create the kinds set, so signal the completion manager about opt-in.
+ Set<ElementKind>? includedElementKinds;
+ Set<String>? includedElementNames;
+ List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
+ if (server.completionState.subscriptions
+ .contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+ includedElementKinds = <ElementKind>{};
+ includedElementNames = <String>{};
+ includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+ }
+
+ // Compute suggestions in the background
+ try {
+ var suggestionBuilders = <CompletionSuggestionBuilder>[];
+ try {
+ suggestionBuilders = await computeSuggestions(
+ budget: budget,
+ performance: performance,
+ request: completionRequest,
+ includedElementKinds: includedElementKinds,
+ includedElementNames: includedElementNames,
+ includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+ );
+ } on AbortCompletion {
+ // Continue with empty suggestions list.
+ }
+ String? libraryFile;
+ var includedSuggestionSets = <IncludedSuggestionSet>[];
+ if (includedElementKinds != null && includedElementNames != null) {
+ libraryFile = resolvedUnit.libraryElement.source.fullName;
+ server.sendNotification(
+ createExistingImportsNotification(resolvedUnit),
+ );
+ computeIncludedSetList(
+ declarationsTracker,
+ completionRequest,
+ includedSuggestionSets,
+ includedElementNames,
+ );
+ }
+
+ const SEND_NOTIFICATION_TAG = 'send notification';
+ performance.run(SEND_NOTIFICATION_TAG, (_) {
+ sendCompletionNotification(
+ completionId,
+ completionRequest.replacementOffset,
+ completionRequest.replacementLength,
+ suggestionBuilders.map((e) => e.build()).toList(),
+ libraryFile,
+ includedSuggestionSets,
+ includedElementKinds?.toList(),
+ includedSuggestionRelevanceTags,
+ );
+ });
+
+ completionPerformance.computedSuggestionCount =
+ suggestionBuilders.length;
+ completionPerformance.transmittedSuggestionCount =
+ suggestionBuilders.length;
+ } finally {
+ _ifMatchesRequestClear(completionRequest);
+ }
+ },
+ );
+ }
+
+ void _ifMatchesRequestClear(DartCompletionRequest request) {
+ if (server.completionState.currentRequest == request) {
+ server.completionState.currentRequest = null;
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
new file mode 100644
index 0000000..1d17711
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_get_suggestions2.dart
@@ -0,0 +1,354 @@
+// 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 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_abstract.dart';
+import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/fuzzy_filter_sort.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
+import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:collection/collection.dart';
+
+/// The handler for the `completion.getSuggestions2` request.
+class CompletionGetSuggestions2Handler extends LegacyHandler
+ with RequestHandlerMixin<AnalysisServer> {
+ /// Initialize a newly created handler to be able to service requests for the
+ /// [server].
+ CompletionGetSuggestions2Handler(
+ super.server, super.request, super.cancellationToken);
+
+ /// Compute completion results for the given request and append them to the
+ /// stream. Clients should not call this method directly as it is
+ /// automatically called when a client listens to the stream returned by
+ /// [results]. Subclasses should override this method, append at least one
+ /// result to the [controller], and close the controller stream once complete.
+ Future<List<CompletionSuggestionBuilder>> computeSuggestions({
+ required CompletionBudget budget,
+ required OperationPerformanceImpl performance,
+ required DartCompletionRequest request,
+ Set<ElementKind>? includedElementKinds,
+ Set<String>? includedElementNames,
+ List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
+ NotImportedSuggestions? notImportedSuggestions,
+ }) async {
+ //
+ // Allow plugins to start computing fixes.
+ //
+ var requestToPlugins = performance.run('askPlugins', (_) {
+ return _sendRequestToPlugins(request);
+ });
+
+ //
+ // Compute completions generated by server.
+ //
+ var suggestions = <CompletionSuggestionBuilder>[];
+ await performance.runAsync('computeSuggestions', (performance) async {
+ var manager = DartCompletionManager(
+ budget: budget,
+ includedElementKinds: includedElementKinds,
+ includedElementNames: includedElementNames,
+ includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+ notImportedSuggestions: notImportedSuggestions,
+ );
+
+ suggestions.addAll(
+ await manager.computeSuggestions(request, performance),
+ );
+ });
+ // TODO (danrubel) if request is obsolete (processAnalysisRequest returns
+ // false) then send empty results
+
+ //
+ // Add the completions produced by plugins to the server-generated list.
+ //
+ if (requestToPlugins != null) {
+ await performance.runAsync('waitForPlugins', (_) async {
+ await _addPluginSuggestions(budget, requestToPlugins, suggestions);
+ });
+ }
+
+ return suggestions;
+ }
+
+ /// Return the suggestions that should be presented in the YAML [file] at the
+ /// given [offset].
+ YamlCompletionResults computeYamlSuggestions(String file, int offset) {
+ var provider = server.resourceProvider;
+ var pathContext = provider.pathContext;
+ if (file_paths.isAnalysisOptionsYaml(pathContext, file)) {
+ var generator = AnalysisOptionsGenerator(provider);
+ return generator.getSuggestions(file, offset);
+ } else if (file_paths.isFixDataYaml(pathContext, file)) {
+ var generator = FixDataGenerator(provider);
+ return generator.getSuggestions(file, offset);
+ } else if (file_paths.isPubspecYaml(pathContext, file)) {
+ var generator = PubspecGenerator(provider, server.pubPackageService);
+ return generator.getSuggestions(file, offset);
+ }
+ return const YamlCompletionResults.empty();
+ }
+
+ @override
+ Future<void> handle() async {
+ var params = CompletionGetSuggestions2Params.fromRequest(request);
+ var file = params.file;
+ var offset = params.offset;
+
+ var timeoutMilliseconds = params.timeout;
+ var budget = CompletionBudget(
+ timeoutMilliseconds != null
+ ? Duration(milliseconds: timeoutMilliseconds)
+ : server.completionState.budgetDuration,
+ );
+
+ var provider = server.resourceProvider;
+ var pathContext = provider.pathContext;
+
+ if (file.endsWith('.yaml')) {
+ final suggestions = computeYamlSuggestions(file, offset);
+ server.sendResponse(
+ CompletionGetSuggestions2Result(
+ suggestions.replacementOffset,
+ suggestions.replacementLength,
+ suggestions.suggestions,
+ false,
+ ).toResponse(request.id),
+ );
+ return;
+ }
+
+ if (!file_paths.isDart(pathContext, file)) {
+ server.sendResponse(
+ CompletionGetSuggestions2Result(offset, 0, [], false)
+ .toResponse(request.id),
+ );
+ return;
+ }
+
+ var performance = OperationPerformanceImpl('<root>');
+ performance.runAsync(
+ 'request',
+ (performance) async {
+ var resolvedUnit = await performance.runAsync(
+ 'resolveForCompletion',
+ (performance) {
+ return server.resolveForCompletion(
+ path: file,
+ offset: offset,
+ performance: performance,
+ );
+ },
+ );
+ if (resolvedUnit == null) {
+ server.sendResponse(Response.fileNotAnalyzed(request, file));
+ return;
+ }
+
+ if (offset < 0 || offset > resolvedUnit.content.length) {
+ server.sendResponse(Response.invalidParameter(
+ request,
+ 'params.offset',
+ 'Expected offset between 0 and source length inclusive,'
+ ' but found $offset'));
+ return;
+ }
+
+ final completionPerformance = CompletionPerformance(
+ operation: performance,
+ path: file,
+ content: resolvedUnit.content,
+ offset: offset,
+ );
+ server.completionState.performanceList.add(completionPerformance);
+
+ var analysisSession = resolvedUnit.analysisSession;
+ var enclosingNode =
+ resolvedUnit.resolvedNodes.lastOrNull ?? resolvedUnit.parsedUnit;
+
+ var completionRequest = DartCompletionRequest(
+ analysisSession: analysisSession,
+ filePath: resolvedUnit.path,
+ fileContent: resolvedUnit.content,
+ unitElement: resolvedUnit.unitElement,
+ enclosingNode: enclosingNode,
+ offset: offset,
+ dartdocDirectiveInfo:
+ server.getDartdocDirectiveInfoForSession(analysisSession),
+ documentationCache:
+ server.getDocumentationCacheForSession(analysisSession),
+ );
+ setNewRequest(completionRequest);
+
+ var notImportedSuggestions = NotImportedSuggestions();
+ var suggestionBuilders = <CompletionSuggestionBuilder>[];
+ try {
+ suggestionBuilders = await computeSuggestions(
+ budget: budget,
+ performance: performance,
+ request: completionRequest,
+ notImportedSuggestions: notImportedSuggestions,
+ );
+ } on AbortCompletion {
+ return server.sendResponse(
+ CompletionGetSuggestions2Result(
+ completionRequest.replacementOffset,
+ completionRequest.replacementLength,
+ [],
+ true,
+ ).toResponse(request.id),
+ );
+ }
+
+ performance.run('filter', (performance) {
+ performance.getDataInt('count').add(suggestionBuilders.length);
+ suggestionBuilders = fuzzyFilterSort(
+ pattern: completionRequest.targetPrefix,
+ suggestions: suggestionBuilders,
+ );
+ performance.getDataInt('matchCount').add(suggestionBuilders.length);
+ });
+
+ var lengthRestricted =
+ suggestionBuilders.take(params.maxResults).toList();
+ completionPerformance.computedSuggestionCount =
+ suggestionBuilders.length;
+ completionPerformance.transmittedSuggestionCount =
+ lengthRestricted.length;
+
+ var suggestions = lengthRestricted.map((e) => e.build()).toList();
+
+ var isIncomplete = notImportedSuggestions.isIncomplete ||
+ lengthRestricted.length < suggestionBuilders.length;
+
+ performance.run('sendResponse', (_) {
+ sendResult(CompletionGetSuggestions2Result(
+ completionRequest.replacementOffset,
+ completionRequest.replacementLength,
+ suggestions,
+ isIncomplete,
+ ));
+ });
+ },
+ );
+ }
+
+ /// Send completion notification results.
+ void sendCompletionNotification(
+ String completionId,
+ int replacementOffset,
+ int replacementLength,
+ List<CompletionSuggestion> results,
+ String? libraryFile,
+ List<IncludedSuggestionSet>? includedSuggestionSets,
+ List<ElementKind>? includedElementKinds,
+ List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
+ ) {
+ server.sendNotification(
+ CompletionResultsParams(
+ completionId,
+ replacementOffset,
+ replacementLength,
+ results,
+ true,
+ libraryFile: libraryFile,
+ includedSuggestionSets: includedSuggestionSets,
+ includedElementKinds: includedElementKinds,
+ includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+ ).toNotification(),
+ );
+ }
+
+ void setNewRequest(DartCompletionRequest request) {
+ _abortCurrentRequest();
+ server.completionState.currentRequest = request;
+ }
+
+ /// Abort the current completion request, if any.
+ void _abortCurrentRequest() {
+ var currentRequest = server.completionState.currentRequest;
+ if (currentRequest != null) {
+ currentRequest.abort();
+ server.completionState.currentRequest = null;
+ }
+ }
+
+ /// Add the completions produced by plugins to the server-generated list.
+ Future<void> _addPluginSuggestions(
+ CompletionBudget budget,
+ _RequestToPlugins requestToPlugins,
+ List<CompletionSuggestionBuilder> suggestionBuilders,
+ ) async {
+ var responses = await waitForResponses(
+ requestToPlugins.futures,
+ requestParameters: requestToPlugins.parameters,
+ timeout: budget.left,
+ );
+ for (var response in responses) {
+ var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
+ if (result.results.isNotEmpty) {
+ var completionRequest = requestToPlugins.completionRequest;
+ if (completionRequest.replacementOffset != result.replacementOffset &&
+ completionRequest.replacementLength != result.replacementLength) {
+ server.instrumentationService
+ .logError('Plugin completion-results dropped due to conflicting'
+ ' replacement offset/length: ${result.toJson()}');
+ continue;
+ }
+ suggestionBuilders.addAll(
+ result.results.map(
+ (suggestion) => ValueCompletionSuggestionBuilder(suggestion),
+ ),
+ );
+ }
+ }
+ }
+
+ /// Send the completion request to plugins, so that they work in other
+ /// isolates in parallel with the server isolate.
+ _RequestToPlugins? _sendRequestToPlugins(
+ DartCompletionRequest completionRequest,
+ ) {
+ var pluginRequestParameters = plugin.CompletionGetSuggestionsParams(
+ completionRequest.path,
+ completionRequest.offset,
+ );
+
+ return _RequestToPlugins(
+ completionRequest: completionRequest,
+ parameters: pluginRequestParameters,
+ futures: server.pluginManager.broadcastRequest(
+ pluginRequestParameters,
+ contextRoot: completionRequest.analysisContext.contextRoot,
+ ),
+ );
+ }
+}
+
+class _RequestToPlugins {
+ final DartCompletionRequest completionRequest;
+ final plugin.CompletionGetSuggestionsParams parameters;
+ final Map<PluginInfo, Future<plugin.Response>> futures;
+
+ _RequestToPlugins({
+ required this.completionRequest,
+ required this.parameters,
+ required this.futures,
+ });
+}
diff --git a/pkg/analysis_server/lib/src/handler/legacy/completion_set_subscriptions.dart b/pkg/analysis_server/lib/src/handler/legacy/completion_set_subscriptions.dart
new file mode 100644
index 0000000..14dbe993
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/completion_set_subscriptions.dart
@@ -0,0 +1,49 @@
+// 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 'dart:async';
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
+import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
+
+/// The handler for the `completion.setSubscriptions` request.
+class CompletionSetSubscriptionsHandler extends LegacyHandler {
+ /// Initialize a newly created handler to be able to service requests for the
+ /// [server].
+ CompletionSetSubscriptionsHandler(
+ super.server, super.request, super.cancellationToken);
+
+ @override
+ Future<void> handle() async {
+ var params = CompletionSetSubscriptionsParams.fromRequest(request);
+
+ var subscriptions = server.completionState.subscriptions;
+ subscriptions.clear();
+ subscriptions.addAll(params.subscriptions);
+
+ var data = server.declarationsTrackerData;
+ if (data != null) {
+ if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+ var soFarLibraries = data.startListening((change) {
+ server.sendNotification(
+ createCompletionAvailableSuggestionsNotification(
+ change.changed,
+ change.removed,
+ ),
+ );
+ });
+ server.sendNotification(
+ createCompletionAvailableSuggestionsNotification(
+ soFarLibraries,
+ [],
+ ),
+ );
+ } else {
+ data.stopListening();
+ }
+ }
+ sendResult(CompletionSetSubscriptionsResult());
+ }
+}
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 788a702..f4fc4e2 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -2,27 +2,166 @@
// 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.10
-
library entities;
-import '../serialization/serialization.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../util/util.dart';
-import 'types.dart';
+import 'package:front_end/src/api_unstable/dart2js.dart' show AsyncModifier;
-import 'entities_migrated.dart';
-export 'entities_migrated.dart';
+// TODO(48820): Spannable was imported from `../common.dart`.
+import '../diagnostics/spannable.dart' show Spannable;
+import '../util/util.dart';
+import 'names.dart';
+
+/// Abstract interface for entities.
+///
+/// Implement this directly if the entity is not a Dart language entity.
+/// Entities defined within the Dart language should implement [Element].
+///
+/// For instance, the JavaScript backend need to create synthetic variables for
+/// calling intercepted classes and such variables do not correspond to an
+/// entity in the Dart source code nor in the terminology of the Dart language
+/// and should therefore implement [Entity] directly.
+abstract class Entity implements Spannable {
+ // Not all entities have names. Imports with no prefix and some local
+ // variables are unnamed. Some entities have a name that is the empty string
+ // (e.g. the default constructor).
+ String? get name;
+}
+
+/// Stripped down super interface for library like entities.
+///
+/// Currently only [LibraryElement] but later also kernel based Dart classes
+/// and/or Dart-in-JS classes.
+abstract class LibraryEntity extends Entity {
+ /// Return the canonical uri that identifies this library.
+ Uri get canonicalUri;
+
+ /// Returns whether or not this library has opted into null safety.
+ bool get isNonNullableByDefault;
+}
+
+/// Stripped down super interface for import entities.
+///
+/// The [name] property corresponds to the prefix name, if any.
+class ImportEntity {
+ final String? name;
+
+ /// The canonical URI of the library where this import occurs
+ /// (where the import is declared).
+ final Uri enclosingLibraryUri;
+
+ /// Whether the import is a deferred import.
+ final bool isDeferred;
+
+ /// The target import URI.
+ final Uri uri;
+
+ ImportEntity(this.isDeferred, this.name, this.uri, this.enclosingLibraryUri);
+
+ @override
+ String toString() => 'import($name:${isDeferred ? ' deferred' : ''})';
+}
+
+/// Stripped down super interface for class like entities.
+///
+/// Currently only [ClassElement] but later also kernel based Dart classes
+/// and/or Dart-in-JS classes.
+abstract class ClassEntity extends Entity {
+ /// If this is a normal class, the enclosing library for this class. If this
+ /// is a closure class, the enclosing class of the closure for which it was
+ /// created.
+ LibraryEntity get library;
+
+ /// Whether this is a synthesized class for a closurized method or local
+ /// function.
+ bool get isClosure;
+
+ /// Whether this is an abstract class.
+ bool get isAbstract;
+}
abstract class TypeVariableEntity extends Entity {
/// The class or generic method that declared this type variable.
- Entity get typeDeclaration;
+ /// Is `null` for some generic functions and closures.
+ // TODO(sra): Figure out how to always have a [typeDeclaration].
+ Entity? get typeDeclaration;
/// The index of this type variable in the type variables of its
/// [typeDeclaration].
int get index;
}
+/// Stripped down super interface for member like entities, that is,
+/// constructors, methods, fields etc.
+///
+/// Currently only [MemberElement] but later also kernel based Dart members
+/// and/or Dart-in-JS properties.
+abstract class MemberEntity extends Entity {
+ /// The [Name] of member which takes privacy and getter/setter naming into
+ /// account.
+ Name get memberName;
+
+ /// Whether this is a member of a library.
+ bool get isTopLevel;
+
+ /// Whether this is a static member of a class.
+ bool get isStatic;
+
+ /// Whether this is an instance member of a class.
+ bool get isInstanceMember;
+
+ /// Whether this is a constructor.
+ bool get isConstructor;
+
+ /// Whether this is a field.
+ bool get isField;
+
+ /// Whether this is a normal method (neither constructor, getter or setter)
+ /// or operator method.
+ bool get isFunction;
+
+ /// Whether this is a getter.
+ bool get isGetter;
+
+ /// Whether this is a setter.
+ bool get isSetter;
+
+ /// Whether this member is assignable, i.e. a non-final, non-const field.
+ bool get isAssignable;
+
+ /// Whether this member is constant, i.e. a constant field or constructor.
+ bool get isConst;
+
+ /// Whether this member is abstract, i.e. an abstract method, getter or
+ /// setter.
+ bool get isAbstract;
+
+ /// The enclosing class if this is a constructor, instance member or
+ /// static member of a class.
+ ClassEntity? get enclosingClass;
+
+ /// The enclosing library if this is a library member, otherwise the
+ /// enclosing library of the [enclosingClass].
+ LibraryEntity get library;
+}
+
+/// Stripped down super interface for field like entities.
+///
+/// Currently only [FieldElement] but later also kernel based Dart fields
+/// and/or Dart-in-JS field-like properties.
+abstract class FieldEntity extends MemberEntity {}
+
+/// An entity that defines a local entity (memory slot) in generated code.
+///
+/// Parameters, local variables and local functions (can) define local entity
+/// and thus implement [Local] through [LocalElement]. For non-element locals,
+/// like `this` and boxes, specialized [Local] classes are created.
+///
+/// Type variables can introduce locals in factories and constructors
+/// but since one type variable can introduce different locals in different
+/// factories and constructors it is not itself a [Local] but instead
+/// a non-element [Local] is created through a specialized class.
+abstract class Local extends Entity {}
+
/// Stripped down super interface for function like entities.
///
/// Currently only [MethodElement] but later also kernel based Dart constructors
@@ -30,7 +169,7 @@
abstract class FunctionEntity extends MemberEntity {
/// Whether this function is external, i.e. the body is not defined in terms
/// of Dart code.
- bool /*!*/ get isExternal;
+ bool get isExternal;
/// The structure of the function parameters.
ParameterStructure get parameterStructure;
@@ -39,6 +178,61 @@
AsyncMarker get asyncMarker;
}
+/// Enum for the synchronous/asynchronous function body modifiers.
+class AsyncMarker {
+ /// The default function body marker.
+ static const AsyncMarker SYNC = AsyncMarker._(AsyncModifier.Sync);
+
+ /// The `sync*` function body marker.
+ static const AsyncMarker SYNC_STAR =
+ AsyncMarker._(AsyncModifier.SyncStar, isYielding: true);
+
+ /// The `async` function body marker.
+ static const AsyncMarker ASYNC =
+ AsyncMarker._(AsyncModifier.Async, isAsync: true);
+
+ /// The `async*` function body marker.
+ static const AsyncMarker ASYNC_STAR =
+ AsyncMarker._(AsyncModifier.AsyncStar, isAsync: true, isYielding: true);
+
+ /// Is `true` if this marker defines the function body to have an
+ /// asynchronous result, that is, either a [Future] or a [Stream].
+ final bool isAsync;
+
+ /// Is `true` if this marker defines the function body to have a plural
+ /// result, that is, either an [Iterable] or a [Stream].
+ final bool isYielding;
+
+ final AsyncModifier asyncParserState;
+
+ const AsyncMarker._(this.asyncParserState,
+ {this.isAsync = false, this.isYielding = false});
+
+ @override
+ String toString() {
+ return '${isAsync ? 'async' : 'sync'}${isYielding ? '*' : ''}';
+ }
+
+ /// Canonical list of marker values.
+ ///
+ /// Added to make [AsyncMarker] enum-like.
+ static const List<AsyncMarker> values = <AsyncMarker>[
+ SYNC,
+ SYNC_STAR,
+ ASYNC,
+ ASYNC_STAR
+ ];
+
+ /// Index to this marker within [values].
+ ///
+ /// Added to make [AsyncMarker] enum-like.
+ int get index => values.indexOf(this);
+}
+
+/// Values for variance annotations.
+/// This needs to be kept in sync with values of `Variance` in `dart:_rti`.
+enum Variance { legacyCovariant, covariant, contravariant, invariant }
+
/// Stripped down super interface for constructor like entities.
///
/// Currently only [ConstructorElement] but later also kernel based Dart
@@ -123,8 +317,8 @@
factory ParameterStructure(
int requiredPositionalParameters,
int positionalParameters,
- List<String /*!*/ > namedParameters,
- Set<String /*!*/ > requiredNamedParameters,
+ List<String> namedParameters,
+ Set<String> requiredNamedParameters,
int typeParameters) {
// This simple canonicalization reduces the number of ParameterStructure
// objects by over 90%.
@@ -149,44 +343,6 @@
);
}
- factory ParameterStructure.fromType(FunctionType type) {
- return ParameterStructure(
- type.parameterTypes.length,
- type.parameterTypes.length + type.optionalParameterTypes.length,
- type.namedParameters,
- type.requiredNamedParameters,
- type.typeVariables.length);
- }
-
- /// Deserializes a [ParameterStructure] object from [source].
- factory ParameterStructure.readFromDataSource(DataSourceReader source) {
- source.begin(tag);
- int requiredPositionalParameters = source.readInt();
- int positionalParameters = source.readInt();
- List<String> namedParameters = source.readStrings() /*!*/;
- Set<String> requiredNamedParameters =
- source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
- int typeParameters = source.readInt();
- source.end(tag);
- return ParameterStructure(
- requiredPositionalParameters,
- positionalParameters,
- namedParameters,
- requiredNamedParameters,
- typeParameters);
- }
-
- /// Serializes this [ParameterStructure] to [sink].
- void writeToDataSink(DataSinkWriter sink) {
- sink.begin(tag);
- sink.writeInt(requiredPositionalParameters);
- sink.writeInt(positionalParameters);
- sink.writeStrings(namedParameters);
- sink.writeStrings(requiredNamedParameters);
- sink.writeInt(typeParameters);
- sink.end(tag);
- }
-
/// The number of optional parameters (positional or named).
int get optionalParameters =>
(positionalParameters - requiredPositionalParameters) +
@@ -195,11 +351,8 @@
/// The total number of parameters (required or optional).
int get totalParameters => positionalParameters + namedParameters.length;
- /// Returns the [CallStructure] corresponding to a call site passing all
- /// parameters both required and optional.
- CallStructure get callStructure {
- return CallStructure(totalParameters, namedParameters, typeParameters);
- }
+ // TODO(48820): Move definition back here:
+ // CallStructure get callStructure;
@override
int get hashCode => Hashing.listHash(
diff --git a/pkg/compiler/lib/src/elements/entities_migrated.dart b/pkg/compiler/lib/src/elements/entities_migrated.dart
deleted file mode 100644
index 7e7a26f..0000000
--- a/pkg/compiler/lib/src/elements/entities_migrated.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library entities.migrated;
-
-import 'package:front_end/src/api_unstable/dart2js.dart' show AsyncModifier;
-
-// TODO(48820): This was imported from `common.dart`.
-import '../diagnostics/spannable.dart' show Spannable;
-
-import 'names.dart';
-
-/// Abstract interface for entities.
-///
-/// Implement this directly if the entity is not a Dart language entity.
-/// Entities defined within the Dart language should implement [Element].
-///
-/// For instance, the JavaScript backend need to create synthetic variables for
-/// calling intercepted classes and such variables do not correspond to an
-/// entity in the Dart source code nor in the terminology of the Dart language
-/// and should therefore implement [Entity] directly.
-abstract class Entity implements Spannable {
- // Not all entities have names. Imports with no prefix and some local
- // variables are unnamed. Some entities have a name that is the empty string
- // (e.g. the default constructor).
- String? get name;
-}
-
-/// Stripped down super interface for library like entities.
-///
-/// Currently only [LibraryElement] but later also kernel based Dart classes
-/// and/or Dart-in-JS classes.
-abstract class LibraryEntity extends Entity {
- /// Return the canonical uri that identifies this library.
- Uri get canonicalUri;
-
- /// Returns whether or not this library has opted into null safety.
- bool get isNonNullableByDefault;
-}
-
-/// Stripped down super interface for import entities.
-///
-/// The [name] property corresponds to the prefix name, if any.
-class ImportEntity {
- final String? name;
-
- /// The canonical URI of the library where this import occurs
- /// (where the import is declared).
- final Uri enclosingLibraryUri;
-
- /// Whether the import is a deferred import.
- final bool isDeferred;
-
- /// The target import URI.
- final Uri uri;
-
- ImportEntity(this.isDeferred, this.name, this.uri, this.enclosingLibraryUri);
-
- @override
- String toString() => 'import($name:${isDeferred ? ' deferred' : ''})';
-}
-
-/// Stripped down super interface for class like entities.
-///
-/// Currently only [ClassElement] but later also kernel based Dart classes
-/// and/or Dart-in-JS classes.
-abstract class ClassEntity extends Entity {
- /// If this is a normal class, the enclosing library for this class. If this
- /// is a closure class, the enclosing class of the closure for which it was
- /// created.
- LibraryEntity get library;
-
- /// Whether this is a synthesized class for a closurized method or local
- /// function.
- bool get isClosure;
-
- /// Whether this is an abstract class.
- bool get isAbstract;
-}
-
-/// Stripped down super interface for member like entities, that is,
-/// constructors, methods, fields etc.
-///
-/// Currently only [MemberElement] but later also kernel based Dart members
-/// and/or Dart-in-JS properties.
-abstract class MemberEntity extends Entity {
- /// The [Name] of member which takes privacy and getter/setter naming into
- /// account.
- Name get memberName;
-
- /// Whether this is a member of a library.
- bool get isTopLevel;
-
- /// Whether this is a static member of a class.
- bool get isStatic;
-
- /// Whether this is an instance member of a class.
- bool get isInstanceMember;
-
- /// Whether this is a constructor.
- bool get isConstructor;
-
- /// Whether this is a field.
- bool get isField;
-
- /// Whether this is a normal method (neither constructor, getter or setter)
- /// or operator method.
- bool get isFunction;
-
- /// Whether this is a getter.
- bool get isGetter;
-
- /// Whether this is a setter.
- bool get isSetter;
-
- /// Whether this member is assignable, i.e. a non-final, non-const field.
- bool get isAssignable;
-
- /// Whether this member is constant, i.e. a constant field or constructor.
- bool get isConst;
-
- /// Whether this member is abstract, i.e. an abstract method, getter or
- /// setter.
- bool get isAbstract;
-
- /// The enclosing class if this is a constructor, instance member or
- /// static member of a class.
- ClassEntity? get enclosingClass;
-
- /// The enclosing library if this is a library member, otherwise the
- /// enclosing library of the [enclosingClass].
- LibraryEntity get library;
-}
-
-/// Stripped down super interface for field like entities.
-///
-/// Currently only [FieldElement] but later also kernel based Dart fields
-/// and/or Dart-in-JS field-like properties.
-abstract class FieldEntity extends MemberEntity {}
-
-/// An entity that defines a local entity (memory slot) in generated code.
-///
-/// Parameters, local variables and local functions (can) define local entity
-/// and thus implement [Local] through [LocalElement]. For non-element locals,
-/// like `this` and boxes, specialized [Local] classes are created.
-///
-/// Type variables can introduce locals in factories and constructors
-/// but since one type variable can introduce different locals in different
-/// factories and constructors it is not itself a [Local] but instead
-/// a non-element [Local] is created through a specialized class.
-abstract class Local extends Entity {}
-
-/// Enum for the synchronous/asynchronous function body modifiers.
-class AsyncMarker {
- /// The default function body marker.
- static const AsyncMarker SYNC = AsyncMarker._(AsyncModifier.Sync);
-
- /// The `sync*` function body marker.
- static const AsyncMarker SYNC_STAR =
- AsyncMarker._(AsyncModifier.SyncStar, isYielding: true);
-
- /// The `async` function body marker.
- static const AsyncMarker ASYNC =
- AsyncMarker._(AsyncModifier.Async, isAsync: true);
-
- /// The `async*` function body marker.
- static const AsyncMarker ASYNC_STAR =
- AsyncMarker._(AsyncModifier.AsyncStar, isAsync: true, isYielding: true);
-
- /// Is `true` if this marker defines the function body to have an
- /// asynchronous result, that is, either a [Future] or a [Stream].
- final bool isAsync;
-
- /// Is `true` if this marker defines the function body to have a plural
- /// result, that is, either an [Iterable] or a [Stream].
- final bool isYielding;
-
- final AsyncModifier asyncParserState;
-
- const AsyncMarker._(this.asyncParserState,
- {this.isAsync = false, this.isYielding = false});
-
- @override
- String toString() {
- return '${isAsync ? 'async' : 'sync'}${isYielding ? '*' : ''}';
- }
-
- /// Canonical list of marker values.
- ///
- /// Added to make [AsyncMarker] enum-like.
- static const List<AsyncMarker> values = <AsyncMarker>[
- SYNC,
- SYNC_STAR,
- ASYNC,
- ASYNC_STAR
- ];
-
- /// Index to this marker within [values].
- ///
- /// Added to make [AsyncMarker] enum-like.
- int get index => values.indexOf(this);
-}
-
-/// Values for variance annotations.
-/// This needs to be kept in sync with values of `Variance` in `dart:_rti`.
-enum Variance { legacyCovariant, covariant, contravariant, invariant }
diff --git a/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart b/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart
new file mode 100644
index 0000000..a7f4702
--- /dev/null
+++ b/pkg/compiler/lib/src/elements/entities_parameter_structure_methods.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2016, 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.10
+
+/// Methods for [ParameterStructure] that have not yet been migrated to null
+/// safety.
+// TODO(48820): Move these methods back to [ParameterStructure].
+library entities.parameter_structure_methods;
+
+import '../serialization/serialization.dart';
+import '../universe/call_structure.dart' show CallStructure;
+import 'entities.dart';
+import 'types.dart' show FunctionType;
+
+extension UnmigratedParameterStructureInstanceMethods on ParameterStructure {
+ /// Returns the [CallStructure] corresponding to a call site passing all
+ /// parameters both required and optional.
+ CallStructure get callStructure {
+ return CallStructure(totalParameters, namedParameters, typeParameters);
+ }
+
+ /// Serializes this [ParameterStructure] to [sink].
+ void writeToDataSink(DataSinkWriter sink) {
+ final tag = ParameterStructure.tag;
+ sink.begin(tag);
+ sink.writeInt(requiredPositionalParameters);
+ sink.writeInt(positionalParameters);
+ sink.writeStrings(namedParameters);
+ sink.writeStrings(requiredNamedParameters);
+ sink.writeInt(typeParameters);
+ sink.end(tag);
+ }
+}
+
+class ParameterStructureMethods {
+ static ParameterStructure fromType(FunctionType type) {
+ return ParameterStructure(
+ type.parameterTypes.length,
+ type.parameterTypes.length + type.optionalParameterTypes.length,
+ type.namedParameters,
+ type.requiredNamedParameters,
+ type.typeVariables.length);
+ }
+
+ /// Deserializes a [ParameterStructure] object from [source].
+ static readFromDataSource(DataSourceReader source) {
+ final tag = ParameterStructure.tag;
+ source.begin(tag);
+ int requiredPositionalParameters = source.readInt();
+ int positionalParameters = source.readInt();
+ List<String> namedParameters = source.readStrings() /*!*/;
+ Set<String> requiredNamedParameters =
+ source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
+ int typeParameters = source.readInt();
+ source.end(tag);
+ return ParameterStructure(
+ requiredPositionalParameters,
+ positionalParameters,
+ namedParameters,
+ requiredNamedParameters,
+ typeParameters);
+ }
+}
diff --git a/pkg/compiler/lib/src/elements/jumps.dart b/pkg/compiler/lib/src/elements/jumps.dart
index f6080e2..de1cf48 100644
--- a/pkg/compiler/lib/src/elements/jumps.dart
+++ b/pkg/compiler/lib/src/elements/jumps.dart
@@ -4,7 +4,7 @@
library elements.jumps;
-import 'entities_migrated.dart' show Entity, Local;
+import 'entities.dart' show Entity, Local;
/// The label entity defined by a labeled statement.
abstract class LabelDefinition extends Entity {
diff --git a/pkg/compiler/lib/src/elements/names.dart b/pkg/compiler/lib/src/elements/names.dart
index 90f5e15..f4ec96f 100644
--- a/pkg/compiler/lib/src/elements/names.dart
+++ b/pkg/compiler/lib/src/elements/names.dart
@@ -6,7 +6,7 @@
import 'package:front_end/src/api_unstable/dart2js.dart' show $_;
-import 'entities_migrated.dart' show LibraryEntity;
+import 'entities.dart' show LibraryEntity;
/// A [Name] represents the abstraction of a Dart identifier which takes privacy
/// and setter into account.
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index e0f1ff5..e8d244f 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -6,8 +6,7 @@
// TODO(48820): revert to '../common.dart':
import '../diagnostics/source_span.dart';
-import '../elements/entities_migrated.dart'
- show AsyncMarker, MemberEntity, Variance;
+import '../elements/entities.dart' show AsyncMarker, MemberEntity, Variance;
/// Returns a textual representation of [node] that include the runtime type and
/// hash code of the node and a one line prefix of the node toString text.
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 6682b3e..d2d4aa2 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -12,6 +12,7 @@
import '../common/names.dart' show Identifiers;
import '../constants/values.dart';
import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../elements/types.dart';
import '../enqueue.dart' show Enqueuer, EnqueuerListener;
import '../native/enqueue.dart';
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index 12113ce..c6b8b41 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -11,6 +11,7 @@
import '../constants/values.dart';
import '../deferred_load/deferred_load.dart';
import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../elements/types.dart';
import '../enqueue.dart' show Enqueuer, EnqueuerListener;
import '../native/enqueue.dart';
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index ce85047..5e14de3 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -10,6 +10,7 @@
import '../common/elements.dart' show CommonElements, ElementEnvironment;
import '../common/names.dart' show Identifiers;
import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../elements/names.dart';
import '../elements/types.dart';
import '../ir/runtime_type_analysis.dart';
@@ -141,7 +142,8 @@
if (property.memberName != selector.memberName) return false;
if (type is FunctionType &&
!selector.callStructure
- .signatureApplies(ParameterStructure.fromType(type))) return false;
+ .signatureApplies(ParameterStructureMethods.fromType(type)))
+ return false;
return true;
}
@@ -288,8 +290,9 @@
instanceName: instanceName,
isNoSuchMethod: isNoSuchMethod);
} else {
- ParameterStructure parameterStructure = ParameterStructure.fromType(
- _elementEnvironment.getLocalFunctionType(function));
+ ParameterStructure parameterStructure =
+ ParameterStructureMethods.fromType(
+ _elementEnvironment.getLocalFunctionType(function));
node = MethodNode(function, parameterStructure, isCallTarget: true);
}
return node;
@@ -446,7 +449,7 @@
for (GenericInstantiation instantiation in _genericInstantiations) {
ParameterStructure instantiationParameterStructure =
- ParameterStructure.fromType(instantiation.functionType);
+ ParameterStructureMethods.fromType(instantiation.functionType);
ClassEntity implementationClass = _commonElements
.getInstantiationClass(instantiation.typeArguments.length);
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index c9df01d..1cb41cc 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -204,7 +204,7 @@
ParameterStructure parameterStructure =
annotations.hasNoElision(constructor)
? constructor.parameterStructure
- : memberUsage.invokedParameters;
+ : memberUsage.invokedParameters /*!*/;
if (constructor.isFactoryConstructor) {
// TODO(redemption): This should be a JFunction.
newMember = JFactoryConstructor(
@@ -236,7 +236,7 @@
ParameterStructure parameterStructure =
annotations.hasNoElision(function)
? function.parameterStructure
- : memberUsage.invokedParameters;
+ : memberUsage.invokedParameters /*!*/;
newMember = JMethod(newLibrary, newClass, memberName,
parameterStructure, function.asyncMarker,
isStatic: function.isStatic,
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 6a6d47c..9d3517e 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -10,6 +10,7 @@
import '../elements/entities.dart';
import '../elements/indexed.dart';
import '../elements/names.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../elements/types.dart';
import '../serialization/serialization.dart';
import '../universe/class_set.dart' show ClassHierarchyNodesMapKey;
@@ -279,7 +280,7 @@
JClass enclosingClass = source.readClass();
String name = source.readString();
ParameterStructure parameterStructure =
- ParameterStructure.readFromDataSource(source);
+ ParameterStructureMethods.readFromDataSource(source);
bool isExternal = source.readBool();
bool isConst = source.readBool();
source.end(tag);
@@ -317,7 +318,9 @@
JFactoryConstructor(
JClass enclosingClass, Name name, ParameterStructure parameterStructure,
- {bool isExternal, bool isConst, this.isFromEnvironmentConstructor})
+ {bool isExternal,
+ bool isConst,
+ /*required*/ this.isFromEnvironmentConstructor})
: super(enclosingClass, name, parameterStructure,
isExternal: isExternal, isConst: isConst);
@@ -326,7 +329,7 @@
JClass enclosingClass = source.readClass();
String name = source.readString();
ParameterStructure parameterStructure =
- ParameterStructure.readFromDataSource(source);
+ ParameterStructureMethods.readFromDataSource(source);
bool isExternal = source.readBool();
bool isConst = source.readBool();
bool isFromEnvironmentConstructor = source.readBool();
@@ -375,7 +378,7 @@
source.begin(tag);
JConstructor constructor = source.readMember();
ParameterStructure parameterStructure =
- ParameterStructure.readFromDataSource(source);
+ ParameterStructureMethods.readFromDataSource(source);
source.end(tag);
return JConstructorBody(constructor, parameterStructure);
}
@@ -423,7 +426,7 @@
}
String name = source.readString();
ParameterStructure parameterStructure =
- ParameterStructure.readFromDataSource(source);
+ ParameterStructureMethods.readFromDataSource(source);
AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
bool isStatic = source.readBool();
bool isExternal = source.readBool();
@@ -705,7 +708,7 @@
source.begin(tag);
JClass enclosingClass = source.readClass();
ParameterStructure parameterStructure =
- ParameterStructure.readFromDataSource(source);
+ ParameterStructureMethods.readFromDataSource(source);
AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
source.end(tag);
return JClosureCallMethod(enclosingClass, parameterStructure, asyncMarker);
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 76086f5..9d05fc1 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -191,8 +191,9 @@
.getTopLevelProcedure('dart:core', '_createInvocationMirror'),
ir.Arguments(<ir.Expression>[
ir.StringLiteral(name)..fileOffset = offset,
- ir.ListLiteral(
- arguments.types.map((t) => ir.TypeLiteral(t)).toList()),
+ ir.ListLiteral(arguments.types
+ .map<ir.Expression>((t) => ir.TypeLiteral(t))
+ .toList()),
ir.ListLiteral(arguments.positional)..fileOffset = offset,
ir.MapLiteral(List<ir.MapLiteralEntry>.from(
arguments.named.map((ir.NamedExpression arg) {
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index a0ab430..75f9512 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -12,6 +12,7 @@
import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart';
import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../elements/types.dart';
import '../inferrer/abstract_value_domain.dart';
import '../inferrer/types.dart';
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index cdafadd..26ac29a 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -9,6 +9,7 @@
import '../common.dart';
import '../common/names.dart' show Names;
import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../elements/entity_utils.dart' as utils;
import '../elements/names.dart';
import '../elements/operators.dart';
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 9ddd60d..f8861b1 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -22,6 +22,7 @@
import '../constants/values.dart';
import '../elements/types.dart';
import '../elements/entities.dart';
+import '../elements/entities_parameter_structure_methods.dart';
import '../inferrer/abstract_value_domain.dart';
import '../serialization/serialization.dart';
import '../js_model/closure.dart';
diff --git a/pkg/compiler/test/generic_methods/generic_method_type_test.dart b/pkg/compiler/test/generic_methods/generic_method_type_test.dart
index 6b2708d..0d30632 100644
--- a/pkg/compiler/test/generic_methods/generic_method_type_test.dart
+++ b/pkg/compiler/test/generic_methods/generic_method_type_test.dart
@@ -7,6 +7,7 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/entities_parameter_structure_methods.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:expect/expect.dart';
diff --git a/pkg/compiler/test/model/enqueuer_test.dart b/pkg/compiler/test/model/enqueuer_test.dart
index ac2f0c3..c3a7b5f 100644
--- a/pkg/compiler/test/model/enqueuer_test.dart
+++ b/pkg/compiler/test/model/enqueuer_test.dart
@@ -12,6 +12,7 @@
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/entities_parameter_structure_methods.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/enqueue.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
index c363409..17d5d77 100644
--- a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
@@ -92,7 +92,7 @@
static Expression _makeForwardingCall(
Member target, List<DartType> typeArguments, FunctionNode function) {
final List<Expression> positional = function.positionalParameters
- .map((v) => new VariableGet(v)..fileOffset = v.fileOffset)
+ .map<Expression>((v) => new VariableGet(v)..fileOffset = v.fileOffset)
.toList();
final List<NamedExpression> named = function.namedParameters
.map((v) => new NamedExpression(
diff --git a/pkg/front_end/testcases/general/infer_map.dart b/pkg/front_end/testcases/general/infer_map.dart
new file mode 100644
index 0000000..af8b81d
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart
@@ -0,0 +1,34 @@
+// 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.
+
+class A {}
+
+class B extends A {}
+
+List<int> intList = [1, 2];
+
+List<A> list1 = intList.map((i) => new B()).toList();
+
+test(List<A> list) {
+ try {
+ list.add(new A());
+ list.removeLast();
+ } catch (e) {
+ return;
+ }
+ throw 'Expected subtype error';
+}
+
+main() {
+ test(list1);
+ list1 = intList.map((i) => new B()).toList();
+ test(list1);
+
+ List<A> list2 = intList.map((i) => new B()).toList();
+ test(list2);
+ list2 = intList.map((i) => new B()).toList();
+ test(list2);
+
+ test(intList.map((i) => new B()).toList());
+}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_map.dart.textual_outline.expect
new file mode 100644
index 0000000..d62af11
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {}
+
+class B extends A {}
+
+List<int> intList = [1, 2];
+List<A> list1 = intList.map((i) => new B()).toList();
+test(List<A> list) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3683c37
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+List<A> list1 = intList.map((i) => new B()).toList();
+List<int> intList = [1, 2];
+
+class A {}
+
+class B extends A {}
+
+main() {}
+test(List<A> list) {}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.expect
new file mode 100644
index 0000000..d1501d8
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+static field core::List<core::int> intList = <core::int>[1, 2];
+static field core::List<self::A> list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+static method test(core::List<self::A> list) → dynamic {
+ try {
+ list.{core::List::add}(new self::A::•()){(self::A) → void};
+ list.{core::List::removeLast}(){() → self::A};
+ }
+ on core::Object catch(final core::Object e) {
+ return;
+ }
+ throw "Expected subtype error";
+}
+static method main() → dynamic {
+ self::test(self::list1);
+ self::list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(self::list1);
+ core::List<self::A> list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(list2);
+ list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(list2);
+ self::test(self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>});
+}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.modular.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.modular.expect
new file mode 100644
index 0000000..d1501d8
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.modular.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+static field core::List<core::int> intList = <core::int>[1, 2];
+static field core::List<self::A> list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+static method test(core::List<self::A> list) → dynamic {
+ try {
+ list.{core::List::add}(new self::A::•()){(self::A) → void};
+ list.{core::List::removeLast}(){() → self::A};
+ }
+ on core::Object catch(final core::Object e) {
+ return;
+ }
+ throw "Expected subtype error";
+}
+static method main() → dynamic {
+ self::test(self::list1);
+ self::list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(self::list1);
+ core::List<self::A> list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(list2);
+ list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(list2);
+ self::test(self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>});
+}
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.outline.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.outline.expect
new file mode 100644
index 0000000..f7b42fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ ;
+}
+static field core::List<core::int> intList;
+static field core::List<self::A> list1;
+static method test(core::List<self::A> list) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/infer_map.dart.weak.transformed.expect b/pkg/front_end/testcases/general/infer_map.dart.weak.transformed.expect
new file mode 100644
index 0000000..8d6c8ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map.dart.weak.transformed.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+static field core::List<core::int> intList = core::_GrowableList::_literal2<core::int>(1, 2);
+static field core::List<self::A> list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+static method test(core::List<self::A> list) → dynamic {
+ try {
+ list.{core::List::add}(new self::A::•()){(self::A) → void};
+ list.{core::List::removeLast}(){() → self::A};
+ }
+ on core::Object catch(final core::Object e) {
+ return;
+ }
+ throw "Expected subtype error";
+}
+static method main() → dynamic {
+ self::test(self::list1);
+ self::list1 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(self::list1);
+ core::List<self::A> list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(list2);
+ list2 = self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>};
+ self::test(list2);
+ self::test(self::intList.{core::Iterable::map}<self::B>((core::int i) → self::B => new self::B::•()){((core::int) → self::B) → core::Iterable<self::B>}.{core::Iterable::toList}(){({growable: core::bool}) → core::List<self::B>});
+}
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index f69a386..67fada2 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -141,8 +141,10 @@
..parent = syntheticConstructor)
.toList();
- initializersConstructor.add(SuperInitializer(superConstructor,
- Arguments(superParameters.map((f) => VariableGet(f)).toList()))
+ initializersConstructor.add(SuperInitializer(
+ superConstructor,
+ Arguments(
+ superParameters.map<Expression>((f) => VariableGet(f)).toList()))
..parent = syntheticConstructor);
syntheticConstructor.function.namedParameters
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 7a67f89..487d337 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -231,7 +231,9 @@
_fixedLengthList(
coreTypes,
coreTypes.typeLegacyRawType,
- arguments.types.map((t) => new TypeLiteral(t)).toList(),
+ arguments.types
+ .map<Expression>((t) => new TypeLiteral(t))
+ .toList(),
arguments.fileOffset),
_fixedLengthList(coreTypes, const DynamicType(), arguments.positional,
arguments.fileOffset),
diff --git a/tools/VERSION b/tools/VERSION
index 543ed1f..710b49e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 38
+PRERELEASE 39
PRERELEASE_PATCH 0
\ No newline at end of file