Bump DAS to use Dart SDK 3.9.0

Change-Id: I04bc285d822a657adb5573c6de3eb38655ab0fcd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448232
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Sam Rawlins
2025-09-03 12:56:29 -07:00
committed by Commit Queue
parent cb23ff22a4
commit 33f664940a
378 changed files with 4499 additions and 5027 deletions
@@ -139,18 +139,17 @@ class CmdLineSeveralProjectsBenchmark extends AbstractCmdLineBenchmark {
String get workingDir => packageRoot;
@override
List<String> analyzeWhat(bool quick) =>
quick
? ['meta']
: [
'analysis_server',
'analysis_server_client',
'analyzer',
'analyzer_cli',
'analyzer_plugin',
'analyzer_utilities',
'_fe_analyzer_shared',
];
List<String> analyzeWhat(bool quick) => quick
? ['meta']
: [
'analysis_server',
'analysis_server_client',
'analyzer',
'analyzer_cli',
'analyzer_plugin',
'analyzer_utilities',
'_fe_analyzer_shared',
];
}
class CmdLineSmallFileBenchmark extends AbstractCmdLineBenchmark {
@@ -34,8 +34,8 @@ class Bar {
await analysisFinished;
var result =
// ignore: deprecated_member_use_from_same_package
await sendAnalysisGetReachableSources(pathname);
// ignore: deprecated_member_use_from_same_package
await sendAnalysisGetReachableSources(pathname);
var sources = result.sources;
var keys = sources.keys.toList();
var url = File(pathname).uri.toString();
@@ -52,10 +52,9 @@ void f() {
}
void check(String elementName, Iterable<String> expectedOccurrences) {
var expectedOffsets =
expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var expectedOffsets = expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var foundOffsets = findOffsets(elementName);
expect(foundOffsets, equals(expectedOffsets));
}
@@ -102,10 +101,9 @@ void f() {
}
void check(String elementName, Iterable<String> expectedOccurrences) {
var expectedOffsets =
expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var expectedOffsets = expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var foundOffsets = findOffsets(elementName);
expect(foundOffsets, equals(expectedOffsets));
}
@@ -156,10 +154,9 @@ void f() {
}
void check(String elementName, Iterable<String> expectedOccurrences) {
var expectedOffsets =
expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var expectedOffsets = expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var foundOffsets = findOffsets(elementName);
expect(foundOffsets, equals(expectedOffsets));
}
@@ -212,10 +209,9 @@ void f() {
}
void check(String elementName, Iterable<String> expectedOccurrences) {
var expectedOffsets =
expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var expectedOffsets = expectedOccurrences
.map((String substring) => text.indexOf(substring))
.toSet();
var foundOffsets = findOffsets(elementName);
expect(foundOffsets, equals(expectedOffsets));
}
@@ -37,11 +37,10 @@ void f() {
// order in which they appear in the file. If these edits are applied in
// the wrong order, some of the quotation marks will be in the wrong
// places, and there will still be errors.
var edits =
'"'
.allMatches(goodText)
.map((Match match) => SourceEdit(match.start, 0, '"'))
.toList();
var edits = '"'
.allMatches(goodText)
.map((Match match) => SourceEdit(match.start, 0, '"'))
.toList();
await sendAnalysisUpdateContent({pathname: ChangeContentOverlay(edits)});
await analysisFinished;
// There should be no errors now, assuming that quotation marks have been
@@ -23,35 +23,29 @@ void main() {
var lines = coverageFile.readAsLinesSync();
// ## server domain
var coveredDomains =
lines
.where((line) => line.startsWith('## ') && line.endsWith(' domain'))
.map(
(line) =>
line
.substring('##'.length, line.length - 'domain'.length)
.trim(),
)
.toSet();
var coveredDomains = lines
.where((line) => line.startsWith('## ') && line.endsWith(' domain'))
.map(
(line) =>
line.substring('##'.length, line.length - 'domain'.length).trim(),
)
.toSet();
// Remove any ' (test failed)' suffixes.
lines =
lines.map((String line) {
var index = line.indexOf('(');
return index != -1 ? line.substring(0, index).trim() : line;
}).toList();
lines = lines.map((String line) {
var index = line.indexOf('(');
return index != -1 ? line.substring(0, index).trim() : line;
}).toList();
// - [ ] server.getVersion
var allMembers =
lines
.where((line) => line.startsWith('- '))
.map((line) => line.substring('- [ ]'.length).trim())
.toSet();
var coveredMembers =
lines
.where((line) => line.startsWith('- [x]'))
.map((line) => line.substring('- [x]'.length).trim())
.toSet();
var allMembers = lines
.where((line) => line.startsWith('- '))
.map((line) => line.substring('- [ ]'.length).trim())
.toSet();
var coveredMembers = lines
.where((line) => line.startsWith('- [x]'))
.map((line) => line.substring('- [x]'.length).trim())
.toSet();
// generate domain tests
for (var domain in api.domains) {
@@ -85,10 +79,9 @@ void main() {
expect(
fileExists,
isMarkedAsCovered,
reason:
isMarkedAsCovered
? '$testName marked as covered but has no test at $testPath'
: '$testName marked as not covered has test at $testPath',
reason: isMarkedAsCovered
? '$testName marked as covered but has no test at $testPath'
: '$testName marked as not covered has test at $testPath',
);
});
}
@@ -139,10 +139,9 @@ abstract class AbstractLspAnalysisServerIntegrationTest
@mustCallSuper
Future<void> setUp() async {
// Set up temporary folder for the test.
projectFolderPath =
Directory.systemTemp
.createTempSync('analysisServer_test_integration_lspProject')
.resolveSymbolicLinksSync();
projectFolderPath = Directory.systemTemp
.createTempSync('analysisServer_test_integration_lspProject')
.resolveSymbolicLinksSync();
_temporaryFolders.add(projectFolderPath);
newFolder(projectFolderPath);
newFolder(path.join(projectFolderPath, 'lib'));
@@ -56,12 +56,11 @@ class BlazeChangesTest extends AbstractAnalysisServerIntegrationTest {
await super.setUp();
oldSourceDirectory = sourceDirectory;
tmpPath =
Directory(
Directory.systemTemp
.createTempSync('analysisServer_test_integration_blazeProject')
.resolveSymbolicLinksSync(),
).path;
tmpPath = Directory(
Directory.systemTemp
.createTempSync('analysisServer_test_integration_blazeProject')
.resolveSymbolicLinksSync(),
).path;
_temporaryFolders.add(tmpPath);
workspacePath = inTmpDir('workspace_root');
writeFile(inWorkspace(file_paths.blazeWorkspaceMarker), '');
@@ -285,8 +285,8 @@ abstract class IntegrationTest {
///
/// The stack trace associated with the generation of the error, used for
/// debugging the server.
late final Stream<ServerErrorParams> onServerError =
_onServerError.stream.asBroadcastStream();
late final Stream<ServerErrorParams> onServerError = _onServerError.stream
.asBroadcastStream();
/// Stream controller for [onServerError].
final _onServerError = StreamController<ServerErrorParams>(sync: true);
@@ -314,8 +314,8 @@ abstract class IntegrationTest {
/// Parameters
///
/// entry: ServerLogEntry
late final Stream<ServerLogParams> onServerLog =
_onServerLog.stream.asBroadcastStream();
late final Stream<ServerLogParams> onServerLog = _onServerLog.stream
.asBroadcastStream();
/// Stream controller for [onServerLog].
final _onServerLog = StreamController<ServerLogParams>(sync: true);
@@ -341,8 +341,8 @@ abstract class IntegrationTest {
///
/// Note: this status type is deprecated, and is no longer sent by the
/// server.
late final Stream<ServerStatusParams> onServerStatus =
_onServerStatus.stream.asBroadcastStream();
late final Stream<ServerStatusParams> onServerStatus = _onServerStatus.stream
.asBroadcastStream();
/// Stream controller for [onServerStatus].
final _onServerStatus = StreamController<ServerStatusParams>(sync: true);
@@ -973,8 +973,9 @@ abstract class IntegrationTest {
/// errors: List<AnalysisError>
///
/// The errors contained in the file.
late final Stream<AnalysisErrorsParams> onAnalysisErrors =
_onAnalysisErrors.stream.asBroadcastStream();
late final Stream<AnalysisErrorsParams> onAnalysisErrors = _onAnalysisErrors
.stream
.asBroadcastStream();
/// Stream controller for [onAnalysisErrors].
final _onAnalysisErrors = StreamController<AnalysisErrorsParams>(sync: true);
@@ -1436,8 +1437,8 @@ abstract class IntegrationTest {
///
/// The existing imports in the library.
late final Stream<CompletionExistingImportsParams>
onCompletionExistingImports =
_onCompletionExistingImports.stream.asBroadcastStream();
onCompletionExistingImports = _onCompletionExistingImports.stream
.asBroadcastStream();
/// Stream controller for [onCompletionExistingImports].
final _onCompletionExistingImports =
@@ -1723,8 +1724,9 @@ abstract class IntegrationTest {
///
/// True if this is that last set of results that will be returned for the
/// indicated search.
late final Stream<SearchResultsParams> onSearchResults =
_onSearchResults.stream.asBroadcastStream();
late final Stream<SearchResultsParams> onSearchResults = _onSearchResults
.stream
.asBroadcastStream();
/// Stream controller for [onSearchResults].
final _onSearchResults = StreamController<SearchResultsParams>(sync: true);
@@ -3014,8 +3016,9 @@ abstract class IntegrationTest {
/// outline: FlutterOutline
///
/// The outline associated with the file.
late final Stream<FlutterOutlineParams> onFlutterOutline =
_onFlutterOutline.stream.asBroadcastStream();
late final Stream<FlutterOutlineParams> onFlutterOutline = _onFlutterOutline
.stream
.asBroadcastStream();
/// Stream controller for [onFlutterOutline].
final _onFlutterOutline = StreamController<FlutterOutlineParams>(sync: true);
@@ -604,11 +604,9 @@ class Server {
]) {
// Provide a default implementation of the reverse request processor that
// just throws because there are many tests that don't use reverse-requests.
reverseRequestProcessor ??=
(_) =>
throw UnimplementedError(
"A reverse request was received but the test did not provide 'reverseRequestProcessor'",
);
reverseRequestProcessor ??= (_) => throw UnimplementedError(
"A reverse request was received but the test did not provide 'reverseRequestProcessor'",
);
_process.stdout.transform(utf8.decoder).transform(LineSplitter()).listen((
String line,
@@ -620,18 +618,16 @@ class Server {
// {"event":"server.connected","params":{...}}The Dart VM service is listening on ...
const dartVMServiceMessage = 'The Dart VM service is listening on ';
if (trimmedLine.contains(dartVMServiceMessage)) {
trimmedLine =
trimmedLine
.substring(0, trimmedLine.indexOf(dartVMServiceMessage))
.trim();
trimmedLine = trimmedLine
.substring(0, trimmedLine.indexOf(dartVMServiceMessage))
.trim();
}
const devtoolsMessage =
'The Dart DevTools debugger and profiler is available at:';
if (trimmedLine.contains(devtoolsMessage)) {
trimmedLine =
trimmedLine
.substring(0, trimmedLine.indexOf(devtoolsMessage))
.trim();
trimmedLine = trimmedLine
.substring(0, trimmedLine.indexOf(devtoolsMessage))
.trim();
}
if (trimmedLine.isEmpty) {
return;
@@ -998,10 +994,9 @@ abstract class _RecursiveMatcher extends Matcher {
mismatchDescription = mismatchDescription
.add(' (should be ')
.addDescriptionOf(matcher);
var subDescription =
matcher
.describeMismatch(item, StringDescription(), subState, false)
.toString();
var subDescription = matcher
.describeMismatch(item, StringDescription(), subState, false)
.toString();
if (subDescription.isNotEmpty) {
mismatchDescription = mismatchDescription
.add('; ')
@@ -1062,10 +1057,9 @@ abstract class _RecursiveMatcher extends Matcher {
void populateMismatches(Object? item, List<MismatchDescriber> mismatches);
/// Create a [MismatchDescriber] describing a mismatch with a simple string.
MismatchDescriber simpleDescription(String description) => (
Description mismatchDescription,
) {
mismatchDescription.add(description);
return mismatchDescription;
};
MismatchDescriber simpleDescription(String description) =>
(Description mismatchDescription) {
mismatchDescription.add(description);
return mismatchDescription;
};
}
@@ -257,17 +257,15 @@ int _preferRequiredParams(
engine.FormalParameterElement e1,
engine.FormalParameterElement e2,
) {
var rank1 =
(e1.isRequiredNamed || e1.metadata.hasRequired)
? 0
: !e1.isNamed
? -1
: 1;
var rank2 =
(e2.isRequiredNamed || e2.metadata.hasRequired)
? 0
: !e2.isNamed
? -1
: 1;
var rank1 = (e1.isRequiredNamed || e1.metadata.hasRequired)
? 0
: !e1.isNamed
? -1
: 1;
var rank2 = (e2.isRequiredNamed || e2.metadata.hasRequired)
? 0
: !e2.isNamed
? -1
: 1;
return rank1 - rank2;
}
File diff suppressed because it is too large Load Diff
@@ -319,14 +319,13 @@ abstract class AnalysisServer {
}
var disablePubCommandVariable =
Platform.environment[PubCommand.disablePubCommandEnvironmentKey];
var pubCommand =
processRunner != null && disablePubCommandVariable == null
? PubCommand(
instrumentationService,
resourceProvider.pathContext,
processRunner,
)
: null;
var pubCommand = processRunner != null && disablePubCommandVariable == null
? PubCommand(
instrumentationService,
resourceProvider.pathContext,
processRunner,
)
: null;
pubPackageService = PubPackageService(
instrumentationService,
@@ -336,14 +335,13 @@ abstract class AnalysisServer {
);
performance = performanceDuringStartup;
this.pluginManager =
pluginManager ??= PluginManager(
resourceProvider,
resourceProvider.byteStorePath,
sdkManager.defaultSdkDirectory,
notificationManager,
instrumentationService,
);
this.pluginManager = pluginManager ??= PluginManager(
resourceProvider,
resourceProvider.byteStorePath,
sdkManager.defaultSdkDirectory,
notificationManager,
instrumentationService,
);
var pluginWatcher = PluginWatcher(resourceProvider, pluginManager);
var logName = options.newAnalysisDriverLog;
@@ -601,10 +599,9 @@ abstract class AnalysisServer {
if (resourceProvider is PhysicalResourceProvider) {
var stateLocation = resourceProvider.getStateLocation('.analysis-driver');
if (stateLocation != null) {
var timingByteStore =
_timingByteStore = TimingByteStore(
EvictingFileByteStore(stateLocation.path, G),
);
var timingByteStore = _timingByteStore = TimingByteStore(
EvictingFileByteStore(stateLocation.path, G),
);
return MemoryCachingByteStore(timingByteStore, memoryCacheSize);
}
}
@@ -840,10 +837,9 @@ abstract class AnalysisServer {
// This is FutureOr<> because for the legacy server it's never a future, so
// we can skip the await.
var initializedLspHandler = lspInitialized;
var handler =
initializedLspHandler is lsp.InitializedStateMessageHandler
? initializedLspHandler
: await initializedLspHandler;
var handler = initializedLspHandler is lsp.InitializedStateMessageHandler
? initializedLspHandler
: await initializedLspHandler;
return handler.handleMessage(
message,
@@ -516,10 +516,10 @@ class AnalyticsManager {
transitiveFileUniqueCount: contextStructure.transitiveFileUniqueCount,
transitiveFileUniqueLineCount:
contextStructure.transitiveFileUniqueLineCount,
libraryCycleLibraryCounts:
contextStructure.libraryCycleLibraryCounts.toAnalyticsString(),
libraryCycleLineCounts:
contextStructure.libraryCycleLineCounts.toAnalyticsString(),
libraryCycleLibraryCounts: contextStructure.libraryCycleLibraryCounts
.toAnalyticsString(),
libraryCycleLineCounts: contextStructure.libraryCycleLineCounts
.toAnalyticsString(),
),
);
}
@@ -598,16 +598,16 @@ class AnalyticsManager {
method: data.method,
duration: data.responseTimes.toAnalyticsString(),
added: data.additionalPercentiles[addedKey]?.toAnalyticsString(),
excluded:
data.additionalPercentiles[excludedKey]?.toAnalyticsString(),
excluded: data.additionalPercentiles[excludedKey]
?.toAnalyticsString(),
files: data.additionalPercentiles[filesKey]?.toAnalyticsString(),
included:
data.additionalPercentiles[includedKey]?.toAnalyticsString(),
openWorkspacePaths:
data.additionalPercentiles[openWorkspacePathsKey]
?.toAnalyticsString(),
removed:
data.additionalPercentiles[removedKey]?.toAnalyticsString(),
included: data.additionalPercentiles[includedKey]
?.toAnalyticsString(),
openWorkspacePaths: data
.additionalPercentiles[openWorkspacePathsKey]
?.toAnalyticsString(),
removed: data.additionalPercentiles[removedKey]
?.toAnalyticsString(),
),
);
var commandMap = data.additionalEnumCounts[commandEnumKey];
@@ -48,9 +48,8 @@ class PercentileCalculator {
return 0;
}
var targetIndex = _valueCount * percentile / 100;
var entries =
_counts.entries.toList()
..sort((first, second) => first.key.compareTo(second.key));
var entries = _counts.entries.toList()
..sort((first, second) => first.key.compareTo(second.key));
// The number of values represented by walking the counts.
var accumulation = 0;
for (var i = 0; i < entries.length; i++) {
@@ -25,26 +25,23 @@ class ByteStreamClientChannel implements ClientCommunicationChannel {
Stream<Notification> notificationStream;
factory ByteStreamClientChannel(Stream<List<int>> input, IOSink output) {
var jsonStream =
input
.transform(const Utf8Decoder())
.transform(LineSplitter())
.transform(JsonStreamDecoder())
.where((json) => json is Map<String, Object?>)
.cast<Map<String, Object?>>()
.asBroadcastStream();
var responseStream =
jsonStream
.where((json) => json[Notification.EVENT] == null)
.transform(ResponseConverter())
.where((response) => response != null)
.cast<Response>()
.asBroadcastStream();
var notificationStream =
jsonStream
.where((json) => json[Notification.EVENT] != null)
.transform(NotificationConverter())
.asBroadcastStream();
var jsonStream = input
.transform(const Utf8Decoder())
.transform(LineSplitter())
.transform(JsonStreamDecoder())
.where((json) => json is Map<String, Object?>)
.cast<Map<String, Object?>>()
.asBroadcastStream();
var responseStream = jsonStream
.where((json) => json[Notification.EVENT] == null)
.transform(ResponseConverter())
.where((response) => response != null)
.cast<Response>()
.asBroadcastStream();
var notificationStream = jsonStream
.where((json) => json[Notification.EVENT] != null)
.transform(NotificationConverter())
.asBroadcastStream();
return ByteStreamClientChannel._(
output,
responseStream,
@@ -170,12 +170,11 @@ class CiderCompletionComputer {
required OperationPerformanceImpl performance,
}) {
var suggestionBuilders = <CompletionSuggestionBuilder>[];
var importedLibraries =
target.withEnclosing2
.expand((fragment) => fragment.libraryImports)
.map((import) => import.importedLibrary)
.nonNulls
.toSet();
var importedLibraries = target.withEnclosing2
.expand((fragment) => fragment.libraryImports)
.map((import) => import.importedLibrary)
.nonNulls
.toSet();
for (var importedLibrary in importedLibraries) {
var importedSuggestions = _importedLibrarySuggestions(
element: importedLibrary,
@@ -47,10 +47,9 @@ class CiderDocumentSymbolsComputer {
) {
var codeRange = toRange(lineInfo, outline.codeOffset, outline.codeLength);
var nameLocation = outline.element.location;
var nameRange =
nameLocation != null
? toRange(lineInfo, nameLocation.offset, nameLocation.length)
: null;
var nameRange = nameLocation != null
? toRange(lineInfo, nameLocation.offset, nameLocation.length)
: null;
return DocumentSymbol(
name: toElementName(outline.element),
detail: outline.element.parameters,
@@ -58,12 +57,9 @@ class CiderDocumentSymbolsComputer {
deprecated: outline.element.isDeprecated,
range: codeRange,
selectionRange: nameRange ?? codeRange,
children:
outline.children
?.map(
(child) => _asDocumentSymbol(supportedKinds, lineInfo, child),
)
.toList(),
children: outline.children
?.map((child) => _asDocumentSymbol(supportedKinds, lineInfo, child))
.toList(),
);
}
}
@@ -37,10 +37,9 @@ class LibraryElementSuggestionBuilder
String? prefix,
]) {
var opType = request.opType;
var kind =
request.target.isFunctionalArgument()
? CompletionSuggestionKind.IDENTIFIER
: opType.suggestKind;
var kind = request.target.isFunctionalArgument()
? CompletionSuggestionKind.IDENTIFIER
: opType.suggestKind;
return LibraryElementSuggestionBuilder._(
request,
builder,
+16 -17
View File
@@ -316,23 +316,22 @@ class CheckNameResponse {
} catch (_) {
match.add(CiderSearchMatch(sourcePath, [searchInfo]));
}
var replacements =
match
.map(
(m) => CiderReplaceMatch(
m.path,
m.references
.map(
(p) => ReplaceInfo(
stateName,
p.startPosition,
stateClass.name!.length,
),
)
.toList(),
),
)
.toList();
var replacements = match
.map(
(m) => CiderReplaceMatch(
m.path,
m.references
.map(
(p) => ReplaceInfo(
stateName,
p.startPosition,
stateClass.name!.length,
),
)
.toList(),
),
)
.toList();
return FlutterWidgetRename(stateName, match, replacements);
}
@@ -110,8 +110,9 @@ class CallHierarchyItem {
var enclosingElement =
element.enclosingElement ??
element.firstFragment.enclosingFragment?.element;
var container =
enclosingElement != null ? _getContainer(enclosingElement) : null;
var container = enclosingElement != null
? _getContainer(enclosingElement)
: null;
containerName = container != null ? _getDisplayName(container) : null;
}
@@ -106,12 +106,11 @@ class ColorComputer {
double? alpha, red, green, blue;
for (var arg in args.whereType<NamedExpression>()) {
var expression = arg.expression;
var value =
expression is DoubleLiteral
? expression.value
: expression is IntegerLiteral
? expression.value?.toDouble()
: null;
var value = expression is DoubleLiteral
? expression.value
: expression is IntegerLiteral
? expression.value?.toDouble()
: null;
switch (arg.name.label.name) {
case 'alpha':
alpha = value;
@@ -154,12 +153,11 @@ class ColorComputer {
var red = arg0 is IntegerLiteral ? arg0.value : null;
var green = arg1 is IntegerLiteral ? arg1.value : null;
var blue = arg2 is IntegerLiteral ? arg2.value : null;
var opacity =
arg3 is IntegerLiteral
? arg3.value
: arg3 is DoubleLiteral
? arg3.value
: null;
var opacity = arg3 is IntegerLiteral
? arg3.value
: arg3 is DoubleLiteral
? arg3.value
: null;
var alpha = opacity != null ? (opacity * 255).toInt() : null;
return alpha != null && red != null && green != null && blue != null
@@ -175,9 +173,9 @@ class ColorComputer {
String? name,
List<Expression> args,
) =>
// MaterialAccentColor is a subclass of SwatchColor and has the same
// constructor.
_getFlutterSwatchColor(name, args);
// MaterialAccentColor is a subclass of SwatchColor and has the same
// constructor.
_getFlutterSwatchColor(name, args);
/// Extracts the color information from Flutter ColorSwatch constructor args.
ColorInformation? _getFlutterSwatchColor(
@@ -270,11 +268,11 @@ class ColorComputer {
}) {
return alpha != null && red != null && green != null && blue != null
? ColorInformation(
(alpha * 255.0).round() & 0xff,
(red * 255.0).round() & 0xff,
(green * 255.0).round() & 0xff,
(blue * 255.0).round() & 0xff,
)
(alpha * 255.0).round() & 0xff,
(red * 255.0).round() & 0xff,
(green * 255.0).round() & 0xff,
(blue * 255.0).round() & 0xff,
)
: null;
}
@@ -283,11 +281,11 @@ class ColorComputer {
static ColorInformation? getColorForInt(int? value) {
return value != null
? ColorInformation(
(value >> 24) & 0xff,
(value >> 16) & 0xff,
(value >> 8) & 0xff,
value & 0xff,
)
(value >> 24) & 0xff,
(value >> 16) & 0xff,
(value >> 8) & 0xff,
value & 0xff,
)
: null;
}
@@ -127,13 +127,12 @@ class DartUnitFoldingComputer {
_hasBlankLineBetween(end, _unit.beginToken.offset));
}
var kind =
isFileHeader
? FoldingKind.FILE_HEADER
: (commentToken.lexeme.startsWith('///') ||
commentToken.lexeme.startsWith('/**'))
? FoldingKind.DOCUMENTATION_COMMENT
: FoldingKind.COMMENT;
var kind = isFileHeader
? FoldingKind.FILE_HEADER
: (commentToken.lexeme.startsWith('///') ||
commentToken.lexeme.startsWith('/**'))
? FoldingKind.DOCUMENTATION_COMMENT
: FoldingKind.COMMENT;
_addRegion(offset, end, kind);
@@ -215,10 +215,9 @@ class DartUnitHighlightsComputer {
type,
semanticTokenType: semanticType,
semanticTokenModifiers: semanticModifiers,
additionalSemanticTokenModifiers:
_isAnnotationIdentifier(parent)
? {CustomSemanticTokenModifiers.annotation}
: null,
additionalSemanticTokenModifiers: _isAnnotationIdentifier(parent)
? {CustomSemanticTokenModifiers.annotation}
: null,
);
}
@@ -304,10 +303,9 @@ class DartUnitHighlightsComputer {
}
// Handle tokens that are references to record fields.
if (staticType is RecordType) {
type =
staticType.fieldByName(nameToken.lexeme) != null
? HighlightRegionType.INSTANCE_GETTER_REFERENCE
: HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE;
type = staticType.fieldByName(nameToken.lexeme) != null
? HighlightRegionType.INSTANCE_GETTER_REFERENCE
: HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE;
}
}
// Add the highlight region.
@@ -315,10 +313,9 @@ class DartUnitHighlightsComputer {
return _addRegion_token(
nameToken,
type,
additionalSemanticTokenModifiers:
_isAnnotationIdentifier(parent)
? {CustomSemanticTokenModifiers.annotation}
: null,
additionalSemanticTokenModifiers: _isAnnotationIdentifier(parent)
? {CustomSemanticTokenModifiers.annotation}
: null,
);
}
return false;
@@ -337,14 +334,13 @@ class DartUnitHighlightsComputer {
parent is MethodInvocation && parent.methodName.token == nameToken;
HighlightRegionType type;
var isTopLevel = element is TopLevelFunctionElement;
type =
isTopLevel
? isInvocation
? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE
: HighlightRegionType.TOP_LEVEL_FUNCTION_TEAR_OFF
: isInvocation
? HighlightRegionType.LOCAL_FUNCTION_REFERENCE
: HighlightRegionType.LOCAL_FUNCTION_TEAR_OFF;
type = isTopLevel
? isInvocation
? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE
: HighlightRegionType.TOP_LEVEL_FUNCTION_TEAR_OFF
: isInvocation
? HighlightRegionType.LOCAL_FUNCTION_REFERENCE
: HighlightRegionType.LOCAL_FUNCTION_TEAR_OFF;
return _addRegion_token(nameToken, type);
}
@@ -412,10 +408,9 @@ class DartUnitHighlightsComputer {
return _addRegion_token(
nameToken,
HighlightRegionType.LABEL,
semanticTokenModifiers:
parent is! BreakStatement
? {SemanticTokenModifiers.declaration}
: null,
semanticTokenModifiers: parent is! BreakStatement
? {SemanticTokenModifiers.declaration}
: null,
);
}
@@ -424,10 +419,9 @@ class DartUnitHighlightsComputer {
return false;
}
// OK
var type =
element.type is DynamicType
? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE
: HighlightRegionType.LOCAL_VARIABLE_REFERENCE;
var type = element.type is DynamicType
? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE
: HighlightRegionType.LOCAL_VARIABLE_REFERENCE;
return _addRegion_token(nameToken, type);
}
@@ -447,15 +441,13 @@ class DartUnitHighlightsComputer {
// OK
HighlightRegionType type;
if (isStatic) {
type =
isInvocation
? HighlightRegionType.STATIC_METHOD_REFERENCE
: HighlightRegionType.STATIC_METHOD_TEAR_OFF;
type = isInvocation
? HighlightRegionType.STATIC_METHOD_REFERENCE
: HighlightRegionType.STATIC_METHOD_TEAR_OFF;
} else {
type =
isInvocation
? HighlightRegionType.INSTANCE_METHOD_REFERENCE
: HighlightRegionType.INSTANCE_METHOD_TEAR_OFF;
type = isInvocation
? HighlightRegionType.INSTANCE_METHOD_REFERENCE
: HighlightRegionType.INSTANCE_METHOD_TEAR_OFF;
}
return _addRegion_token(nameToken, type);
}
@@ -468,21 +460,20 @@ class DartUnitHighlightsComputer {
if (element is! FormalParameterElement) {
return false;
}
var type =
element.type is DynamicType
? HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE
: HighlightRegionType.PARAMETER_REFERENCE;
var modifiers =
parent is Label ? {CustomSemanticTokenModifiers.label} : null;
var type = element.type is DynamicType
? HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE
: HighlightRegionType.PARAMETER_REFERENCE;
var modifiers = parent is Label
? {CustomSemanticTokenModifiers.label}
: null;
return _addRegion_token(nameToken, type, semanticTokenModifiers: modifiers);
}
bool _addIdentifierRegion_typeAlias(Token nameToken, Element? element) {
if (element is TypeAliasElement) {
var type =
element.aliasedType is FunctionType
? HighlightRegionType.FUNCTION_TYPE_ALIAS
: HighlightRegionType.TYPE_ALIAS;
var type = element.aliasedType is FunctionType
? HighlightRegionType.FUNCTION_TYPE_ALIAS
: HighlightRegionType.TYPE_ALIAS;
return _addRegion_token(nameToken, type);
}
return false;
@@ -1420,20 +1411,17 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
HighlightRegionType nameType;
if (node.isGetter) {
nameType =
node.isStatic
? HighlightRegionType.STATIC_GETTER_DECLARATION
: HighlightRegionType.INSTANCE_GETTER_DECLARATION;
nameType = node.isStatic
? HighlightRegionType.STATIC_GETTER_DECLARATION
: HighlightRegionType.INSTANCE_GETTER_DECLARATION;
} else if (node.isSetter) {
nameType =
node.isStatic
? HighlightRegionType.STATIC_SETTER_DECLARATION
: HighlightRegionType.INSTANCE_SETTER_DECLARATION;
nameType = node.isStatic
? HighlightRegionType.STATIC_SETTER_DECLARATION
: HighlightRegionType.INSTANCE_SETTER_DECLARATION;
} else {
nameType =
node.isStatic
? HighlightRegionType.STATIC_METHOD_DECLARATION
: HighlightRegionType.INSTANCE_METHOD_DECLARATION;
nameType = node.isStatic
? HighlightRegionType.STATIC_METHOD_DECLARATION
: HighlightRegionType.INSTANCE_METHOD_DECLARATION;
}
computer._addRegion_token(node.name, nameType);
@@ -138,13 +138,12 @@ class DartLazyTypeHierarchyComputer {
var mixins = type.mixins;
var superclassConstraints = type.superclassConstraints;
var supertypes =
[
if (supertype != null) TypeHierarchyRelatedItem.extends_(supertype),
...superclassConstraints.map(TypeHierarchyRelatedItem.constrainedTo),
...interfaces.map(TypeHierarchyRelatedItem.implements),
...mixins.map(TypeHierarchyRelatedItem.mixesIn),
].nonNulls.toList();
var supertypes = [
if (supertype != null) TypeHierarchyRelatedItem.extends_(supertype),
...superclassConstraints.map(TypeHierarchyRelatedItem.constrainedTo),
...interfaces.map(TypeHierarchyRelatedItem.implements),
...mixins.map(TypeHierarchyRelatedItem.mixesIn),
].nonNulls.toList();
return supertypes;
}
@@ -321,8 +321,9 @@ class DartUnitOutlineComputer {
var name = nameToken.lexeme;
var aliasedType = node.type;
var aliasedFunctionType =
aliasedType is GenericFunctionType ? aliasedType : null;
var aliasedFunctionType = aliasedType is GenericFunctionType
? aliasedType
: null;
var element = Element(
aliasedFunctionType != null
@@ -335,14 +336,12 @@ class DartUnitOutlineComputer {
),
aliasedType: _safeToSource(aliasedType),
location: _getLocationToken(nameToken),
parameters:
aliasedFunctionType != null
? _safeToSource(aliasedFunctionType.parameters)
: null,
returnType:
aliasedFunctionType != null
? _safeToSource(aliasedFunctionType.returnType)
: null,
parameters: aliasedFunctionType != null
? _safeToSource(aliasedFunctionType.parameters)
: null,
returnType: aliasedFunctionType != null
? _safeToSource(aliasedFunctionType.returnType)
: null,
typeParameters: _getTypeParametersStr(node.typeParameters),
);
@@ -48,19 +48,17 @@ class DartUnitOverridesComputer {
var superElements = overridesResult.superElements;
var interfaceElements = overridesResult.interfaceElements;
if (superElements.isNotEmpty || interfaceElements.isNotEmpty) {
var superMember =
superElements.isNotEmpty
? proto.newOverriddenMember_fromEngine(
superElements.first.nonSynthetic,
)
: null;
var interfaceMembers =
interfaceElements
.map(
(member) =>
proto.newOverriddenMember_fromEngine(member.nonSynthetic),
)
.toList();
var superMember = superElements.isNotEmpty
? proto.newOverriddenMember_fromEngine(
superElements.first.nonSynthetic,
)
: null;
var interfaceMembers = interfaceElements
.map(
(member) =>
proto.newOverriddenMember_fromEngine(member.nonSynthetic),
)
.toList();
_overrides.add(
proto.Override(
token.offset,
@@ -43,8 +43,9 @@ class DartUnitSignatureComputer {
if (parent is MethodInvocation) {
name = parent.methodName.name;
element = ElementLocator.locate(parent);
parameters =
element is FunctionTypedElement ? element.formalParameters : null;
parameters = element is FunctionTypedElement
? element.formalParameters
: null;
} else if (parent is InstanceCreationExpression) {
name = parent.constructorName.type.qualifiedName;
var constructorName = parent.constructorName.name;
@@ -52,8 +53,9 @@ class DartUnitSignatureComputer {
name += '.${constructorName.name}';
}
element = ElementLocator.locate(parent);
parameters =
element is FunctionTypedElement ? element.formalParameters : null;
parameters = element is FunctionTypedElement
? element.formalParameters
: null;
} else if (parent case FunctionExpressionInvocation(
function: Identifier function,
)) {
@@ -83,11 +85,10 @@ class DartUnitSignatureComputer {
// If we're not a named expression, then we can count how many positional
// parameters there are before us, and then find the index of the same
// index positional parameter.
var positionalArgsToSkip =
argumentList.arguments
.where((argument) => argument is! NamedExpression)
.takeWhile((argument) => argument.end < _offset)
.length;
var positionalArgsToSkip = argumentList.arguments
.where((argument) => argument is! NamedExpression)
.takeWhile((argument) => argument.end < _offset)
.length;
for (var i = 0; i < parameters.length; i++) {
if (parameters[i].isPositional) {
// This is the first positional parameter after our skips, so this is
@@ -88,20 +88,15 @@ class DartTypeArgumentsSignatureComputer {
String? documentation,
List<TypeParameterElement> typeParameters,
) {
var parameters =
typeParameters
.map(
(param) =>
lsp.ParameterInformation(label: param.displayString()),
)
.toList();
var parameters = typeParameters
.map((param) => lsp.ParameterInformation(label: param.displayString()))
.toList();
var signature = lsp.SignatureInformation(
label: label,
documentation:
documentation != null
? asMarkupContentOrString(preferredFormats, documentation)
: null,
documentation: documentation != null
? asMarkupContentOrString(preferredFormats, documentation)
: null,
parameters: parameters,
);
@@ -389,8 +389,9 @@ class ContextManagerImpl implements ContextManager {
var analysisOptions = driver.getAnalysisOptionsForFile(file);
var content = file.readAsStringSync();
var lineInfo = LineInfo.fromContent(content);
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
var sdkVersionConstraint = (package is PubPackage)
? package.sdkVersionConstraint
: null;
var errors = analyzeAnalysisOptions(
FileSource(file),
content,
@@ -582,22 +583,21 @@ class ContextManagerImpl implements ContextManager {
_fileContentCache.invalidateAll();
var watchers = <ResourceWatcher>[];
var collection =
_collection = AnalysisContextCollectionImpl(
includedPaths: includedPaths,
excludedPaths: excludedPaths,
byteStore: _byteStore,
drainStreams: false,
enableIndex: true,
performanceLog: _performanceLog,
resourceProvider: resourceProvider,
scheduler: _scheduler,
sdkPath: sdkManager.defaultSdkDirectory,
packagesFile: packagesFile,
fileContentCache: _fileContentCache,
unlinkedUnitStore: _unlinkedUnitStore,
enabledExperiments: _enabledExperiments,
);
var collection = _collection = AnalysisContextCollectionImpl(
includedPaths: includedPaths,
excludedPaths: excludedPaths,
byteStore: _byteStore,
drainStreams: false,
enableIndex: true,
performanceLog: _performanceLog,
resourceProvider: resourceProvider,
scheduler: _scheduler,
sdkPath: sdkManager.defaultSdkDirectory,
packagesFile: packagesFile,
fileContentCache: _fileContentCache,
unlinkedUnitStore: _unlinkedUnitStore,
enabledExperiments: _enabledExperiments,
);
for (var analysisContext in collection.contexts) {
var driver = analysisContext.driver;
@@ -671,37 +671,35 @@ class ContextManagerImpl implements ContextManager {
// Create temporary watchers before we start the context build so we can
// tell if any files were modified while waiting for the "real" watchers to
// become ready and start the process again.
var temporaryWatchers =
includedPaths
.map((path) => resourceProvider.getResource(path))
.map((resource) => resource.watch())
.toList();
var temporaryWatchers = includedPaths
.map((path) => resourceProvider.getResource(path))
.map((resource) => resource.watch())
.toList();
// If any watcher picks up an important change while we're running the
// rest of this method, we will need to start again.
var needsBuild = true;
var temporaryWatcherSubscriptions =
temporaryWatchers
.map(
(watcher) => watcher.changes.listen(
(event) {
if (shouldRestartBuild(event.path)) {
needsBuild = true;
}
},
onError: (error, stackTrace) {
// Errors in the watcher such as "Directory watcher closed
// unexpectedly" on Windows when the buffer overflows also
// require that we restarted to be consistent.
needsBuild = true;
_instrumentationService.logError(
'Temporary watcher error; restarting context build.\n'
'$error\n$stackTrace',
);
},
),
)
.toList();
var temporaryWatcherSubscriptions = temporaryWatchers
.map(
(watcher) => watcher.changes.listen(
(event) {
if (shouldRestartBuild(event.path)) {
needsBuild = true;
}
},
onError: (error, stackTrace) {
// Errors in the watcher such as "Directory watcher closed
// unexpectedly" on Windows when the buffer overflows also
// require that we restarted to be consistent.
needsBuild = true;
_instrumentationService.logError(
'Temporary watcher error; restarting context build.\n'
'$error\n$stackTrace',
);
},
),
)
.toList();
try {
// Ensure all watchers are ready before we begin any rebuild.
@@ -949,10 +947,9 @@ class ContextManagerImpl implements ContextManager {
class NoopContextManagerCallbacks implements ContextManagerCallbacks {
@override
AnalysisServer get analysisServer =>
throw StateError(
'The callback object should have been set by the server.',
);
AnalysisServer get analysisServer => throw StateError(
'The callback object should have been set by the server.',
);
@override
void afterContextsCreated() {}
@@ -24,11 +24,10 @@ void addDartOccurrences(OccurrencesCollector collector, CompilationUnit unit) {
// what is in the source.
var length =
serverElement.location?.length ?? engineElement.name?.length ?? 0;
var offsets =
nodes
.where((node) => node.length == length)
.map((node) => node.offset)
.toList();
var offsets = nodes
.where((node) => node.length == length)
.map((node) => node.offset)
.toList();
var occurrences = protocol.Occurrences(serverElement, offsets, length);
collector.addOccurrences(occurrences);
@@ -285,10 +284,9 @@ class DartUnitOccurrencesComputerVisitor extends GeneralizingAstVisitor<void> {
var element = node.element;
var pattern = node.pattern;
// If no explicit field name, use the variables name.
var name =
node.name?.name == null && pattern is VariablePattern
? pattern.name
: node.name?.name;
var name = node.name?.name == null && pattern is VariablePattern
? pattern.name
: node.name?.name;
if (element != null && name != null) {
_addOccurrence(element, name);
}
+12 -12
View File
@@ -36,14 +36,13 @@ String format(String content, {Version? languageVersion}) {
/// cause of the failure, a list of [Diagnostic]s.
ParseStringResult sortDirectives(String contents, {String? fileName}) {
var (unit, diagnostics) = _parse(contents, fullName: fileName);
var parseErrors =
diagnostics
.where(
(d) =>
d.diagnosticCode is ScannerErrorCode ||
d.diagnosticCode is ParserErrorCode,
)
.toList();
var parseErrors = diagnostics
.where(
(d) =>
d.diagnosticCode is ScannerErrorCode ||
d.diagnosticCode is ParserErrorCode,
)
.toList();
if (parseErrors.isNotEmpty) {
return ParseStringResultImpl(contents, unit, parseErrors);
}
@@ -63,10 +62,11 @@ ParseStringResult sortDirectives(String contents, {String? fileName}) {
sdkLanguageVersion: ExperimentStatus.currentVersion,
flags: [],
);
var scanner = Scanner(source, reader, diagnosticListener)..configureFeatures(
featureSetForOverriding: FeatureSet.latestLanguageVersion(),
featureSet: featureSet,
);
var scanner = Scanner(source, reader, diagnosticListener)
..configureFeatures(
featureSetForOverriding: FeatureSet.latestLanguageVersion(),
featureSet: featureSet,
);
var token = scanner.tokenize(reportScannerErrors: false);
var lineInfo = LineInfo(scanner.lineStarts);
var languageVersion = LibraryLanguageVersion(
@@ -20,11 +20,10 @@ class AnalysisGetErrorsHandler extends LegacyHandler {
@override
Future<void> handle() async {
var file =
AnalysisGetErrorsParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).file;
var file = AnalysisGetErrorsParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).file;
if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
return;
@@ -50,12 +50,11 @@ class AnalysisGetImportedElementsHandler extends LegacyHandler {
if (disableManageImportsOnPaste) {
elements = <ImportedElements>[];
} else {
elements =
ImportedElementsComputer(
result.unit,
params.offset,
params.length,
).compute();
elements = ImportedElementsComputer(
result.unit,
params.offset,
params.length,
).compute();
}
sendResult(AnalysisGetImportedElementsResult(elements));
@@ -41,10 +41,9 @@ Future<CompletionSuggestion?> candidateToCompletionSuggestion(
case TypedSuggestion():
var data = await createTypedSuggestionData(candidate, request);
requiredImports = data?.imports.toList() ?? requiredImports;
var kind =
request.target.isFunctionalArgument()
? CompletionSuggestionKind.IDENTIFIER
: null;
var kind = request.target.isFunctionalArgument()
? CompletionSuggestionKind.IDENTIFIER
: null;
candidate.data = data;
return switch (candidate) {
@@ -84,20 +83,20 @@ Future<CompletionSuggestion?> candidateToCompletionSuggestion(
),
MethodSuggestion(kind: var suggestionKind) =>
// TODO(brianwilkerson): Correctly set the kind of suggestion in cases
// where `isFunctionalArgument` would return `true` so we can stop
// using the `request.target`.
_getDartCompletionSuggestion(
candidate.element,
candidate.completion,
candidate.relevanceScore,
kind ?? suggestionKind,
request,
isNotImportedLibrary,
libraryUriStr,
requiredImports,
displayString: data?.displayText,
),
// TODO(brianwilkerson): Correctly set the kind of suggestion in cases
// where `isFunctionalArgument` would return `true` so we can stop
// using the `request.target`.
_getDartCompletionSuggestion(
candidate.element,
candidate.completion,
candidate.relevanceScore,
kind ?? suggestionKind,
request,
isNotImportedLibrary,
libraryUriStr,
requiredImports,
displayString: data?.displayText,
),
RecordFieldSuggestion() => DartCompletionSuggestion(
CompletionSuggestionKind.IDENTIFIER,
candidate.relevanceScore,
@@ -455,14 +454,14 @@ _ParameterData _createParameterData(e.Element element) {
bool? hasNamedParameters;
CompletionDefaultArgumentList? defaultArgumentList;
if (element is e.ExecutableElement && element is! e.PropertyAccessorElement) {
parameterNames =
element.formalParameters.map((parameter) {
return parameter.displayName;
}).toList();
parameterTypes =
element.formalParameters.map((e.FormalParameterElement parameter) {
return parameter.type.getDisplayString();
}).toList();
parameterNames = element.formalParameters.map((parameter) {
return parameter.displayName;
}).toList();
parameterTypes = element.formalParameters.map((
e.FormalParameterElement parameter,
) {
return parameter.type.getDisplayString();
}).toList();
var requiredParameters = element.formalParameters.where(
(e.FormalParameterElement param) => param.isRequiredPositional,
@@ -134,7 +134,8 @@ class EditGetAssistsHandler extends LegacyHandler
} on InconsistentAnalysisException {
// ignore
} catch (exception, stackTrace) {
var parametersFile = '''
var parametersFile =
'''
offset: $offset
length: $length
''';
@@ -125,8 +125,9 @@ class EditGetFixesHandler extends LegacyHandler
var package = analysisContext.contextRoot.workspace.findPackageFor(
optionsFile.path,
);
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
var sdkVersionConstraint = (package is PubPackage)
? package.sdkVersionConstraint
: null;
var diagnostics = analyzeAnalysisOptions(
FileSource(optionsFile),
content,
@@ -222,7 +223,8 @@ class EditGetFixesHandler extends LegacyHandler
} on InconsistentAnalysisException {
fixes = [];
} catch (exception, stackTrace) {
var parametersFile = '''
var parametersFile =
'''
offset: $offset
error: $diagnostic
error.errorCode: ${diagnostic.diagnosticCode}
@@ -21,13 +21,12 @@ class EditListPostfixCompletionTemplatesHandler extends LegacyHandler {
@override
Future<void> handle() async {
var templates =
DartPostfixCompletion.ALL_TEMPLATES
.map(
(PostfixCompletionKind kind) =>
PostfixTemplateDescriptor(kind.name, kind.key, kind.example),
)
.toList();
var templates = DartPostfixCompletion.ALL_TEMPLATES
.map(
(PostfixCompletionKind kind) =>
PostfixTemplateDescriptor(kind.name, kind.key, kind.example),
)
.toList();
sendResult(EditListPostfixCompletionTemplatesResult(templates));
}
}
@@ -20,11 +20,10 @@ class ExecutionCreateContextHandler extends LegacyHandler {
@override
Future<void> handle() async {
var file =
ExecutionCreateContextParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).contextRoot;
var file = ExecutionCreateContextParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).contextRoot;
var executionContext = server.executionContext;
var contextId = (executionContext.nextContextId++).toString();
executionContext.contextMap[contextId] = file;
@@ -20,11 +20,10 @@ class ExecutionDeleteContextHandler extends LegacyHandler {
@override
Future<void> handle() async {
var contextId =
ExecutionDeleteContextParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).id;
var contextId = ExecutionDeleteContextParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).id;
server.executionContext.contextMap.remove(contextId);
sendResult(ExecutionDeleteContextResult());
}
@@ -40,14 +40,14 @@ class LspOverLegacyHandler extends LegacyHandler {
var reporter = LspJsonReporter();
var lspMessage =
lspMessageJson is Map<String, Object?> &&
RequestMessage.canParse(lspMessageJson, reporter)
? RequestMessage.fromJson({
// Pass across any clientRequestTime from the envelope so that we
// can record latency for LSP-over-Legacy requests.
'clientRequestTime': request.clientRequestTime,
...lspMessageJson,
})
: null;
RequestMessage.canParse(lspMessageJson, reporter)
? RequestMessage.fromJson({
// Pass across any clientRequestTime from the envelope so that we
// can record latency for LSP-over-Legacy requests.
'clientRequestTime': request.clientRequestTime,
...lspMessageJson,
})
: null;
if (lspMessage != null) {
server.analyticsManager.startedRequestMessage(
@@ -74,22 +74,21 @@ class SearchGetElementDeclarationsHandler extends LegacyHandler {
).compute();
var declarations = workspaceSymbols.declarations;
var elementDeclarations =
declarations.map((declaration) {
return protocol.ElementDeclaration(
declaration.name,
getElementKind(declaration.kind),
declaration.fileIndex,
declaration.offset,
declaration.line,
declaration.column,
declaration.codeOffset,
declaration.codeLength,
className: declaration.className,
mixinName: declaration.mixinName,
parameters: declaration.parameters,
);
}).toList();
var elementDeclarations = declarations.map((declaration) {
return protocol.ElementDeclaration(
declaration.name,
getElementKind(declaration.kind),
declaration.fileIndex,
declaration.offset,
declaration.line,
declaration.column,
declaration.codeOffset,
declaration.codeLength,
className: declaration.className,
mixinName: declaration.mixinName,
parameters: declaration.parameters,
);
}).toList();
server.sendResponse(
protocol.SearchGetElementDeclarationsResult(
@@ -20,11 +20,10 @@ class ServerCancelRequestHandler extends LegacyHandler {
@override
Future<void> handle() async {
var id =
ServerCancelRequestParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).id;
var id = ServerCancelRequestParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).id;
server.cancelRequest(id);
sendResult(ServerCancelRequestResult());
}
@@ -22,11 +22,10 @@ class ServerSetSubscriptionsHandler extends LegacyHandler {
@override
Future<void> handle() async {
try {
server.serverServices =
ServerSetSubscriptionsParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).subscriptions.toSet();
server.serverServices = ServerSetSubscriptionsParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).subscriptions.toSet();
server.requestStatistics?.isNotificationSubscribed = server.serverServices
.contains(ServerService.LOG);
} on RequestFailure catch (exception) {
@@ -777,14 +777,14 @@ class LegacyAnalysisServer extends AnalysisServer {
return lspResponse is Map<String, Object?>
? lsp.ResponseMessage.fromJson(lspResponse)
: lsp.ResponseMessage(
jsonrpc: lsp.jsonRpcVersion,
error: lsp.ResponseError(
code: lsp.ServerErrorCodes.UnhandledError,
message:
"The client responded to a '$method' LSP request but"
' did not include a valid response in the lspResponse field',
),
);
jsonrpc: lsp.jsonRpcVersion,
error: lsp.ResponseError(
code: lsp.ServerErrorCodes.UnhandledError,
message:
"The client responded to a '$method' LSP request but"
' did not include a valid response in the lspResponse field',
),
);
}
/// Send the given [notification] to the client.
@@ -157,14 +157,13 @@ class LspClientConfiguration {
/// Gets the path for the WorkspaceFolder closest to [resourcePath].
String? _getWorkspaceFolderPath(String resourcePath) {
var candidates =
_resourceSettings.keys
.where(
(wfPath) =>
wfPath == _normaliseFolderPath(resourcePath) ||
pathContext.isWithin(wfPath, resourcePath),
)
.toList();
var candidates = _resourceSettings.keys
.where(
(wfPath) =>
wfPath == _normaliseFolderPath(resourcePath) ||
pathContext.isWithin(wfPath, resourcePath),
)
.toList();
candidates.sort((a, b) => -a.length.compareTo(b.length));
return candidates.firstOrNull;
}
@@ -341,13 +340,12 @@ class LspGlobalClientConfiguration extends LspResourceClientConfiguration {
///
/// [showAllTodos] should be checked first, as this will return an empty
/// set if `showTodos` is a boolean.
Set<String> get showTodoTypes =>
_settings['showTodos'] is List
? (_settings['showTodos'] as List)
.cast<String>()
.map((kind) => kind.toUpperCase())
.toSet()
: const {};
Set<String> get showTodoTypes => _settings['showTodos'] is List
? (_settings['showTodos'] as List)
.cast<String>()
.map((kind) => kind.toUpperCase())
.toSet()
: const {};
}
/// Wraps the client (editor) configuration for a specific resource.
@@ -191,10 +191,9 @@ lsp.CompletionItem? toLspCompletionItem(
//
// In the case of show combinators, the parens will still be shown to indicate
// functions but they should not be included in the completions.
var element =
suggestion is ElementBasedSuggestion
? (suggestion as ElementBasedSuggestion).element
: null;
var element = suggestion is ElementBasedSuggestion
? (suggestion as ElementBasedSuggestion).element
: null;
var isCallable =
element != null &&
(element is ConstructorElement ||
@@ -238,10 +237,9 @@ lsp.CompletionItem? toLspCompletionItem(
// TODO(dantup): Consider including more of these raw fields in the original
// suggestion to avoid needing to manipulate them in this way here.
var filterText =
!label.startsWith(completionFilterTextSplitPattern)
? label.split(completionFilterTextSplitPattern).first.trim()
: label;
var filterText = !label.startsWith(completionFilterTextSplitPattern)
? label.split(completionFilterTextSplitPattern).first.trim()
: label;
// If we're using label details, we also don't want the label to include any
// additional symbols as noted above, because they will appear in the extra
@@ -266,18 +264,17 @@ lsp.CompletionItem? toLspCompletionItem(
var colorPreviewHex =
capabilities.completionItemKinds.contains(lsp.CompletionItemKind.Color) &&
suggestion is ElementBasedSuggestion
? server.getColorHexString(element)
: null;
suggestion is ElementBasedSuggestion
? server.getColorHexString(element)
: null;
var completionKind =
colorPreviewHex != null
? lsp.CompletionItemKind.Color
: _candidateToCompletionItemKind(
capabilities.completionItemKinds,
suggestion,
label,
);
var completionKind = colorPreviewHex != null
? lsp.CompletionItemKind.Color
: _candidateToCompletionItemKind(
capabilities.completionItemKinds,
suggestion,
label,
);
var labelDetails = _getCompletionDetail(
suggestion,
@@ -305,10 +302,9 @@ lsp.CompletionItem? toLspCompletionItem(
var element = (suggestion as ElementBasedSuggestion).element;
if (element is ExecutableElement && element is! PropertyAccessorElement) {
parameterNames =
element.formalParameters.map((parameter) {
return parameter.displayName;
}).toList();
parameterNames = element.formalParameters.map((parameter) {
return parameter.displayName;
}).toList();
var requiredParameters = element.formalParameters.where(
(FormalParameterElement param) => param.isRequiredPositional,
@@ -328,10 +324,9 @@ lsp.CompletionItem? toLspCompletionItem(
}
var completion = suggestion.completion;
var selectionOffset =
(suggestion is KeywordSuggestion)
? suggestion.selectionOffset
: completion.length;
var selectionOffset = (suggestion is KeywordSuggestion)
? suggestion.selectionOffset
: completion.length;
var selectionLength = 0;
if (suggestion is SuggestionData) {
@@ -361,10 +356,9 @@ lsp.CompletionItem? toLspCompletionItem(
// To improve the display of some items (like pubspec version numbers),
// short labels in the format `_foo_` in docComplete are "upgraded" to the
// detail field.
var labelMatch =
cleanedDoc != null
? upgradableDocCompletePattern.firstMatch(cleanedDoc)
: null;
var labelMatch = cleanedDoc != null
? upgradableDocCompletePattern.firstMatch(cleanedDoc)
: null;
if (labelMatch != null) {
cleanedDoc = null;
labelDetails = (
@@ -398,50 +392,46 @@ lsp.CompletionItem? toLspCompletionItem(
]),
data: resolutionData,
detail: labelDetails.detail.nullIfEmpty,
labelDetails:
useLabelDetails
? lsp.CompletionItemLabelDetails(
detail: labelDetails.truncatedSignature.nullIfEmpty,
description: getCompletionDisplayUriString(
uriConverter: uriConverter,
pathContext: pathContext,
elementLibraryUri: labelDetails.autoImportUri,
completionFilePath: completionFilePath,
),
).nullIfEmpty
: null,
documentation:
cleanedDoc != null
? asMarkupContentOrString(formats, cleanedDoc)
: null,
labelDetails: useLabelDetails
? lsp.CompletionItemLabelDetails(
detail: labelDetails.truncatedSignature.nullIfEmpty,
description: getCompletionDisplayUriString(
uriConverter: uriConverter,
pathContext: pathContext,
elementLibraryUri: labelDetails.autoImportUri,
completionFilePath: completionFilePath,
),
).nullIfEmpty
: null,
documentation: cleanedDoc != null
? asMarkupContentOrString(formats, cleanedDoc)
: null,
deprecated: supportsCompletionDeprecatedFlag && isDeprecated ? true : null,
sortText: relevanceToSortText(suggestion.relevanceScore),
filterText: filterText.orNullIfSameAs(
label,
), // filterText uses label if not set
insertTextFormat:
insertTextFormat != lsp.InsertTextFormat.PlainText
? insertTextFormat
: null, // Defaults to PlainText if not supplied
insertTextFormat: insertTextFormat != lsp.InsertTextFormat.PlainText
? insertTextFormat
: null, // Defaults to PlainText if not supplied
insertTextMode:
!hasDefaultTextMode && supportsAsIsInsertMode && isMultilineCompletion
? lsp.InsertTextMode.asIs
: null,
? lsp.InsertTextMode.asIs
: null,
// When using defaults for edit range, don't use textEdit.
textEdit:
hasDefaultEditRange
? null
: supportsInsertReplace && insertionRange != replacementRange
? lsp.Either2<lsp.InsertReplaceEdit, lsp.TextEdit>.t1(
lsp.InsertReplaceEdit(
insert: insertionRange,
replace: replacementRange,
newText: insertText,
),
)
: lsp.Either2<lsp.InsertReplaceEdit, lsp.TextEdit>.t2(
lsp.TextEdit(range: replacementRange, newText: insertText),
textEdit: hasDefaultEditRange
? null
: supportsInsertReplace && insertionRange != replacementRange
? lsp.Either2<lsp.InsertReplaceEdit, lsp.TextEdit>.t1(
lsp.InsertReplaceEdit(
insert: insertionRange,
replace: replacementRange,
newText: insertText,
),
)
: lsp.Either2<lsp.InsertReplaceEdit, lsp.TextEdit>.t2(
lsp.TextEdit(range: replacementRange, newText: insertText),
),
// When using defaults for edit range, use textEditText.
textEditText: hasDefaultEditRange ? insertText.orNullIfSameAs(label) : null,
);
@@ -490,13 +480,13 @@ lsp.CompletionItemKind? _candidateToCompletionItemKind(
if (!label.startsWith('dart:')) {
return label.endsWith('.dart')
? const [
lsp.CompletionItemKind.File,
lsp.CompletionItemKind.Module,
]
lsp.CompletionItemKind.File,
lsp.CompletionItemKind.Module,
]
: const [
lsp.CompletionItemKind.Folder,
lsp.CompletionItemKind.Module,
];
lsp.CompletionItemKind.Folder,
lsp.CompletionItemKind.Module,
];
}
return const [lsp.CompletionItemKind.Module];
default:
@@ -603,10 +593,9 @@ CompletionDetail _getCompletionDetail(
} else if (suggestion is RecordFieldSuggestion) {
returnType = suggestion.field.type.getDisplayString();
}
var element =
suggestion is ElementBasedSuggestion
? (suggestion as ElementBasedSuggestion).element
: null;
var element = suggestion is ElementBasedSuggestion
? (suggestion as ElementBasedSuggestion).element
: null;
// Usually getter/setters look the same in completion because they insert the
// same text. This is not the case for overrides because they will insert
@@ -702,8 +691,9 @@ CompletionDetail _getCompletionDetail(
isNotImported = importData.isNotImported;
}
}
var autoImportUri =
isNotImported && libraryUri.isNotEmpty ? Uri.parse(libraryUri) : null;
var autoImportUri = isNotImported && libraryUri.isNotEmpty
? Uri.parse(libraryUri)
: null;
return (
detail: detail,
@@ -757,43 +747,41 @@ String? _getDocumentation(
var docs = _getDocsFromComputer(element, request);
var doc = removeDartDocDelimiters(docs?.full);
var rawDoc =
includeDocumentation == DocumentationPreference.full
? doc
: includeDocumentation == DocumentationPreference.summary
? getDartDocSummary(docs?.summary)
: null;
var rawDoc = includeDocumentation == DocumentationPreference.full
? doc
: includeDocumentation == DocumentationPreference.summary
? getDartDocSummary(docs?.summary)
: null;
return cleanDartdoc(rawDoc);
}
/// Additional details about a completion that may be formatted differently
/// depending on the client capabilities.
typedef CompletionDetail =
({
/// Additional details to go in the details popup.
///
/// This is usually a full signature (with full parameters) and may also
/// include whether the item is deprecated if the client did not support the
/// native deprecated tag.
String detail,
typedef CompletionDetail = ({
/// Additional details to go in the details popup.
///
/// This is usually a full signature (with full parameters) and may also
/// include whether the item is deprecated if the client did not support the
/// native deprecated tag.
String detail,
/// Truncated parameters. Similar to [truncatedSignature] but does not
/// include return types. Used in clients that cannot format signatures
/// differently and is appended immediately after the completion label. The
/// return type is omitted to reduce noise because this text is not subtle.
String truncatedParams,
/// Truncated parameters. Similar to [truncatedSignature] but does not
/// include return types. Used in clients that cannot format signatures
/// differently and is appended immediately after the completion label. The
/// return type is omitted to reduce noise because this text is not subtle.
String truncatedParams,
/// A signature with truncated params. Used for showing immediately after
/// the completion label when it can be formatted differently.
///
/// () String
String truncatedSignature,
/// A signature with truncated params. Used for showing immediately after
/// the completion label when it can be formatted differently.
///
/// () String
String truncatedSignature,
/// The URI that will be auto-imported if this item is selected in a
/// user-friendly string format (for example a relative path if for a `file:/`
/// URI).
Uri? autoImportUri,
});
/// The URI that will be auto-imported if this item is selected in a
/// user-friendly string format (for example a relative path if for a `file:/`
/// URI).
Uri? autoImportUri,
});
class _ElementDocumentation {
final String full;
@@ -27,8 +27,11 @@ import 'package:meta/meta.dart';
typedef CodeActionWithPriority = ({CodeAction action, int priority});
typedef CodeActionWithPriorityAndIndex =
({CodeAction action, int priority, int index});
typedef CodeActionWithPriorityAndIndex = ({
CodeAction action,
int priority,
int index,
});
/// A base for classes that produce [CodeAction]s for the LSP handler.
abstract class AbstractCodeActionsProducer
@@ -78,8 +78,9 @@ class AnalysisOptionsCodeActionsProducer extends AbstractCodeActionsProducer {
var contextRoot = session.analysisContext.contextRoot;
var package = contextRoot.workspace.findPackageFor(optionsFile.path);
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
var sdkVersionConstraint = (package is PubPackage)
? package.sdkVersionConstraint
: null;
var errors = analyzeAnalysisOptions(
FileSource(optionsFile),
@@ -366,15 +366,10 @@ class _CodeActionSorter {
var dedupedActions = _dedupeActions(actions, range.start);
// Add each index so we can do a stable sort on priority.
var dedupedActionsWithIndex =
dedupedActions.indexed.map((item) {
var (index, action) = item;
return (
action: action.action,
priority: action.priority,
index: index,
);
}).toList();
var dedupedActionsWithIndex = dedupedActions.indexed.map((item) {
var (index, action) = item;
return (action: action.action, priority: action.priority, index: index);
}).toList();
dedupedActionsWithIndex.sort(_compareCodeActions);
return dedupedActionsWithIndex.map((action) => action.action).toList();
@@ -488,7 +483,7 @@ class _CodeActionSorter {
return firstLiteral.edit != null
? firstLiteral.edit == other.edit
: firstLiteral.command != null &&
firstLiteral.command == other.command;
firstLiteral.command == other.command;
});
// Build a new CodeAction that merges the diagnostics from each same
@@ -208,8 +208,9 @@ class DartCodeActionsProducer extends AbstractCodeActionsProducer {
try {
// If deduplicating the result only do the expensive "fix all in file"
// calculation when we haven't before.
Set<String>? skipAlreadyCalculatedIfNonNull =
willBeDeduplicated ? {} : null;
Set<String>? skipAlreadyCalculatedIfNonNull = willBeDeduplicated
? {}
: null;
var workspace = DartChangeWorkspace(await server.currentSessions);
CorrectionUtils? correctionUtils;
for (var error in unitResult.diagnostics) {
@@ -546,8 +547,12 @@ class DartCodeActionsProducer extends AbstractCodeActionsProducer {
) {
return allowCodeActionLiterals
? CodeAction.t1(
CodeActionLiteral(title: command.title, kind: kind, command: command),
)
CodeActionLiteral(
title: command.title,
kind: kind,
command: command,
),
)
: CodeAction.t2(command);
}
}
@@ -106,8 +106,9 @@ abstract class AbstractRefactorCommandHandler
// inject their own user-provided names until LSP has some native
// support:
// https://github.com/microsoft/language-server-protocol/issues/764
refactor.name =
options != null ? options['name'] as String : 'NewWidget';
refactor.name = options != null
? options['name'] as String
: 'NewWidget';
return success(refactor);
case RefactoringKind.INLINE_LOCAL_VARIABLE:
@@ -76,10 +76,9 @@ abstract class AbstractFixAllInWorkspaceCommandHandler
server,
clientCapabilities,
change,
annotateChanges:
requireConfirmation
? ChangeAnnotations.requireConfirmation
: ChangeAnnotations.include,
annotateChanges: requireConfirmation
? ChangeAnnotations.requireConfirmation
: ChangeAnnotations.include,
);
return sendWorkspaceEditToClient(edit);
}
@@ -12,18 +12,17 @@ import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/utilities/extensions/flutter.dart';
/// Information about the arguments and parameters for an invocation.
typedef EditableInvocationInfo =
({
AstNode invocation,
String? widgetName,
String? widgetDocumentation,
List<FormalParameterElement> parameters,
Map<FormalParameterElement, Expression> parameterArguments,
Map<FormalParameterElement, int> positionalParameterIndexes,
ArgumentList argumentList,
int numPositionals,
int numSuppliedPositionals,
});
typedef EditableInvocationInfo = ({
AstNode invocation,
String? widgetName,
String? widgetDocumentation,
List<FormalParameterElement> parameters,
Map<FormalParameterElement, Expression> parameterArguments,
Map<FormalParameterElement, int> positionalParameterIndexes,
ArgumentList argumentList,
int numPositionals,
int numSuppliedPositionals,
});
mixin EditableArgumentsMixin {
DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result);
@@ -115,10 +114,9 @@ mixin EditableArgumentsMixin {
}
var numPositionals = parameters.where((p) => p.isPositional).length;
var numSuppliedPositionals =
argumentList.arguments
.where((argument) => argument is! NamedExpression)
.length;
var numSuppliedPositionals = argumentList.arguments
.where((argument) => argument is! NamedExpression)
.length;
// Build a map of parameters to their positional index so we can tell
// whether a parameter that doesn't already have an argument will be
@@ -116,8 +116,9 @@ class EditArgumentHandler extends SharedMessageHandler<EditArgumentParams, Null>
}
var argument = parameterArguments[parameter];
var valueExpression =
argument is NamedExpression ? argument.expression : argument;
var valueExpression = argument is NamedExpression
? argument.expression
: argument;
// Determine whether a value for this parameter is editable.
var notEditableReason = getNotEditableReason(
@@ -179,10 +180,9 @@ class EditArgumentHandler extends SharedMessageHandler<EditArgumentParams, Null>
currentArgument is SimpleIdentifier ||
currentArgument == null;
var enumValue =
preferDotShorthand
? getDotShorthandEnumConstantName(enumConstant) ?? requestValue
: requestValue;
var enumValue = preferDotShorthand
? getDotShorthandEnumConstantName(enumConstant) ?? requestValue
: requestValue;
return enumValue.toString();
}
@@ -294,11 +294,10 @@ class EditArgumentHandler extends SharedMessageHandler<EditArgumentParams, Null>
// It is a bug if we produced edits in some file other than the one we
// expect.
var fileEdits = changeBuilder.sourceChange.edits;
var otherFilesEdited =
fileEdits
.map((edit) => edit.file)
.where((file) => file != result.path)
.toSet();
var otherFilesEdited = fileEdits
.map((edit) => edit.file)
.where((file) => file != result.path)
.toSet();
if (otherFilesEdited.isNotEmpty) {
var otherNames = otherFilesEdited.join(', ');
throw 'Argument edit for ${result.path} unexpectedly produced edits for $otherNames';
@@ -405,8 +404,9 @@ class EditArgumentHandler extends SharedMessageHandler<EditArgumentParams, Null>
// If this parameter is positional, we need to first ensure arguments for
// any earlier positional parameters are present.
if (parameter.isPositional) {
var existingPositionalArguments =
argumentList.arguments.where((a) => a is! NamedExpression).length;
var existingPositionalArguments = argumentList.arguments
.where((a) => a is! NamedExpression)
.length;
var unspecifiedPositionals = parameters
.where((p) => p.isPositional)
.skip(existingPositionalArguments)
@@ -422,8 +422,9 @@ class EditArgumentHandler extends SharedMessageHandler<EditArgumentParams, Null>
}
var parameterName = parameter.name;
var argumentNamePrefix =
parameter.isNamed && parameterName != null ? '$parameterName: ' : '';
var argumentNamePrefix = parameter.isNamed && parameterName != null
? '$parameterName: '
: '';
var argumentCode = '$argumentNamePrefix$newValueCode';
// Usually we insert at the end (after the last argument), but if the last
@@ -447,10 +448,9 @@ class EditArgumentHandler extends SharedMessageHandler<EditArgumentParams, Null>
lineInfo.getLocation(argumentList.rightParenthesis.offset).lineNumber;
// If we are multiline, indent one level more than the invocation.
var indent =
isMultiline
? '${utils.getLinePrefix(argumentList.leftParenthesis.offset)} '
: '';
var indent = isMultiline
? '${utils.getLinePrefix(argumentList.leftParenthesis.offset)} '
: '';
// The prefix we need depends on whether there is an argument before us
// and whether we are multiline.
@@ -161,8 +161,9 @@ class EditableArgumentsHandler
required int numPositionals,
required int numSuppliedPositionals,
}) {
var valueExpression =
argument is NamedExpression ? argument.expression : argument;
var valueExpression = argument is NamedExpression
? argument.expression
: argument;
// Lazily compute the values if we will use this parameter/argument.
late var values = _getValues(parameter, valueExpression);
@@ -40,10 +40,9 @@ class AugmentationHandler
return (unit, offset).mapResultsSync((unit, offset) {
// Find the nearest node that could have fragments.
var node =
unit.unit
.nodeCovering(offset: offset)
?.thisOrAncestorOfType<ast.Declaration>();
var node = unit.unit
.nodeCovering(offset: offset)
?.thisOrAncestorOfType<ast.Declaration>();
var location = fragmentToLocation(
uriConverter,
@@ -40,10 +40,9 @@ class AugmentedHandler
return (unit, offset).mapResultsSync((unit, offset) {
// Find the nearest node that could have fragments.
var node =
unit.unit
.nodeCovering(offset: offset)
?.thisOrAncestorOfType<ast.Declaration>();
var node = unit.unit
.nodeCovering(offset: offset)
?.thisOrAncestorOfType<ast.Declaration>();
var location = fragmentToLocation(
uriConverter,
@@ -39,10 +39,9 @@ class DartTextDocumentContentProviderHandler
var uri = params.uri;
if (!allowedSchemes.contains(uri.scheme)) {
var supportedSchemesString =
allowedSchemes.isEmpty
? '(none)'
: allowedSchemes.map((scheme) => "'$scheme'").join(', ');
var supportedSchemesString = allowedSchemes.isEmpty
? '(none)'
: allowedSchemes.map((scheme) => "'$scheme'").join(', ');
return error(
ErrorCodes.InvalidParams,
"Fetching content for scheme '${uri.scheme}' is not supported. "
@@ -49,9 +49,9 @@ class ImportsHandler
return unit != null
? success(unit)
: error(
ErrorCodes.InternalError,
'The library containing a path did not contain the path.',
);
ErrorCodes.InternalError,
'The library containing a path did not contain the path.',
);
});
var offset = unit.mapResultSync(
(unit) => toOffset(unit.unit.lineInfo, pos),
@@ -143,15 +143,13 @@ class ImportsHandler
var importPrefix = directive.prefix?.name;
if (importPrefix != prefix) continue;
var importedElement =
prefix == null
? import.namespace.get2(elementName)
: import.namespace.getPrefixed2(prefix, elementName);
var importedElement = prefix == null
? import.namespace.get2(elementName)
: import.namespace.getPrefixed2(prefix, elementName);
var isMatch =
element is MultiplyDefinedElement
? element.conflictingElements.contains(importedElement)
: element == importedElement;
var isMatch = element is MultiplyDefinedElement
? element.conflictingElements.contains(importedElement)
: element == importedElement;
if (isMatch) {
var uri = uriConverter.toClientUri(
@@ -540,7 +540,8 @@ extension on DirectiveUri {
DirectiveUriWithLibrary(:var source) => source.uri.toString(),
DirectiveUriWithRelativeUriString(:var relativeUriString) =>
relativeUriString,
DirectiveUri() =>
throw UnimplementedError('Unhandled instance of type $runtimeType'),
DirectiveUri() => throw UnimplementedError(
'Unhandled instance of type $runtimeType',
),
};
}
@@ -101,13 +101,12 @@ class IncomingCallHierarchyHandler
itemLineInfo,
supportedSymbolKinds: supportedSymbolKinds,
),
fromRanges:
calls.ranges
// For incoming calls, ranges are in the referenced item so we use
// itemLineInfo and not localLineInfo (which is for the original
// target we're collecting calls to).
.map((call) => sourceRangeToRange(itemLineInfo, call))
.toList(),
fromRanges: calls.ranges
// For incoming calls, ranges are in the referenced item so we use
// itemLineInfo and not localLineInfo (which is for the original
// target we're collecting calls to).
.map((call) => sourceRangeToRange(itemLineInfo, call))
.toList(),
);
}
}
@@ -174,13 +173,12 @@ class OutgoingCallHierarchyHandler
itemLineInfo,
supportedSymbolKinds: supportedSymbolKinds,
),
fromRanges:
calls.ranges
// For incoming calls, ranges are in original target so we use
// localLineInfo and not itemLineInfo (which is for call target
// the outbound call points to).
.map((call) => sourceRangeToRange(localLineInfo, call))
.toList(),
fromRanges: calls.ranges
// For incoming calls, ranges are in original target so we use
// localLineInfo and not itemLineInfo (which is for call target
// the outbound call points to).
.map((call) => sourceRangeToRange(localLineInfo, call))
.toList(),
);
}
}
@@ -43,8 +43,9 @@ class CodeActionHandler
}
var supportsLiterals = callerCapabilities.literalCodeActions;
var supportedKinds =
supportsLiterals ? callerCapabilities.codeActionKinds : null;
var supportedKinds = supportsLiterals
? callerCapabilities.codeActionKinds
: null;
var computer = CodeActionComputer(
server,
@@ -86,12 +87,12 @@ class CodeActionRegistrations extends FeatureRegistration
// signals code action literal support via the property
// `textDocument.codeAction.codeActionLiteralSupport`."
codeActionLiteralSupport
? Either2.t2(
CodeActionOptions(
codeActionKinds: DartCodeActionKind.serverSupportedKinds,
),
)
: Either2.t1(true);
? Either2.t2(
CodeActionOptions(
codeActionKinds: DartCodeActionKind.serverSupportedKinds,
),
)
: Either2.t1(true);
@override
bool get supportsDynamic => clientDynamic.codeActions;
@@ -71,10 +71,9 @@ class CompletionHandler
: suggestFromUnimportedLibraries =
server.initializationOptions?.suggestFromUnimportedLibraries ?? true {
var budgetMs = server.initializationOptions?.completionBudgetMilliseconds;
completionBudgetDuration =
budgetMs != null
? Duration(milliseconds: budgetMs)
: CompletionBudget.defaultDuration;
completionBudgetDuration = budgetMs != null
? Duration(milliseconds: budgetMs)
: CompletionBudget.defaultDuration;
}
@override
@@ -148,8 +147,9 @@ class CompletionHandler
offset,
) async {
var fileExtension = pathContext.extension(path);
var maxResults =
server.lspClientConfiguration.forResource(path).maxCompletionItems;
var maxResults = server.lspClientConfiguration
.forResource(path)
.maxCompletionItems;
CompletionPerformance? completionPerformance;
Future<ErrorOr<_CompletionResults>>? serverResultsFuture;
if (fileExtension == '.dart') {
@@ -216,18 +216,17 @@ class CompletionHandler
var maxRankedItems = math.max(maxResults - unrankedItems.length, 0);
var truncatedRankedItems =
untruncatedRankedItems.length <= maxRankedItems
? untruncatedRankedItems
: _truncateResults(
untruncatedRankedItems,
serverResults.targetPrefix,
maxRankedItems,
);
? untruncatedRankedItems
: _truncateResults(
untruncatedRankedItems,
serverResults.targetPrefix,
maxRankedItems,
);
var truncatedItems =
truncatedRankedItems
.map((item) => item.item)
.followedBy(unrankedItems)
.toList();
var truncatedItems = truncatedRankedItems
.map((item) => item.item)
.followedBy(unrankedItems)
.toList();
// If we're tracing performance (only Dart), record the number of results
// after truncation.
@@ -263,8 +262,9 @@ class CompletionHandler
}
return CompletionItemDefaults(
insertTextMode:
capabilities.completionDefaultTextMode ? InsertTextMode.asIs : null,
insertTextMode: capabilities.completionDefaultTextMode
? InsertTextMode.asIs
: null,
editRange: _computeDefaultEditRange(
capabilities,
insertionRange,
@@ -541,10 +541,9 @@ class CompletionHandler
resolutionData: resolutionInfo,
// Exclude docs if we will be providing them via
// `completionItem/resolve`, otherwise use users preference.
includeDocumentation:
resolutionInfo != null
? DocumentationPreference.none
: server.lspClientConfiguration.global.preferredDocumentation,
includeDocumentation: resolutionInfo != null
? DocumentationPreference.none
: server.lspClientConfiguration.global.preferredDocumentation,
);
}
@@ -562,8 +561,9 @@ class CompletionHandler
});
// Add in any snippets.
var snippetsEnabled =
server.lspClientConfiguration.forResource(unit.path).enableSnippets;
var snippetsEnabled = server.lspClientConfiguration
.forResource(unit.path)
.enableSnippets;
// We can only produce edits with edit builders for files inside
// the root, so skip snippets entirely if not.
var isEditableFile = unit.session.analysisContext.contextRoot.isAnalyzed(
@@ -658,47 +658,41 @@ class CompletionHandler
var fuzzyPattern = suggestions.targetPrefix;
var fuzzyMatcher = FuzzyMatcher(fuzzyPattern);
var completionItems =
suggestions.suggestions
.where(
(item) =>
fuzzyMatcher.score(item.displayText ?? item.completion) > 0,
)
.map((item) {
var resolutionInfo =
item.kind == CompletionSuggestionKind.PACKAGE_NAME
? PubPackageCompletionItemResolutionInfo(
// The completion for package names may contain a trailing
// ': ' for convenience, so if it's there, trim it off.
packageName: item.completion.split(':').first,
)
: null;
return toCompletionItem(
capabilities,
lineInfo,
item,
uriConverter: uriConverter,
pathContext: pathContext,
completionFilePath: filePath,
replacementRange: replacementRange,
insertionRange: insertionRange,
commitCharactersEnabled: false,
completeFunctionCalls: false,
// Exclude docs if we could provide them via
// `completionItem/resolve`, otherwise use users preference.
includeDocumentation:
resolutionInfo != null
? DocumentationPreference.none
: server
.lspClientConfiguration
.global
.preferredDocumentation,
// Add on any completion-kind-specific resolution data that will be
// used during resolve() calls to provide additional information.
resolutionData: resolutionInfo,
);
})
.toList();
var completionItems = suggestions.suggestions
.where(
(item) => fuzzyMatcher.score(item.displayText ?? item.completion) > 0,
)
.map((item) {
var resolutionInfo =
item.kind == CompletionSuggestionKind.PACKAGE_NAME
? PubPackageCompletionItemResolutionInfo(
// The completion for package names may contain a trailing
// ': ' for convenience, so if it's there, trim it off.
packageName: item.completion.split(':').first,
)
: null;
return toCompletionItem(
capabilities,
lineInfo,
item,
uriConverter: uriConverter,
pathContext: pathContext,
completionFilePath: filePath,
replacementRange: replacementRange,
insertionRange: insertionRange,
commitCharactersEnabled: false,
completeFunctionCalls: false,
// Exclude docs if we could provide them via
// `completionItem/resolve`, otherwise use users preference.
includeDocumentation: resolutionInfo != null
? DocumentationPreference.none
: server.lspClientConfiguration.global.preferredDocumentation,
// Add on any completion-kind-specific resolution data that will be
// used during resolve() calls to provide additional information.
resolutionData: resolutionInfo,
);
})
.toList();
return success(
_CompletionResults.unranked(completionItems, isIncomplete: false),
);
@@ -784,12 +778,10 @@ class CompletionHandler
// Skip the text comparisons if we don't have a prefix (plugin results, or
// just no prefix when completion was invoked).
var shouldInclude =
prefixLower.isEmpty
? (int index, _ScoredCompletionItem item) =>
index < maxCompletionCount
: (int index, _ScoredCompletionItem item) =>
index < maxCompletionCount || isExactMatch(item.item);
var shouldInclude = prefixLower.isEmpty
? (int index, _ScoredCompletionItem item) => index < maxCompletionCount
: (int index, _ScoredCompletionItem item) =>
index < maxCompletionCount || isExactMatch(item.item);
return items.whereIndexed(shouldInclude);
}
@@ -851,8 +843,9 @@ class CompletionRegistrations extends FeatureRegistration
CompletionRegistrationOptions(
documentSelector: dartFiles,
triggerCharacters: dartCompletionTriggerCharacters,
allCommitCharacters:
previewCommitCharacters ? dartCompletionCommitCharacters : null,
allCommitCharacters: previewCommitCharacters
? dartCompletionCommitCharacters
: null,
resolveProvider: true,
completionItem: ServerCompletionItemOptions(
labelDetailsSupport: true,
@@ -892,8 +885,9 @@ class CompletionRegistrations extends FeatureRegistration
@override
CompletionOptions get staticOptions => CompletionOptions(
triggerCharacters: dartCompletionTriggerCharacters,
allCommitCharacters:
previewCommitCharacters ? dartCompletionCommitCharacters : null,
allCommitCharacters: previewCommitCharacters
? dartCompletionCommitCharacters
: null,
resolveProvider: true,
completionItem: ServerCompletionItemOptions(labelDetailsSupport: true),
);
@@ -87,12 +87,9 @@ class CompletionResolveHandler
return cancelled(token);
}
var element =
elementReference != null
? await ElementLocation.decode(
elementReference,
).locateIn(session)
: null;
var element = elementReference != null
? await ElementLocation.decode(elementReference).locateIn(session)
: null;
var showName = element?.name;
if (element?.enclosingElement case InstanceElement(:var name)) {
@@ -111,10 +108,12 @@ class CompletionResolveHandler
}
var changes = builder.sourceChange;
var thisFilesChanges =
changes.edits.where((e) => e.file == file).toList();
var otherFilesChanges =
changes.edits.where((e) => e.file != file).toList();
var thisFilesChanges = changes.edits
.where((e) => e.file == file)
.toList();
var otherFilesChanges = changes.edits
.where((e) => e.file != file)
.toList();
// If this completion involves editing other files, we'll need to build
// a command that the client will call to apply those edits later.
@@ -145,10 +144,9 @@ class CompletionResolveHandler
server.lspClientConfiguration.global.preferredDocumentation,
);
// `dartDoc` can be both null or empty.
documentation =
dartDoc != null && dartDoc.isNotEmpty
? asMarkupContentOrString(formats, dartDoc)
: null;
documentation = dartDoc != null && dartDoc.isNotEmpty
? asMarkupContentOrString(formats, dartDoc)
: null;
}
String? detail = item.detail;
@@ -185,14 +183,13 @@ class CompletionResolveHandler
insertTextFormat: item.insertTextFormat,
insertTextMode: item.insertTextMode,
textEdit: item.textEdit,
additionalTextEdits:
thisFilesChanges
.expand(
(change) => sortSourceEditsForLsp(
change.edits,
).map((edit) => toTextEdit(result.lineInfo, edit)),
)
.toList(),
additionalTextEdits: thisFilesChanges
.expand(
(change) => sortSourceEditsForLsp(
change.edits,
).map((edit) => toTextEdit(result.lineInfo, edit)),
)
.toList(),
commitCharacters: item.commitCharacters,
command: command ?? item.command,
data: item.data,
@@ -233,10 +230,9 @@ class CompletionResolveHandler
kind: item.kind,
tags: item.tags,
detail: item.detail,
documentation:
description != null
? Either2<MarkupContent, String>.t2(description)
: null,
documentation: description != null
? Either2<MarkupContent, String>.t2(description)
: null,
deprecated: item.deprecated,
preselect: item.preselect,
sortText: item.sortText,
@@ -156,12 +156,11 @@ class DefinitionHandler
// Convert and filter the results using the correct type of Location class
// depending on the client capabilities.
if (supportsLocationLink) {
var convertedResults =
convert(
mergedTargets,
(NavigationTarget target) =>
_toLocationLink(mergedResults, lineInfo, target),
).nonNulls.toList();
var convertedResults = convert(
mergedTargets,
(NavigationTarget target) =>
_toLocationLink(mergedResults, lineInfo, target),
).nonNulls.toList();
var results = _filterResults(
convertedResults,
@@ -173,11 +172,10 @@ class DefinitionHandler
return success(TextDocumentDefinitionResult.t2(results));
} else {
var convertedResults =
convert(
mergedTargets,
(NavigationTarget target) => _toLocation(mergedResults, target),
).nonNulls.toList();
var convertedResults = convert(
mergedTargets,
(NavigationTarget target) => _toLocation(mergedResults, target),
).nonNulls.toList();
var results = _filterResults(
convertedResults,
@@ -210,14 +208,13 @@ class DefinitionHandler
// adjacent to the var keyword, so providing navigation to it is not useful).
// To prevent this, filter the list to only those on different lines (or
// different files).
var otherResults =
results
.where(
(element) =>
uriSelector(element) != sourceUri ||
rangeSelector(element).start.line != sourceLineNumber,
)
.toList();
var otherResults = results
.where(
(element) =>
uriSelector(element) != sourceUri ||
rangeSelector(element).start.line != sourceLineNumber,
)
.toList();
return otherResults.isNotEmpty ? otherResults : results;
}
@@ -306,12 +303,12 @@ class DefinitionHandler
return targetLineInfo != null
? navigationTargetToLocationLink(
region,
sourceLineInfo,
targetFileUri,
target,
targetLineInfo,
)
region,
sourceLineInfo,
targetFileUri,
target,
targetLineInfo,
)
: null;
}
@@ -89,11 +89,10 @@ class DocumentColorPresentationHandler
// We can only apply changes to the same file, so filter any change from the
// builder to only include this file, otherwise we may corrupt the users
// source (although hopefully we don't produce edits for other files).
var editsForThisFile =
builder.sourceChange.edits
.where((edit) => edit.file == unit.path)
.expand((edit) => edit.edits)
.toList();
var editsForThisFile = builder.sourceChange.edits
.where((edit) => edit.file == unit.path)
.expand((edit) => edit.edits)
.toList();
// LSP requires that we separate the main edit (changing the color code)
// from anything else (imports).
@@ -107,12 +106,9 @@ class DocumentColorPresentationHandler
return ColorPresentation(
label: '$typeName$invocationString',
textEdit: toTextEdit(unit.lineInfo, mainEdit),
additionalTextEdits:
otherEdits.isNotEmpty
? otherEdits
.map((edit) => toTextEdit(unit.lineInfo, edit))
.toList()
: null,
additionalTextEdits: otherEdits.isNotEmpty
? otherEdits.map((edit) => toTextEdit(unit.lineInfo, edit)).toList()
: null,
);
}
@@ -245,8 +241,9 @@ class DocumentColorPresentationHandler
return node.isConst;
} else if (node is SimpleIdentifier) {
var parent = node.parent;
var element =
parent is PrefixedIdentifier ? parent.element : node.element;
var element = parent is PrefixedIdentifier
? parent.element
: node.element;
return switch (element) {
PropertyAccessorElement(:var variable) => variable.isConst,
@@ -71,14 +71,13 @@ class DocumentHighlightsHandler
// No matches will return an empty list (not null) because that prevents
// the editor falling back to a text search.
var highlights =
matchingSet
.map(
(token) => DocumentHighlight(
range: toRange(unit.lineInfo, token.offset, token.length),
),
)
.toList();
var highlights = matchingSet
.map(
(token) => DocumentHighlight(
range: toRange(unit.lineInfo, token.offset, token.length),
),
)
.toList();
return success(highlights);
});
@@ -57,10 +57,9 @@ class DocumentSymbolHandler
) {
var codeRange = toRange(lineInfo, outline.codeOffset, outline.codeLength);
var nameLocation = outline.element.location;
var nameRange =
nameLocation != null
? toRange(lineInfo, nameLocation.offset, nameLocation.length)
: null;
var nameRange = nameLocation != null
? toRange(lineInfo, nameLocation.offset, nameLocation.length)
: null;
return DocumentSymbol(
name: toElementName(outline.element),
detail: outline.element.parameters,
@@ -68,12 +67,9 @@ class DocumentSymbolHandler
deprecated: outline.element.isDeprecated,
range: codeRange,
selectionRange: nameRange ?? codeRange,
children:
outline.children
?.map(
(child) => _asDocumentSymbol(supportedKinds, lineInfo, child),
)
.toList(),
children: outline.children
?.map((child) => _asDocumentSymbol(supportedKinds, lineInfo, child))
.toList(),
);
}
@@ -98,14 +98,13 @@ class ExecuteCommandHandler
var workDoneToken = params.workDoneToken;
ProgressReporter progress = ProgressReporter.noop;
if (server case LspAnalysisServer server) {
progress =
workDoneToken != null
? ProgressReporter.clientProvided(server, workDoneToken)
// Use editor client capabilities, as that's who gets progress
// notifications, not the caller.
: server.editorClientCapabilities?.workDoneProgress ?? false
? ProgressReporter.serverCreated(server)
: ProgressReporter.noop;
progress = workDoneToken != null
? ProgressReporter.clientProvided(server, workDoneToken)
// Use editor client capabilities, as that's who gets progress
// notifications, not the caller.
: server.editorClientCapabilities?.workDoneProgress ?? false
? ProgressReporter.serverCreated(server)
: ProgressReporter.noop;
}
// To make passing arguments easier in commands, instead of a
@@ -73,16 +73,12 @@ class FoldingHandler
// line mode below.
regions.sort((r1, r2) => r1.offset.compareTo(r2.offset));
var foldingRanges =
regions
.map(
(region) => _toFoldingRange(
lineInfo!,
region,
lineOnly: lineFoldingOnly,
),
)
.toList();
var foldingRanges = regions
.map(
(region) =>
_toFoldingRange(lineInfo!, region, lineOnly: lineFoldingOnly),
)
.toList();
// When in line-only mode, ranges that end on the same line that another
// ranges starts should be truncated to be on the line before (and if this
@@ -88,13 +88,12 @@ class FormatOnTypeRegistrations extends FeatureRegistration
Method get registrationMethod => Method.textDocument_onTypeFormatting;
@override
StaticOptions get staticOptions =>
enableFormatter
? DocumentOnTypeFormattingOptions(
firstTriggerCharacter: dartTypeFormattingCharacters.first,
moreTriggerCharacter: dartTypeFormattingCharacters.skip(1).toList(),
)
: null;
StaticOptions get staticOptions => enableFormatter
? DocumentOnTypeFormattingOptions(
firstTriggerCharacter: dartTypeFormattingCharacters.first,
moreTriggerCharacter: dartTypeFormattingCharacters.skip(1).toList(),
)
: null;
@override
bool get supportsDynamic => enableFormatter && clientDynamic.typeFormatting;
@@ -87,44 +87,37 @@ class ImplementationHandler
var locations = performance.run(
'filter and get location',
(_) =>
allSubtypes
.map((element) {
return needsMember
// Filter based on type, so when searching for members we don't
// include any intermediate classes that don't have
// implementations for the method.
? helper.findMemberElement(element)?.nonSynthetic
: element;
})
.nonNulls
.toSet()
.map((element) {
var firstFragment = element.firstFragment;
var libraryFragment = firstFragment.libraryFragment;
if (libraryFragment == null) {
return null;
}
(_) => allSubtypes
.map((element) {
return needsMember
// Filter based on type, so when searching for members we don't
// include any intermediate classes that don't have
// implementations for the method.
? helper.findMemberElement(element)?.nonSynthetic
: element;
})
.nonNulls
.toSet()
.map((element) {
var firstFragment = element.firstFragment;
var libraryFragment = firstFragment.libraryFragment;
if (libraryFragment == null) {
return null;
}
var nameOffset = firstFragment.nameOffset;
var name = firstFragment.name;
if (nameOffset == null || name == null) {
return null;
}
var nameOffset = firstFragment.nameOffset;
var name = firstFragment.name;
if (nameOffset == null || name == null) {
return null;
}
return Location(
uri: uriConverter.toClientUri(
libraryFragment.source.fullName,
),
range: toRange(
libraryFragment.lineInfo,
nameOffset,
name.length,
),
);
})
.nonNulls
.toList(),
return Location(
uri: uriConverter.toClientUri(libraryFragment.source.fullName),
range: toRange(libraryFragment.lineInfo, nameOffset, name.length),
);
})
.nonNulls
.toList(),
);
return success(locations);
@@ -24,8 +24,8 @@ class InitializedMessageHandler
MessageInfo message,
CancellationToken token,
) async {
var initializedHandler =
server.messageHandler = InitializedLspStateMessageHandler(server);
var initializedHandler = server.messageHandler =
InitializedLspStateMessageHandler(server);
server.analyticsManager.initialized(openWorkspacePaths: openWorkspacePaths);
@@ -274,13 +274,12 @@ class RenameHandler extends LspMessageHandler<RenameParams, WorkspaceEdit?> {
_isClassRename(refactoring)) {
// The rename must always be performed on the file that defines the
// class which is not necessarily the one where the rename was invoked.
var declaringFile =
(refactoring as RenameUnitMemberRefactoringImpl)
.element
.firstFragment
.libraryFragment
?.source
.fullName;
var declaringFile = (refactoring as RenameUnitMemberRefactoringImpl)
.element
.firstFragment
.libraryFragment
?.source
.fullName;
if (declaringFile != null) {
var folder = pathContext.dirname(declaringFile);
var actualFilename = pathContext.basename(declaringFile);
@@ -358,12 +357,9 @@ class RenameRegistrations extends FeatureRegistration
Method get registrationMethod => Method.textDocument_rename;
@override
StaticOptions get staticOptions =>
clientCapabilities.renameValidation
? Either2<bool, RenameOptions>.t2(
RenameOptions(prepareProvider: true),
)
: Either2<bool, RenameOptions>.t1(true);
StaticOptions get staticOptions => clientCapabilities.renameValidation
? Either2<bool, RenameOptions>.t2(RenameOptions(prepareProvider: true))
: Either2<bool, RenameOptions>.t1(true);
@override
bool get supportsDynamic => clientDynamic.rename;
@@ -40,8 +40,9 @@ class SelectionRangeHandler
var unit = await requireUnresolvedUnit(path);
return unit.mapResultSync((unit) {
var positions = params.positions;
var offsets =
positions.map((pos) => toOffset(unit.lineInfo, pos)).errorOrResults;
var offsets = positions
.map((pos) => toOffset(unit.lineInfo, pos))
.errorOrResults;
var allRanges = offsets.mapResultSync(
(offsets) => success(_getSelectionRangesForOffsets(offsets, unit)),
);
@@ -73,10 +73,9 @@ abstract class AbstractSemanticTokensHandler<T>
}
return toSourceRangeNullable(lineInfo, range).mapResult((range) async {
var serverTokens =
resolvedUnit != null
? await getServerResult(resolvedUnit.unit, range)
: <SemanticTokenInfo>[];
var serverTokens = resolvedUnit != null
? await getServerResult(resolvedUnit.unit, range)
: <SemanticTokenInfo>[];
var pluginHighlightRegions = getPluginResults(path).flattenedToList;
if (token.isCancellationRequested) {
@@ -102,8 +101,8 @@ abstract class AbstractSemanticTokensHandler<T>
// Some of the translation operations and the final encoding require
// the tokens to be sorted. Do it once here to avoid each method needing
// to do it itself (resulting in multiple sorts).
tokens =
tokens.toList()..sort(SemanticTokenInfo.offsetLengthPrioritySort);
tokens = tokens.toList()
..sort(SemanticTokenInfo.offsetLengthPrioritySort);
if (!allowOverlappingTokens) {
tokens = encoder.splitOverlappingTokens(tokens);
@@ -180,10 +180,9 @@ class TypeDefinitionHandler
_ => (null, null),
};
var codeRange =
codeOffset != null && codeLength != null
? toRange(targetUnit.lineInfo, codeOffset, codeLength)
: targetNameRange;
var codeRange = codeOffset != null && codeLength != null
? toRange(targetUnit.lineInfo, codeOffset, codeLength)
: targetNameRange;
return LocationLink(
originSelectionRange: toRange(
@@ -49,11 +49,10 @@ class WorkspaceSymbolHandler
}
var supportedSymbolKinds = clientCapabilities.workspaceSymbolKinds;
var searchOnlyAnalyzed =
!server
.lspClientConfiguration
.global
.includeDependenciesInWorkspaceSymbols;
var searchOnlyAnalyzed = !server
.lspClientConfiguration
.global
.includeDependenciesInWorkspaceSymbols;
// Cap the number of results we'll return because short queries may match
// huge numbers on large projects.
@@ -191,10 +191,9 @@ mixin HandlerHelperMixin<S extends AnalysisServer> {
var supportedSchemes = server.uriConverter.supportedSchemes;
var isValidScheme = supportedSchemes.contains(uri.scheme);
if (!isValidScheme) {
var supportedSchemesString =
supportedSchemes.isEmpty
? '(none)'
: supportedSchemes.map((scheme) => "'$scheme'").join(', ');
var supportedSchemesString = supportedSchemes.isEmpty
? '(none)'
: supportedSchemes.map((scheme) => "'$scheme'").join(', ');
return ErrorOr<String>.error(
ResponseError(
code: ServerErrorCodes.InvalidFilePath,
@@ -428,8 +427,9 @@ abstract class MessageHandler<P, R, S extends AnalysisServer>
);
}
var params =
paramsJson != null ? jsonHandler.convertParams(paramsJson) : null as P;
var params = paramsJson != null
? jsonHandler.convertParams(paramsJson)
: null as P;
return handle(params, messageInfo, token);
}
}
@@ -374,10 +374,8 @@ class LspAnalysisServer extends AnalysisServer {
) {
_clientCapabilities = LspClientCapabilities(capabilities);
_clientInfo = clientInfo;
var initializationOptions =
_initializationOptions = LspInitializationOptions(
rawInitializationOptions,
);
var initializationOptions = _initializationOptions =
LspInitializationOptions(rawInitializationOptions);
/// Enable virtual file support.
var supportsVirtualFiles =
@@ -533,14 +531,13 @@ class LspAnalysisServer extends AnalysisServer {
);
completer?.setComplete();
} catch (error, stackTrace) {
var errorMessage =
message is ResponseMessage
? 'An error occurred while handling the response to request ${message.id}'
: message is RequestMessage
? 'An error occurred while handling ${message.method} request'
: message is NotificationMessage
? 'An error occurred while handling ${message.method} notification'
: 'Unknown message type';
var errorMessage = message is ResponseMessage
? 'An error occurred while handling the response to request ${message.id}'
: message is RequestMessage
? 'An error occurred while handling ${message.method} request'
: message is NotificationMessage
? 'An error occurred while handling ${message.method} notification'
: 'Unknown message type';
sendErrorResponse(
message,
ResponseError(
@@ -579,8 +576,9 @@ class LspAnalysisServer extends AnalysisServer {
fullMessage = '$fullMessage: $exception';
}
var fullError =
stackTrace == null ? fullMessage : '$fullMessage\n$stackTrace';
var fullError = stackTrace == null
? fullMessage
: '$fullMessage\n$stackTrace';
stackTrace ??= StackTrace.current;
// Log the full message since showMessage above may be truncated or
@@ -1027,12 +1025,11 @@ class LspAnalysisServer extends AnalysisServer {
var packages = <String>{};
var additionalFiles = <String>[];
for (var file in openFiles) {
var package =
roots
.where((root) => root.isAnalyzed(file))
.map((root) => root.workspace.findPackageFor(file)?.root)
.nonNulls
.firstOrNull;
var package = roots
.where((root) => root.isAnalyzed(file))
.map((root) => root.workspace.findPackageFor(file)?.root)
.nonNulls
.firstOrNull;
if (package != null && !package.isRoot) {
packages.add(package.path);
} else {
@@ -1101,30 +1098,25 @@ class LspAnalysisServer extends AnalysisServer {
// When there are open folders, they are always the roots. If there are no
// open workspace folders, then we use the open (priority) files to compute
// roots.
var includedPaths =
_workspaceFolders.isNotEmpty
? _workspaceFolders.toSet()
: _getRootsForOpenFiles();
var includedPaths = _workspaceFolders.isNotEmpty
? _workspaceFolders.toSet()
: _getRootsForOpenFiles();
var excludedPaths =
lspClientConfiguration.global.analysisExcludedFolders
.expand(
(excludePath) =>
resourceProvider.pathContext.isAbsolute(excludePath)
? [excludePath]
// Apply the relative path to each open workspace folder.
// TODO(dantup): Consider supporting per-workspace config by
// calling workspace/configuration whenever workspace folders change
// and caching the config for each one.
: _workspaceFolders.map(
(root) => resourceProvider.pathContext.join(
root,
excludePath,
),
),
)
.map(pathContext.normalize)
.toSet();
var excludedPaths = lspClientConfiguration.global.analysisExcludedFolders
.expand(
(excludePath) => resourceProvider.pathContext.isAbsolute(excludePath)
? [excludePath]
// Apply the relative path to each open workspace folder.
// TODO(dantup): Consider supporting per-workspace config by
// calling workspace/configuration whenever workspace folders change
// and caching the config for each one.
: _workspaceFolders.map(
(root) =>
resourceProvider.pathContext.join(root, excludePath),
),
)
.map(pathContext.normalize)
.toSet();
var completer = analysisContextRebuildCompleter = Completer();
try {
@@ -1252,17 +1244,18 @@ class LspServerContextManagerCallbacks
var unit = result.unit;
if (analysisServer.shouldSendClosingLabelsFor(path)) {
var labels =
DartUnitClosingLabelsComputer(
result.lineInfo,
unit,
).compute().map((l) => toClosingLabel(result.lineInfo, l)).toList();
var labels = DartUnitClosingLabelsComputer(
result.lineInfo,
unit,
).compute().map((l) => toClosingLabel(result.lineInfo, l)).toList();
analysisServer.publishClosingLabels(path, labels);
}
if (analysisServer.shouldSendOutlineFor(path)) {
var outline =
DartUnitOutlineComputer(result, withBasicFlutter: true).compute();
var outline = DartUnitOutlineComputer(
result,
withBasicFlutter: true,
).compute();
var lspOutline = toOutline(result.lineInfo, outline);
analysisServer.publishOutline(path, lspOutline);
}
@@ -38,53 +38,54 @@ class LspPacketTransformer extends StreamTransformerBase<List<int>, String> {
Stream<String> bind(Stream<List<int>> stream) {
LspHeaders? headersState;
var buffer = <int>[];
var controller = MoreTypedStreamController<
String,
_LspPacketTransformerListenData,
_LspPacketTransformerPauseData
>(
onListen: (controller) {
var input = stream
.expand((b) => b)
.listen(
(codeUnit) {
buffer.add(codeUnit);
var headers = headersState;
if (headers == null && _endsWithCrLfCrLf(buffer)) {
headersState = _parseHeaders(buffer);
buffer.clear();
} else if (headers != null &&
buffer.length >= headers.contentLength) {
// UTF-8 is the default - and only supported - encoding for LSP.
// The string 'utf8' is valid since it was published in the original spec.
// Any other encodings should be rejected with an error.
if ([
null,
'utf-8',
'utf8',
].contains(headers.encoding?.toLowerCase())) {
controller.add(utf8.decode(buffer));
} else {
controller.addError(
InvalidEncodingError(headers.rawHeaders),
);
}
buffer.clear();
headersState = null;
}
},
onError: controller.addError,
onDone: controller.close,
);
return _LspPacketTransformerListenData(input);
},
onPause: (listenData) {
listenData.input.pause();
return _LspPacketTransformerPauseData();
},
onResume: (listenData, pauseData) => listenData.input.resume(),
onCancel: (listenData) => listenData.input.cancel(),
);
var controller =
MoreTypedStreamController<
String,
_LspPacketTransformerListenData,
_LspPacketTransformerPauseData
>(
onListen: (controller) {
var input = stream
.expand((b) => b)
.listen(
(codeUnit) {
buffer.add(codeUnit);
var headers = headersState;
if (headers == null && _endsWithCrLfCrLf(buffer)) {
headersState = _parseHeaders(buffer);
buffer.clear();
} else if (headers != null &&
buffer.length >= headers.contentLength) {
// UTF-8 is the default - and only supported - encoding for LSP.
// The string 'utf8' is valid since it was published in the original spec.
// Any other encodings should be rejected with an error.
if ([
null,
'utf-8',
'utf8',
].contains(headers.encoding?.toLowerCase())) {
controller.add(utf8.decode(buffer));
} else {
controller.addError(
InvalidEncodingError(headers.rawHeaders),
);
}
buffer.clear();
headersState = null;
}
},
onError: controller.addError,
onDone: controller.close,
);
return _LspPacketTransformerListenData(input);
},
onPause: (listenData) {
listenData.input.pause();
return _LspPacketTransformerPauseData();
},
onResume: (listenData, pauseData) => listenData.input.resume(),
onCancel: (listenData) => listenData.input.cancel(),
);
return controller.controller.stream;
}
@@ -89,19 +89,18 @@ class LspSocketServer implements AbstractSocketServer {
stateLocation: analysisServerOptions.cacheFolder,
);
var server =
analysisServer = LspAnalysisServer(
serverChannel,
resourceProvider,
analysisServerOptions,
sdkManager,
analyticsManager,
CrashReportingAttachmentsBuilder.empty,
instrumentationService,
diagnosticServer: diagnosticServer,
detachableFileSystemManager: detachableFileSystemManager,
enableBlazeWatcher: true,
);
var server = analysisServer = LspAnalysisServer(
serverChannel,
resourceProvider,
analysisServerOptions,
sdkManager,
analyticsManager,
CrashReportingAttachmentsBuilder.empty,
instrumentationService,
diagnosticServer: diagnosticServer,
detachableFileSystemManager: detachableFileSystemManager,
enableBlazeWatcher: true,
);
detachableFileSystemManager?.setAnalysisServer(server);
}
}
+234 -253
View File
@@ -88,8 +88,8 @@ lsp.Either2<lsp.MarkupContent, String> asMarkupContentOrString(
) {
return preferredFormats != null
? lsp.Either2<lsp.MarkupContent, String>.t1(
_asMarkup(preferredFormats, content),
)
_asMarkup(preferredFormats, content),
)
: lsp.Either2<lsp.MarkupContent, String>.t2(content);
}
@@ -126,15 +126,15 @@ lsp.Either2<lsp.MarkupContent, String> asMarkupContentOrString(
requiredArgumentListTextRanges?.isNotEmpty ?? false;
var functionCallSuffix =
hasRequiredParameters && requiredArgumentListString != null
? buildSnippetStringWithTabStops(
requiredArgumentListString,
requiredArgumentListTextRanges,
)
// Optional params still gets a final tab stop in the parens.
: hasOptionalParameters
? SnippetBuilder.finalTabStop
// And no parameters at all we skip the tabstop in the parens.
: '';
? buildSnippetStringWithTabStops(
requiredArgumentListString,
requiredArgumentListTextRanges,
)
// Optional params still gets a final tab stop in the parens.
: hasOptionalParameters
? SnippetBuilder.finalTabStop
// And no parameters at all we skip the tabstop in the parens.
: '';
insertText =
'${SnippetBuilder.escapeSnippetPlainText(insertText)}($functionCallSuffix)';
} else if (selectionOffset != 0 &&
@@ -288,25 +288,26 @@ lsp.WorkspaceEdit createWorkspaceEdit(
// Compile the edits into a TextDocumentEdit for this file.
var textDocumentEdit = lsp.TextDocumentEdit(
textDocument: analysisServer.getVersionedDocumentIdentifier(fileEdit.file),
edits:
snippetEdits
.map(
(e) => Either3<
edits: snippetEdits
.map(
(e) =>
Either3<
lsp.AnnotatedTextEdit,
lsp.SnippetTextEdit,
lsp.TextEdit
>.t2(e),
)
.toList(),
)
.toList(),
);
// Convert to the union that documentChanges require.
var textDocumentEditsAsUnion = Either4<
lsp.CreateFile,
lsp.DeleteFile,
lsp.RenameFile,
lsp.TextDocumentEdit
>.t4(textDocumentEdit);
var textDocumentEditsAsUnion =
Either4<
lsp.CreateFile,
lsp.DeleteFile,
lsp.RenameFile,
lsp.TextDocumentEdit
>.t4(textDocumentEdit);
/// Add the textDocumentEdit to a WorkspaceEdit.
return lsp.WorkspaceEdit(documentChanges: [textDocumentEditsAsUnion]);
@@ -606,10 +607,9 @@ CompletionDetail getCompletionDetail(
}
var libraryUri = suggestion.libraryUri;
var autoImportUri =
(suggestion.isNotImported ?? false) && libraryUri != null
? Uri.parse(libraryUri)
: null;
var autoImportUri = (suggestion.isNotImported ?? false) && libraryUri != null
? Uri.parse(libraryUri)
: null;
return (
detail: detail,
@@ -638,13 +638,13 @@ String? getCompletionDisplayUriString({
// Compute the relative path and then put into a URI so the display
// always uses forward slashes (as a URI) regardless of platform.
? uriConverter
.toClientUri(
pathContext.relative(
uriConverter.fromClientUri(elementLibraryUri),
from: pathContext.dirname(completionFilePath),
),
)
.toString()
.toClientUri(
pathContext.relative(
uriConverter.fromClientUri(elementLibraryUri),
from: pathContext.dirname(completionFilePath),
),
)
.toString()
: elementLibraryUri.toString();
}
@@ -656,10 +656,9 @@ List<lsp.DiagnosticTag>? getDiagnosticTags(
return null;
}
var tags =
diagnosticTagsForErrorCode[error.code]
?.where(supportedTags.contains)
.toList();
var tags = diagnosticTagsForErrorCode[error.code]
?.where(supportedTags.contains)
.toList();
return tags != null && tags.isNotEmpty ? tags : null;
}
@@ -737,10 +736,9 @@ lsp.LocationLink? navigationTargetToLocationLink(
var nameRange = toRange(targetLineInfo, target.offset, target.length);
var codeOffset = target.codeOffset;
var codeLength = target.codeLength;
var codeRange =
codeOffset != null && codeLength != null
? toRange(targetLineInfo, codeOffset, codeLength)
: nameRange;
var codeRange = codeOffset != null && codeLength != null
? toRange(targetLineInfo, codeOffset, codeLength)
: nameRange;
return lsp.LocationLink(
originSelectionRange: toRange(regionLineInfo, region.offset, region.length),
@@ -760,17 +758,16 @@ lsp.Diagnostic pluginToDiagnostic(
List<lsp.DiagnosticRelatedInformation>? relatedInformation;
var contextMessages = error.contextMessages;
if (contextMessages != null && contextMessages.isNotEmpty) {
relatedInformation =
contextMessages
.map(
(message) => pluginToDiagnosticRelatedInformation(
uriConverter,
getLineInfo,
message,
),
)
.nonNulls
.toList();
relatedInformation = contextMessages
.map(
(message) => pluginToDiagnosticRelatedInformation(
uriConverter,
getLineInfo,
message,
),
)
.nonNulls
.toList();
}
var message = error.message;
@@ -800,10 +797,9 @@ lsp.Diagnostic pluginToDiagnostic(
relatedInformation: relatedInformation,
// Only include codeDescription if the client explicitly supports it
// (a minor optimization to avoid unnecessary payload/(de)serialization).
codeDescription:
clientSupportsCodeDescription && documentationUrl != null
? CodeDescription(href: Uri.parse(documentationUrl))
: null,
codeDescription: clientSupportsCodeDescription && documentationUrl != null
? CodeDescription(href: Uri.parse(documentationUrl))
: null,
);
}
@@ -991,10 +987,12 @@ lsp.CompletionItem snippetToCompletionItem(
thisFilesChange,
changes.linkedEditGroups,
lineInfo,
selectionOffset:
changes.selection?.file == file ? changes.selection?.offset : null,
selectionLength:
changes.selection?.file == file ? changes.selectionLength : null,
selectionOffset: changes.selection?.file == file
? changes.selection?.offset
: null,
selectionLength: changes.selection?.file == file
? changes.selectionLength
: null,
);
// For LSP, we need to provide the main edit and other edits separately. The
@@ -1021,10 +1019,9 @@ lsp.CompletionItem snippetToCompletionItem(
filterText: snippet.prefix.orNullIfSameAs(snippet.label),
kind: lsp.CompletionItemKind.Snippet,
command: command,
documentation:
documentation != null
? asMarkupContentOrString(formats, documentation)
: null,
documentation: documentation != null
? asMarkupContentOrString(formats, documentation)
: null,
// Force snippets to be sorted at the bottom of the list.
// TODO(dantup): Consider if we can rank these better. Client-side
// snippets have always been forced to the bottom partly because they
@@ -1034,14 +1031,12 @@ lsp.CompletionItem snippetToCompletionItem(
insertTextMode: supportsAsIsInsertMode ? InsertTextMode.asIs : null,
// Set textEdit or textEditText depending on whether we need to specify
// a range or not.
textEdit:
hasDefaultEditRange
? null
: Either2<InsertReplaceEdit, TextEdit>.t2(mainEdit),
textEditText:
hasDefaultEditRange
? mainEdit.newText.orNullIfSameAs(snippet.label)
: null,
textEdit: hasDefaultEditRange
? null
: Either2<InsertReplaceEdit, TextEdit>.t2(mainEdit),
textEditText: hasDefaultEditRange
? mainEdit.newText.orNullIfSameAs(snippet.label)
: null,
additionalTextEdits: nonMainEdits.nullIfEmpty,
);
}
@@ -1075,13 +1070,13 @@ lsp.CompletionItemKind? suggestionKindToCompletionItemKind(
if (!label.startsWith('dart:')) {
return label.endsWith('.dart')
? const [
lsp.CompletionItemKind.File,
lsp.CompletionItemKind.Module,
]
lsp.CompletionItemKind.File,
lsp.CompletionItemKind.Module,
]
: const [
lsp.CompletionItemKind.Folder,
lsp.CompletionItemKind.Module,
];
lsp.CompletionItemKind.Folder,
lsp.CompletionItemKind.Module,
];
}
return const [lsp.CompletionItemKind.Module];
case server.CompletionSuggestionKind.IDENTIFIER:
@@ -1207,10 +1202,9 @@ lsp.CompletionItem toCompletionItem(
// TODO(dantup): Consider including more of these raw fields in the original
// suggestion to avoid needing to manipulate them in this way here.
var filterText =
!label.startsWith(completionFilterTextSplitPattern)
? label.split(completionFilterTextSplitPattern).first.trim()
: label;
var filterText = !label.startsWith(completionFilterTextSplitPattern)
? label.split(completionFilterTextSplitPattern).first.trim()
: label;
// If we're using label details, we also don't want the label to include any
// additional symbols as noted above, because they will appear in the extra
@@ -1227,22 +1221,21 @@ lsp.CompletionItem toCompletionItem(
var element = suggestion.element;
var colorPreviewHex =
capabilities.completionItemKinds.contains(CompletionItemKind.Color) &&
suggestion is DartCompletionSuggestion
? suggestion.colorHex
: null;
var completionKind =
colorPreviewHex != null
? CompletionItemKind.Color
: element != null
? elementKindToCompletionItemKind(
capabilities.completionItemKinds,
element.kind,
)
: suggestionKindToCompletionItemKind(
capabilities.completionItemKinds,
suggestion.kind,
label,
);
suggestion is DartCompletionSuggestion
? suggestion.colorHex
: null;
var completionKind = colorPreviewHex != null
? CompletionItemKind.Color
: element != null
? elementKindToCompletionItemKind(
capabilities.completionItemKinds,
element.kind,
)
: suggestionKindToCompletionItemKind(
capabilities.completionItemKinds,
suggestion.kind,
label,
);
var labelDetails = getCompletionDetail(
suggestion,
@@ -1272,21 +1265,19 @@ lsp.CompletionItem toCompletionItem(
var insertTextFormat = insertTextInfo.format;
var isMultilineCompletion = insertText.contains('\n');
var rawDoc =
includeDocumentation == DocumentationPreference.full
? suggestion.docComplete
: includeDocumentation == DocumentationPreference.summary
? suggestion.docSummary
: null;
var rawDoc = includeDocumentation == DocumentationPreference.full
? suggestion.docComplete
: includeDocumentation == DocumentationPreference.summary
? suggestion.docSummary
: null;
var cleanedDoc = cleanDartdoc(rawDoc);
// To improve the display of some items (like pubspec version numbers),
// short labels in the format `_foo_` in docComplete are "upgraded" to the
// detail field.
var labelMatch =
cleanedDoc != null
? upgradableDocCompletePattern.firstMatch(cleanedDoc)
: null;
var labelMatch = cleanedDoc != null
? upgradableDocCompletePattern.firstMatch(cleanedDoc)
: null;
if (labelMatch != null) {
cleanedDoc = null;
labelDetails = (
@@ -1316,53 +1307,48 @@ lsp.CompletionItem toCompletionItem(
]),
data: resolutionData,
detail: labelDetails.detail.nullIfEmpty,
labelDetails:
useLabelDetails
? CompletionItemLabelDetails(
detail: labelDetails.truncatedSignature.nullIfEmpty,
description: getCompletionDisplayUriString(
uriConverter: uriConverter,
pathContext: pathContext,
elementLibraryUri: labelDetails.autoImportUri,
completionFilePath: completionFilePath,
),
).nullIfEmpty
: null,
documentation:
cleanedDoc != null
? asMarkupContentOrString(formats, cleanedDoc)
: null,
deprecated:
supportsCompletionDeprecatedFlag && suggestion.isDeprecated
? true
: null,
labelDetails: useLabelDetails
? CompletionItemLabelDetails(
detail: labelDetails.truncatedSignature.nullIfEmpty,
description: getCompletionDisplayUriString(
uriConverter: uriConverter,
pathContext: pathContext,
elementLibraryUri: labelDetails.autoImportUri,
completionFilePath: completionFilePath,
),
).nullIfEmpty
: null,
documentation: cleanedDoc != null
? asMarkupContentOrString(formats, cleanedDoc)
: null,
deprecated: supportsCompletionDeprecatedFlag && suggestion.isDeprecated
? true
: null,
sortText: relevanceToSortText(suggestion.relevance),
filterText: filterText.orNullIfSameAs(
label,
), // filterText uses label if not set
insertTextFormat:
insertTextFormat != lsp.InsertTextFormat.PlainText
? insertTextFormat
: null, // Defaults to PlainText if not supplied
insertTextFormat: insertTextFormat != lsp.InsertTextFormat.PlainText
? insertTextFormat
: null, // Defaults to PlainText if not supplied
insertTextMode:
!hasDefaultTextMode && supportsAsIsInsertMode && isMultilineCompletion
? InsertTextMode.asIs
: null,
? InsertTextMode.asIs
: null,
// When using defaults for edit range, don't use textEdit.
textEdit:
hasDefaultEditRange
? null
: supportsInsertReplace && insertionRange != replacementRange
? Either2<InsertReplaceEdit, TextEdit>.t1(
InsertReplaceEdit(
insert: insertionRange,
replace: replacementRange,
newText: insertText,
),
)
: Either2<InsertReplaceEdit, TextEdit>.t2(
TextEdit(range: replacementRange, newText: insertText),
textEdit: hasDefaultEditRange
? null
: supportsInsertReplace && insertionRange != replacementRange
? Either2<InsertReplaceEdit, TextEdit>.t1(
InsertReplaceEdit(
insert: insertionRange,
replace: replacementRange,
newText: insertText,
),
)
: Either2<InsertReplaceEdit, TextEdit>.t2(
TextEdit(range: replacementRange, newText: insertText),
),
// When using defaults for edit range, use textEditText.
textEditText: hasDefaultEditRange ? insertText.orNullIfSameAs(label) : null,
);
@@ -1387,10 +1373,9 @@ lsp.Diagnostic toDiagnostic(
lsp.Element toElement(server.LineInfo lineInfo, server.Element element) {
var location = element.location;
return lsp.Element(
range:
location != null
? toRange(lineInfo, location.offset, location.length)
: null,
range: location != null
? toRange(lineInfo, location.offset, location.length)
: null,
name: toElementName(element),
kind: element.kind.name,
parameters: element.parameters,
@@ -1403,8 +1388,8 @@ String toElementName(server.Element element) {
return element.name.isNotEmpty
? element.name
: (element.kind == server.ElementKind.EXTENSION
? '<unnamed extension>'
: '<unnamed>');
? '<unnamed extension>'
: '<unnamed>');
}
lsp.FlutterOutline toFlutterOutline(
@@ -1420,10 +1405,9 @@ lsp.FlutterOutline toFlutterOutline(
label: outline.label,
className: outline.className,
variableName: outline.variableName,
attributes:
attributes
?.map((attribute) => toFlutterOutlineAttribute(lineInfo, attribute))
.toList(),
attributes: attributes
?.map((attribute) => toFlutterOutlineAttribute(lineInfo, attribute))
.toList(),
dartElement: dartElement != null ? toElement(lineInfo, dartElement) : null,
range: toRange(lineInfo, outline.offset, outline.length),
codeRange: toRange(lineInfo, outline.codeOffset, outline.codeLength),
@@ -1439,10 +1423,9 @@ lsp.FlutterOutlineAttribute toFlutterOutlineAttribute(
return lsp.FlutterOutlineAttribute(
name: attribute.name,
label: attribute.label,
valueRange:
valueLocation != null
? toRange(lineInfo, valueLocation.offset, valueLocation.length)
: null,
valueRange: valueLocation != null
? toRange(lineInfo, valueLocation.offset, valueLocation.length)
: null,
);
}
@@ -1480,10 +1463,9 @@ ErrorOr<int> toOffset(
if (pos.line >= lineInfo.lineCount) {
return ErrorOr<int>.error(
lsp.ResponseError(
code:
failureIsCritical
? lsp.ServerErrorCodes.ClientServerInconsistentState
: lsp.ServerErrorCodes.InvalidFileLineCol,
code: failureIsCritical
? lsp.ServerErrorCodes.ClientServerInconsistentState
: lsp.ServerErrorCodes.InvalidFileLineCol,
message: 'Invalid line number',
data: pos.line.toString(),
),
@@ -1535,8 +1517,9 @@ lsp.SignatureHelp toSignatureHelp(
/// Gets the label for an individual parameter in the form
/// String s = 'foo'
String getParamLabel(FormalParameterElement p) {
var defaultCodeSuffix =
p.defaultValueCode != null ? ' = ${p.defaultValueCode}' : '';
var defaultCodeSuffix = p.defaultValueCode != null
? ' = ${p.defaultValueCode}'
: '';
var requiredPrefix = p.isRequiredNamed ? 'required ' : '';
return '$requiredPrefix${p.type} ${p.displayName}$defaultCodeSuffix';
}
@@ -1544,10 +1527,12 @@ lsp.SignatureHelp toSignatureHelp(
/// Gets the full signature label in the form
/// foo(String s, int i, bool a = true)
String getSignatureLabel(server.SignatureInformation resp) {
var positionalRequired =
signature.parameters.where((p) => p.isRequiredPositional).toList();
var positionalOptional =
signature.parameters.where((p) => p.isOptionalPositional).toList();
var positionalRequired = signature.parameters
.where((p) => p.isRequiredPositional)
.toList();
var positionalOptional = signature.parameters
.where((p) => p.isOptionalPositional)
.toList();
var named = signature.parameters.where((p) => p.isNamed).toList();
var params = [
if (positionalRequired.isNotEmpty)
@@ -1573,10 +1558,9 @@ lsp.SignatureHelp toSignatureHelp(
signatures: [
lsp.SignatureInformation(
label: getSignatureLabel(signature),
documentation:
cleanedDoc != null
? asMarkupContentOrString(preferredFormats, cleanedDoc)
: null,
documentation: cleanedDoc != null
? asMarkupContentOrString(preferredFormats, cleanedDoc)
: null,
parameters: signature.parameters.map(toParameterInfo).toList(),
),
],
@@ -1665,23 +1649,22 @@ lsp.TextDocumentEdit toTextDocumentEdit(
);
return lsp.TextDocumentEdit(
textDocument: fileEdit.doc,
edits:
sortSourceEditsForLsp(fileEdit.edits).map((edit) {
var annotation = recordEditAnnotation(
fileEdit.doc.uri,
edit,
annotateChanges: annotateChanges,
changeAnnotations: changeAnnotations,
);
return toTextDocumentEditEdit(
capabilities,
fileEdit.lineInfo,
edit,
selectionOffsetRelative: fileEdit.selectionOffsetRelative,
selectionLength: fileEdit.selectionLength,
annotationIdentifier: annotation?.label,
);
}).toList(),
edits: sortSourceEditsForLsp(fileEdit.edits).map((edit) {
var annotation = recordEditAnnotation(
fileEdit.doc.uri,
edit,
annotateChanges: annotateChanges,
changeAnnotations: changeAnnotations,
);
return toTextDocumentEditEdit(
capabilities,
fileEdit.lineInfo,
edit,
selectionOffsetRelative: fileEdit.selectionOffsetRelative,
selectionLength: fileEdit.selectionLength,
annotationIdentifier: annotation?.label,
);
}).toList(),
);
}
@@ -1726,14 +1709,14 @@ lsp.TextEdit toTextEdit(
}) {
return annotation != null
? lsp.AnnotatedTextEdit(
range: toRange(lineInfo, edit.offset, edit.length),
newText: edit.replacement,
annotationId: annotation.label,
)
range: toRange(lineInfo, edit.offset, edit.length),
newText: edit.replacement,
annotationId: annotation.label,
)
: lsp.TextEdit(
range: toRange(lineInfo, edit.offset, edit.length),
newText: edit.replacement,
);
range: toRange(lineInfo, edit.offset, edit.length),
newText: edit.replacement,
);
}
/// Creates an [lsp.WorkspaceEdit] for [edits].
@@ -1751,10 +1734,9 @@ lsp.WorkspaceEdit toWorkspaceEdit(
ChangeAnnotations annotateChanges = ChangeAnnotations.none,
}) {
var supportsDocumentChanges = clientCapabilities.documentChanges;
var changeAnnotations =
annotateChanges != ChangeAnnotations.none
? <lsp.ChangeAnnotationIdentifier, ChangeAnnotation>{}
: null;
var changeAnnotations = annotateChanges != ChangeAnnotations.none
? <lsp.ChangeAnnotationIdentifier, ChangeAnnotation>{}
: null;
if (supportsDocumentChanges) {
var supportsCreate = clientCapabilities.createResourceOperations;
@@ -1774,12 +1756,13 @@ lsp.WorkspaceEdit toWorkspaceEdit(
for (var fileEdit in edits) {
if (supportsCreate && fileEdit.newFile) {
var create = lsp.CreateFile(uri: fileEdit.doc.uri);
var createUnion = Either4<
lsp.CreateFile,
lsp.DeleteFile,
lsp.RenameFile,
lsp.TextDocumentEdit
>.t1(create);
var createUnion =
Either4<
lsp.CreateFile,
lsp.DeleteFile,
lsp.RenameFile,
lsp.TextDocumentEdit
>.t1(create);
changes.add(createUnion);
}
@@ -1789,12 +1772,13 @@ lsp.WorkspaceEdit toWorkspaceEdit(
annotateChanges: annotateChanges,
changeAnnotations: changeAnnotations,
);
var textDocEditUnion = Either4<
lsp.CreateFile,
lsp.DeleteFile,
lsp.RenameFile,
lsp.TextDocumentEdit
>.t4(textDocEdit);
var textDocEditUnion =
Either4<
lsp.CreateFile,
lsp.DeleteFile,
lsp.RenameFile,
lsp.TextDocumentEdit
>.t4(textDocEdit);
changes.add(textDocEditUnion);
}
@@ -1820,16 +1804,15 @@ Map<Uri, List<lsp.TextEdit>> toWorkspaceEditChanges(
Map<ChangeAnnotationIdentifier, ChangeAnnotation>? changeAnnotations,
}) {
MapEntry<Uri, List<lsp.TextEdit>> createEdit(FileEditInformation file) {
var edits =
sortSourceEditsForLsp(file.edits).map((edit) {
var annotation = recordEditAnnotation(
file.doc.uri,
edit,
annotateChanges: annotateChanges,
changeAnnotations: changeAnnotations,
);
return toTextEdit(file.lineInfo, edit, annotation: annotation);
}).toList();
var edits = sortSourceEditsForLsp(file.edits).map((edit) {
var annotation = recordEditAnnotation(
file.doc.uri,
edit,
annotateChanges: annotateChanges,
changeAnnotations: changeAnnotations,
);
return toTextEdit(file.lineInfo, edit, annotation: annotation);
}).toList();
return MapEntry(file.doc.uri, edits);
}
@@ -1848,10 +1831,9 @@ lsp.MarkupContent _asMarkup(
var supportsPlain = preferredFormats.contains(lsp.MarkupKind.PlainText);
// Since our PlainText version is actually just Markdown, only advertise it
// as PlainText if the client explicitly supports PlainText and not Markdown.
var format =
supportsPlain && !supportsMarkdown
? lsp.MarkupKind.PlainText
: lsp.MarkupKind.Markdown;
var format = supportsPlain && !supportsMarkdown
? lsp.MarkupKind.PlainText
: lsp.MarkupKind.Markdown;
return lsp.MarkupContent(kind: format, value: content);
}
@@ -1860,32 +1842,31 @@ String _diagnosticCode(server.DiagnosticCode code) => code.name.toLowerCase();
/// Additional details about a completion that may be formatted differently
/// depending on the client capabilities.
typedef CompletionDetail =
({
/// Additional details to go in the details popup.
///
/// This is usually a full signature (with full parameters) and may also
/// include whether the item is deprecated if the client did not support the
/// native deprecated tag.
String detail,
typedef CompletionDetail = ({
/// Additional details to go in the details popup.
///
/// This is usually a full signature (with full parameters) and may also
/// include whether the item is deprecated if the client did not support the
/// native deprecated tag.
String detail,
/// Truncated parameters. Similar to [truncatedSignature] but does not
/// include return types. Used in clients that cannot format signatures
/// differently and is appended immediately after the completion label. The
/// return type is omitted to reduce noise because this text is not subtle.
String truncatedParams,
/// Truncated parameters. Similar to [truncatedSignature] but does not
/// include return types. Used in clients that cannot format signatures
/// differently and is appended immediately after the completion label. The
/// return type is omitted to reduce noise because this text is not subtle.
String truncatedParams,
/// A signature with truncated params. Used for showing immediately after
/// the completion label when it can be formatted differently.
///
/// () String
String truncatedSignature,
/// A signature with truncated params. Used for showing immediately after
/// the completion label when it can be formatted differently.
///
/// () String
String truncatedSignature,
/// The URI that will be auto-imported if this item is selected in a
/// user-friendly string format (for example a relative path if for a `file:/`
/// URI).
Uri? autoImportUri,
});
/// The URI that will be auto-imported if this item is selected in a
/// user-friendly string format (for example a relative path if for a `file:/`
/// URI).
Uri? autoImportUri,
});
extension CompletionLabelExtension on CompletionItemLabelDetails {
/// Returns `null` if no fields are set, otherwise `this`.
@@ -25,19 +25,18 @@ class LspNotificationManager extends AbstractNotificationManager {
// Currently these diagnostics are always sent to the editor client, so
// use those client capabilities.
var clientCapabilities = server.editorClientCapabilities;
var diagnostics =
errors
.map(
(error) => pluginToDiagnostic(
server.uriConverter,
(path) => server.getLineInfo(path),
error,
supportedTags: clientCapabilities?.diagnosticTags,
clientSupportsCodeDescription:
clientCapabilities?.diagnosticCodeDescription ?? false,
),
)
.toList();
var diagnostics = errors
.map(
(error) => pluginToDiagnostic(
server.uriConverter,
(path) => server.getLineInfo(path),
error,
supportedTags: clientCapabilities?.diagnosticTags,
clientSupportsCodeDescription:
clientCapabilities?.diagnosticCodeDescription ?? false,
),
)
.toList();
server.publishDiagnostics(filePath, diagnostics);
}
@@ -65,8 +65,9 @@ class SemanticTokenEncoder {
var relativeLine = tokenLine - lastLine;
// Column is relative to last only if on the same line.
var relativeColumn =
relativeLine == 0 ? tokenColumn - lastColumn : tokenColumn;
var relativeColumn = relativeLine == 0
? tokenColumn - lastColumn
: tokenColumn;
// The resulting array is groups of 5 items as described in the LSP spec:
// https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md#textDocument_semanticTokens
@@ -106,10 +107,9 @@ class SemanticTokenEncoder {
var lineOffset = lineInfo.getOffsetOfLine(lineNumber - 1);
var startOffset = isFirstLine ? start.columnNumber - 1 : 0;
var endOffset =
isLastLine
? end.columnNumber - 1
: lineInfo.getOffsetOfLine(lineNumber) - lineOffset;
var endOffset = isLastLine
? end.columnNumber - 1
: lineInfo.getOffsetOfLine(lineNumber) - lineOffset;
var length = endOffset - startOffset;
yield SemanticTokenInfo(
@@ -31,28 +31,26 @@ class SemanticTokenLegendLookup {
SemanticTokenLegendLookup() {
// Build lists of all tokens and modifiers that exist in our mappings or that
// we have added as custom types. These will be used to determine the indexes used for communication.
_usedTokenTypes =
Set.of(
highlightRegionTokenTypes.values.followedBy(
CustomSemanticTokenTypes.values,
),
).toList();
_usedTokenModifiers =
Set.of(
highlightRegionTokenModifiers.values.flattenedToList.followedBy(
CustomSemanticTokenModifiers.values,
),
).toList();
_usedTokenTypes = Set.of(
highlightRegionTokenTypes.values.followedBy(
CustomSemanticTokenTypes.values,
),
).toList();
_usedTokenModifiers = Set.of(
highlightRegionTokenModifiers.values.flattenedToList.followedBy(
CustomSemanticTokenModifiers.values,
),
).toList();
// Build the LSP Legend which tells the client all of the tokens and modifiers
// we will use in the order they should be accessed by index/bit.
lspLegend = SemanticTokensLegend(
tokenTypes:
_usedTokenTypes.map((tokenType) => tokenType.toString()).toList(),
tokenModifiers:
_usedTokenModifiers
.map((tokenModifier) => tokenModifier.toString())
.toList(),
tokenTypes: _usedTokenTypes
.map((tokenType) => tokenType.toString())
.toList(),
tokenModifiers: _usedTokenModifiers
.map((tokenModifier) => tokenModifier.toString())
.toList(),
);
}
@@ -7,102 +7,108 @@ import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
/// A mapping from [HighlightRegionType] to a set of [SemanticTokenModifiers].
final highlightRegionTokenModifiers = <
HighlightRegionType,
Set<SemanticTokenModifiers>
>{
HighlightRegionType.COMMENT_DOCUMENTATION: {
SemanticTokenModifiers.documentation,
},
HighlightRegionType.CONSTRUCTOR_TEAR_OFF: {
CustomSemanticTokenModifiers.constructor,
},
HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.IMPORT_PREFIX: {
CustomSemanticTokenModifiers.importPrefix,
},
HighlightRegionType.INSTANCE_FIELD_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_FIELD_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_GETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_GETTER_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_METHOD_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_METHOD_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_METHOD_TEAR_OFF: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_SETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_SETTER_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.LOCAL_FUNCTION_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.LOCAL_VARIABLE_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.PARAMETER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.STATIC_FIELD_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_GETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_GETTER_REFERENCE: {SemanticTokenModifiers.static},
HighlightRegionType.STATIC_METHOD_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_METHOD_REFERENCE: {SemanticTokenModifiers.static},
HighlightRegionType.STATIC_METHOD_TEAR_OFF: {SemanticTokenModifiers.static},
HighlightRegionType.STATIC_SETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_SETTER_REFERENCE: {SemanticTokenModifiers.static},
HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.VALID_STRING_ESCAPE: {
CustomSemanticTokenModifiers.escape,
},
};
final highlightRegionTokenModifiers =
<HighlightRegionType, Set<SemanticTokenModifiers>>{
HighlightRegionType.COMMENT_DOCUMENTATION: {
SemanticTokenModifiers.documentation,
},
HighlightRegionType.CONSTRUCTOR_TEAR_OFF: {
CustomSemanticTokenModifiers.constructor,
},
HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.IMPORT_PREFIX: {
CustomSemanticTokenModifiers.importPrefix,
},
HighlightRegionType.INSTANCE_FIELD_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_FIELD_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_GETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_GETTER_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_METHOD_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_METHOD_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_METHOD_TEAR_OFF: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_SETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.INSTANCE_SETTER_REFERENCE: {
CustomSemanticTokenModifiers.instance,
},
HighlightRegionType.LOCAL_FUNCTION_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.LOCAL_VARIABLE_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.PARAMETER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.STATIC_FIELD_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_GETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_GETTER_REFERENCE: {
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_METHOD_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_METHOD_REFERENCE: {
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_METHOD_TEAR_OFF: {
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_SETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.STATIC_SETTER_REFERENCE: {
SemanticTokenModifiers.static,
},
HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION: {
SemanticTokenModifiers.declaration,
SemanticTokenModifiers.static,
},
HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION: {
SemanticTokenModifiers.declaration,
},
HighlightRegionType.VALID_STRING_ESCAPE: {
CustomSemanticTokenModifiers.escape,
},
};
/// A mapping from [HighlightRegionType] to [SemanticTokenTypes].
///
@@ -149,20 +149,20 @@ class ServerCapabilitiesComputer {
ServerCapabilitiesComputer(this._server);
List<TextDocumentFilterScheme> get pluginTypes =>
_server.pluginManager.pluginIsolates
.expand(
(isolate) =>
isolate.currentSession?.interestingFiles ?? const <String>[],
)
// All published plugins use something like `*.extension` as
// interestingFiles. Prefix a `**/` so that the glob matches nested
// folders as well.
.map(
(glob) =>
TextDocumentFilterScheme(scheme: 'file', pattern: '**/$glob'),
)
.toList();
List<TextDocumentFilterScheme> get pluginTypes => _server
.pluginManager
.pluginIsolates
.expand(
(isolate) =>
isolate.currentSession?.interestingFiles ?? const <String>[],
)
// All published plugins use something like `*.extension` as
// interestingFiles. Prefix a `**/` so that the glob matches nested
// folders as well.
.map(
(glob) => TextDocumentFilterScheme(scheme: 'file', pattern: '**/$glob'),
)
.toList();
ServerCapabilities computeServerCapabilities(
LspClientCapabilities clientCapabilities,
@@ -204,12 +204,11 @@ class ServerCapabilitiesComputer {
supported: true,
changeNotifications: features.changeNotifications.staticRegistration,
),
fileOperations:
!context.clientDynamic.fileOperations
? FileOperationOptions(
willRename: features.willRename.staticRegistration,
)
: null,
fileOperations: !context.clientDynamic.fileOperations
? FileOperationOptions(
willRename: features.willRename.staticRegistration,
)
: null,
),
experimental: {
// 'experimental' is a field we can put any arbitrary data that is not
@@ -287,17 +286,15 @@ class ServerCapabilitiesComputer {
);
var currentRegistrationJsons = currentRegistrationsMap.values.toSet();
var registrationsToAdd =
newRegistrationsMap.entries
.where((entry) => !currentRegistrationJsons.contains(entry.value))
.map((entry) => entry.key)
.toList();
var registrationsToAdd = newRegistrationsMap.entries
.where((entry) => !currentRegistrationJsons.contains(entry.value))
.map((entry) => entry.key)
.toList();
var registrationsToRemove =
currentRegistrationsMap.entries
.where((entry) => !newRegistrationsJsons.contains(entry.value))
.map((entry) => entry.key)
.toList();
var registrationsToRemove = currentRegistrationsMap.entries
.where((entry) => !newRegistrationsJsons.contains(entry.value))
.map((entry) => entry.key)
.toList();
// Update the current list before we start sending requests since we
// go async.
@@ -307,10 +304,9 @@ class ServerCapabilitiesComputer {
Future<void>? unregistrationRequest;
if (registrationsToRemove.isNotEmpty) {
var unregistrations =
registrationsToRemove
.map((r) => Unregistration(id: r.id, method: r.method))
.toList();
var unregistrations = registrationsToRemove
.map((r) => Unregistration(id: r.id, method: r.method))
.toList();
// It's important not to await this request here, as we must ensure
// we cannot re-enter this method until we have sent both the unregister
// and register requests to the client atomically.
@@ -28,8 +28,9 @@ String buildSnippetStringForEditGroups(
filePath: filePath,
editGroups: editGroups,
editGroupsOffset: editOffset,
selectionOffset:
selectionOffset != null ? selectionOffset - editOffset : null,
selectionOffset: selectionOffset != null
? selectionOffset - editOffset
: null,
selectionLength: selectionLength,
);
@@ -80,10 +81,9 @@ String _buildSnippetString(
// Make the position relative to the supplied text.
position.offset - editGroupsOffset,
editGroup.length,
suggestions:
editGroup.suggestions
.map((suggestion) => suggestion.value)
.toList(),
suggestions: editGroup.suggestions
.map((suggestion) => suggestion.value)
.toList(),
// Use the index as an ID to keep all related positions together (so
// the remain "linked").
linkedGroupId: index,
@@ -135,9 +135,8 @@ String _buildSnippetString(
/// If there are no edit groups, then placeholders are all simple and
/// guaranteed to be in the correct order.
var isPreSorted = editGroups.isEmpty;
var builder =
SnippetBuilder()
..appendPlaceholders(text, placeholders, isPreSorted: isPreSorted);
var builder = SnippetBuilder()
..appendPlaceholders(text, placeholders, isPreSorted: isPreSorted);
return builder.value;
}
@@ -175,8 +175,9 @@ ErrorOr<List<TextEdit>> generateMinimalEdits(
}) {
var unformatted = result.content;
var lineInfo = result.lineInfo;
var rangeStart =
range != null ? toOffset(lineInfo, range.start) : success(null);
var rangeStart = range != null
? toOffset(lineInfo, range.start)
: success(null);
var rangeEnd = range != null ? toOffset(lineInfo, range.end) : success(null);
return (rangeStart, rangeEnd).mapResultsSync((rangeStart, rangeEnd) {
@@ -328,8 +329,8 @@ class _MinimalEditComputer {
// Walk through the token streams computing edits for the differences.
bool unformattedHasMore, formattedHasMore;
while ((unformattedHasMore =
unformattedTokens.moveNext()) & // Don't short-circuit.
while ((unformattedHasMore = unformattedTokens
.moveNext()) & // Don't short-circuit.
(formattedHasMore = formattedTokens.moveNext())) {
var unformattedToken = unformattedTokens.current;
var formattedToken = formattedTokens.current;
@@ -675,14 +676,15 @@ class _MinimalEditComputer {
/// be parsed.
static Token? _parse(String s, FeatureSet featureSet) {
try {
var scanner = Scanner(
_SourceMock.instance,
CharSequenceReader(s),
DiagnosticListener.nullListener,
)..configureFeatures(
featureSetForOverriding: featureSet,
featureSet: featureSet,
);
var scanner =
Scanner(
_SourceMock.instance,
CharSequenceReader(s),
DiagnosticListener.nullListener,
)..configureFeatures(
featureSetForOverriding: featureSet,
featureSet: featureSet,
);
return scanner.tokenize();
} catch (e) {
return null;
@@ -50,12 +50,11 @@ Future<void> scheduleImplementedNotification(
void sendAnalysisNotificationAnalyzedFiles(LegacyAnalysisServer server) {
_sendNotification(server, () {
var analyzedFiles =
server.driverMap.values
.map((driver) => driver.knownFiles)
.flattenedToList
.map((file) => file.path)
.toSet();
var analyzedFiles = server.driverMap.values
.map((driver) => driver.knownFiles)
.flattenedToList
.map((file) => file.path)
.toSet();
// Exclude *.yaml files because IDEA Dart plugin attempts to index
// all the files in folders which contain analyzed files.
@@ -138,8 +137,10 @@ void sendAnalysisNotificationOutline(
var libraryName = _computeLibraryName(unit);
// compute Outline
var outline =
DartUnitOutlineComputer(resolvedUnit, withBasicFlutter: true).compute();
var outline = DartUnitOutlineComputer(
resolvedUnit,
withBasicFlutter: true,
).compute();
// send notification
var params = protocol.AnalysisOutlineParams(
@@ -646,11 +646,10 @@ class PluginManager {
var uri = Uri.parse('package:$packageName/$packageName.dart');
var packageSource = packageUriResolver.resolveAbsolute(uri);
if (packageSource != null) {
var packageRoot =
_resourceProvider
.getFile(packageSource.fullName)
.parent
.parent;
var packageRoot = _resourceProvider
.getFile(packageSource.fullName)
.parent
.parent;
packages.add(_Package(packageName, packageRoot));
pubspecFiles.add(
packageRoot.getChildAssumingFile(file_paths.pubspecYaml),
@@ -16,13 +16,12 @@ class ResultConverter {
server.AnalysisErrorFixes convertAnalysisErrorFixes(
plugin.AnalysisErrorFixes fixes,
) {
var changes =
fixes.fixes
.map(
(plugin.PrioritizedSourceChange change) =>
convertPrioritizedSourceChange(change),
)
.toList();
var changes = fixes.fixes
.map(
(plugin.PrioritizedSourceChange change) =>
convertPrioritizedSourceChange(change),
)
.toList();
return server.AnalysisErrorFixes(fixes.error, fixes: changes);
}
@@ -302,11 +302,10 @@ class ResultMerger {
//
for (var j = 0; j < regions.length; j++) {
var region = regions[j];
var newTargets =
region.targets
.map((int oldTarget) => targetMap[oldTarget])
.toList()
.cast<int>();
var newTargets = region.targets
.map((int oldTarget) => targetMap[oldTarget])
.toList()
.cast<int>();
if (region.targets != newTargets) {
region = NavigationRegion(region.offset, region.length, newTargets);
}
@@ -496,8 +495,9 @@ class ResultMerger {
if (currentChildren == null || currentChildren.isEmpty) {
return outline;
}
var updatedChildren =
currentChildren.map((Outline child) => traverse(child)).toList();
var updatedChildren = currentChildren
.map((Outline child) => traverse(child))
.toList();
if (currentChildren != updatedChildren) {
if (!isCopied) {
return Outline(
@@ -604,14 +604,12 @@ class ResultMerger {
names.toList(),
offsets,
lengths,
coveringExpressionOffsets:
coveringExpressionOffsets.isEmpty
? null
: coveringExpressionOffsets,
coveringExpressionLengths:
coveringExpressionLengths.isEmpty
? null
: coveringExpressionLengths,
coveringExpressionOffsets: coveringExpressionOffsets.isEmpty
? null
: coveringExpressionOffsets,
coveringExpressionLengths: coveringExpressionLengths.isEmpty
? null
: coveringExpressionLengths,
);
} else if (first is ExtractMethodFeedback) {
var offset = first.offset;
@@ -186,10 +186,9 @@ AnalysisError newAnalysisError_fromEngine(
var code = diagnosticCode.name.toLowerCase();
List<DiagnosticMessage>? contextMessages;
if (diagnostic.contextMessages.isNotEmpty) {
contextMessages =
diagnostic.contextMessages
.map((message) => newDiagnosticMessage(result, message))
.toList();
contextMessages = diagnostic.contextMessages
.map((message) => newDiagnosticMessage(result, message))
.toList();
}
var correction = diagnostic.correctionMessage;
var url = diagnosticCode.url;
@@ -94,11 +94,10 @@ final class MessageScheduler {
var request = message.request;
var method = request.method;
if (method == legacy.SERVER_REQUEST_CANCEL_REQUEST) {
var id =
legacy.ServerCancelRequestParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).id;
var id = legacy.ServerCancelRequestParams.fromRequest(
request,
clientUriConverter: server.uriConverter,
).id;
listener?.addActiveMessage(message);
(server as LegacyAnalysisServer).cancelRequest(id);
// The message needs to be added to the queue of pending messages, but
@@ -154,10 +153,9 @@ final class MessageScheduler {
// Cancel in progress completion and refactoring requests.
var incomingMsgMethod = msg.method;
if (_isCancelableRequest(msg)) {
var reason =
incomingMsgMethod == lsp.Method.workspace_executeCommand
? 'Another workspace/executeCommand request for a refactor was started'
: 'Another textDocument/completion request was started';
var reason = incomingMsgMethod == lsp.Method.workspace_executeCommand
? 'Another workspace/executeCommand request for a refactor was started'
: 'Another textDocument/completion request was started';
for (var activeMessage in _activeMessages) {
if (activeMessage is LspMessage && activeMessage.isRequest) {
var message = activeMessage.message as lsp.RequestMessage;
@@ -71,10 +71,9 @@ class TypeHierarchyComputer {
var subMemberElementDeclared = subMemberElement?.nonSynthetic;
subItem = TypeHierarchyItem(
convertElement(subElement),
memberElement:
subMemberElementDeclared != null
? convertElement(subMemberElementDeclared)
: null,
memberElement: subMemberElementDeclared != null
? convertElement(subMemberElementDeclared)
: null,
superclass: itemId,
);
var subItemId = _items.length;
@@ -124,10 +123,9 @@ class TypeHierarchyComputer {
item = TypeHierarchyItem(
convertElement(classElement),
displayName: displayName,
memberElement:
memberElementDeclared != null
? convertElement(memberElementDeclared)
: null,
memberElement: memberElementDeclared != null
? convertElement(memberElementDeclared)
: null,
);
_elementItemMap[classElement] = item;
itemId = _items.length;
@@ -20,13 +20,12 @@ class CrashReportingInstrumentation extends NoopInstrumentationService {
StackTrace? stackTrace,
List<InstrumentationServiceAttachment>? attachments,
]) {
var crashReportAttachments =
(attachments ?? []).map((e) {
return CrashReportAttachment.string(
field: 'attachment_${e.id}',
value: e.stringValue,
);
}).toList();
var crashReportAttachments = (attachments ?? []).map((e) {
return CrashReportAttachment.string(
field: 'attachment_${e.id}',
value: e.stringValue,
);
}).toList();
if (exception is CaughtException) {
// Get the root CaughtException, which matters most for debugging.
@@ -142,8 +142,9 @@ class DevAnalysisServer {
}),
);
directories =
directories.map((dir) => path.normalize(path.absolute(dir))).toList();
directories = directories
.map((dir) => path.normalize(path.absolute(dir)))
.toList();
await _channel.simulateRequestFromClient(
Request('${_nextId++}', 'analysis.setAnalysisRoots', {
+16 -20
View File
@@ -377,10 +377,9 @@ class Driver implements ServerStarter {
ErrorNotifier errorNotifier,
SendPort? sendPort,
) {
var capture =
results.flag(DISABLE_SERVER_EXCEPTION_HANDLING)
? (_, Function f, {void Function(String)? print}) => f()
: _captureExceptions;
var capture = results.flag(DISABLE_SERVER_EXCEPTION_HANDLING)
? (_, Function f, {void Function(String)? print}) => f()
: _captureExceptions;
var trainDirectory = results.option(TRAIN_USING);
if (trainDirectory != null) {
if (!FileSystemEntity.isDirectorySync(trainDirectory)) {
@@ -479,10 +478,9 @@ class Driver implements ServerStarter {
if (sendPort == null) exit(0);
});
},
print:
results.flag(INTERNAL_PRINT_TO_CONSOLE)
? null
: diagnosticServer.httpServer.recordPrint,
print: results.flag(INTERNAL_PRINT_TO_CONSOLE)
? null
: diagnosticServer.httpServer.recordPrint,
);
}
}
@@ -496,10 +494,9 @@ class Driver implements ServerStarter {
int? diagnosticServerPort,
ErrorNotifier errorNotifier,
) {
var capture =
args.flag(DISABLE_SERVER_EXCEPTION_HANDLING)
? (_, Function f, {void Function(String)? print}) => f()
: _captureExceptions;
var capture = args.flag(DISABLE_SERVER_EXCEPTION_HANDLING)
? (_, Function f, {void Function(String)? print}) => f()
: _captureExceptions;
linter.registerLintRules();
registerBuiltInAssistGenerators();
@@ -555,14 +552,13 @@ class Driver implements ServerStarter {
throw exception;
}
var printFunction =
print == null
? null
: (Zone self, ZoneDelegate parent, Zone zone, String line) {
// Note: we don't pass the line on to stdout, because that is
// reserved for communication to the client.
print(line);
};
var printFunction = print == null
? null
: (Zone self, ZoneDelegate parent, Zone zone, String line) {
// Note: we don't pass the line on to stdout, because that is
// reserved for communication to the client.
print(line);
};
var zoneSpecification = ZoneSpecification(
handleUncaughtError: errorFunction,
print: printFunction,

Some files were not shown because too many files have changed in this diff Show More