Skip to content

Commit

Permalink
Version 3.7.0-137.0.dev
Browse files Browse the repository at this point in the history
Merge 526c575 into dev
  • Loading branch information
Dart CI committed Nov 12, 2024
2 parents 5f42ef8 + 526c575 commit cdc17e2
Show file tree
Hide file tree
Showing 34 changed files with 506 additions and 390 deletions.
77 changes: 35 additions & 42 deletions pkg/analysis_server/lib/src/computer/computer_hover.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:analysis_server/protocol/protocol_generated.dart'
import 'package:analysis_server/src/computer/computer_documentation.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/element_locator.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
Expand Down Expand Up @@ -63,20 +63,16 @@ class DartUnitHoverComputer {
var range = _hoverRange(node, locationEntity);
var hover = HoverInformation(range.offset, range.length);
// element
var element = ElementLocator.locate(node);
var element = ElementLocator.locate2(node);
if (element != null) {
// use the non-synthetic element to get things like dartdoc from the
// underlying field (and resolved type args), except for `enum.values`
// because that will resolve to the enum itself.
if (_useNonSyntheticElement(element)) {
element = element.nonSynthetic;
}
// short code that illustrates the element meaning.
hover.elementDescription = _elementDisplayString(node, element);
hover.elementKind = element.kind.displayName;
hover.isDeprecated = element.hasDeprecated;
if (element case Annotatable a) {
hover.isDeprecated = a.metadata2.hasDeprecated;
}
// not local element
if (element.enclosingElement3 is! ExecutableElement) {
if (element.enclosingElement2 is! ExecutableElement2) {
// containing class
hover.containingClassDescription = _containingClass(element);
// containing library
Expand All @@ -85,7 +81,7 @@ class DartUnitHoverComputer {
hover.containingLibraryPath = libraryInfo?.libraryPath;
}
// documentation
hover.dartdoc = _documentationComputer.computePreferred(
hover.dartdoc = _documentationComputer.computePreferred2(
element,
documentationPreference,
);
Expand All @@ -102,8 +98,8 @@ class DartUnitHoverComputer {
}

/// Gets the name of the containing class of [element].
String? _containingClass(Element element) {
var containingClass = element.thisOrAncestorOfType<InterfaceElement>();
String? _containingClass(Element2 element) {
var containingClass = element.thisOrAncestorOfType2<InterfaceElement2>();
return containingClass != null && containingClass != element
? containingClass.displayName
: null;
Expand All @@ -114,8 +110,8 @@ class DartUnitHoverComputer {
/// This is usually `element.getDisplayString()` but may contain additional
/// information to disambiguate things like constructors from types (and
/// whether they are const).
String? _elementDisplayString(AstNode node, Element? element) {
var displayString = element?.getDisplayString(multiline: true);
String? _elementDisplayString(AstNode node, Element2? element) {
var displayString = element?.displayString2(multiline: true);

if (displayString != null &&
node is InstanceCreationExpression &&
Expand Down Expand Up @@ -150,13 +146,14 @@ class DartUnitHoverComputer {
}

/// Returns information about the library that contains [element].
_LibraryInfo _libraryInfo(Element element) {
var library = element.library;
_LibraryInfo _libraryInfo(Element2 element) {
var library = element.library2;
if (library == null) {
return null;
}

var uri = library.source.uri;
var definingSource = library.firstFragment.source;
var uri = definingSource.uri;
var analysisSession = _unit.declaredElement?.session;

String? libraryName, libraryPath;
Expand All @@ -178,7 +175,7 @@ class DartUnitHoverComputer {
} else {
libraryName = uri.toString();
}
libraryPath = library.source.fullName;
libraryPath = definingSource.fullName;

return (libraryName: libraryName, libraryPath: libraryPath);
}
Expand Down Expand Up @@ -211,10 +208,19 @@ class DartUnitHoverComputer {
///
/// Returns `null` if the parameter is not an expression.
String? _parameterDisplayString(AstNode node) {
if (node is Expression) {
return _elementDisplayString(node, node.staticParameterElement);
if (node is! Expression) {
return null;
}
return null;
var parameter = node.correspondingParameter;
return switch (parameter?.enclosingElement2) {
// Expressions passed as arguments to setters and binary expressions
// will have parameters here but we don't want them to show as such in
// hovers because information about those functions are already available
// by hovering over the function name or the operator.
SetterElement() => null,
MethodElement2 method when method.isOperator => null,
_ => _elementDisplayString(node, parameter),
};
}

/// Adjusts the target node for constructors.
Expand All @@ -237,15 +243,16 @@ class DartUnitHoverComputer {
}

/// Returns information about the static type of [node].
String? _typeDisplayString(AstNode node, Element? element) {
String? _typeDisplayString(AstNode node, Element2? element) {
var parent = node.parent;
DartType? staticType;
if (node is Expression &&
(element == null ||
element is VariableElement ||
element is PropertyAccessorElement)) {
element is VariableElement2 ||
element is GetterElement ||
element is SetterElement)) {
staticType = _getTypeOfDeclarationOrReference(node);
} else if (element is VariableElement) {
} else if (element is VariableElement2) {
staticType = element.type;
} else if (parent is MethodInvocation && parent.methodName == node) {
staticType = parent.staticInvokeType;
Expand All @@ -260,24 +267,10 @@ class DartUnitHoverComputer {
return staticType?.getDisplayString();
}

/// Whether to use the non-synthetic element for hover information.
///
/// Usually we want this because the non-synthetic element will include the
/// users DartDoc and show any type arguments as declared.
///
/// For enum.values, nonSynthetic returns the enum itself which causes
/// incorrect types to be shown and so we stick with the synthetic getter.
bool _useNonSyntheticElement(Element element) {
return element is PropertyAccessorElement &&
!(element.enclosingElement3 is EnumElement &&
element.name == 'values' &&
element.isSynthetic);
}

static DartType? _getTypeOfDeclarationOrReference(Expression node) {
if (node is SimpleIdentifier) {
var element = node.staticElement;
if (element is VariableElement) {
var element = node.element;
if (element is VariableElement2) {
if (node.inDeclarationContext()) {
return element.type;
}
Expand Down
18 changes: 16 additions & 2 deletions pkg/analysis_server/lib/src/lsp/error_or.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,24 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
import 'package:meta/meta.dart';

ErrorOr<R> cancelled<R>() =>
error(ErrorCodes.RequestCancelled, 'Request was cancelled');
ErrorOr<R> cancelled<R>([CancellationToken? token]) {
var code = ErrorCodes.RequestCancelled;
var reason = 'Request was cancelled';

if (token is CancelableToken) {
if (token.cancellationCode case var cancellationCode?) {
code = ErrorCodes(cancellationCode);
}
if (token.cancellationReason case var cancellationReason?) {
reason = cancellationReason;
}
}

return error(code, reason);
}

ErrorOr<R> error<R>(ErrorCodes code, String message, [String? data]) =>
ErrorOr<R>.error(ResponseError(code: code, message: message, data: data));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,10 @@ class LspRefactorManager {

/// Begins a new refactor, cancelling any other in-progress refactors.
void begin(CancelableToken cancelToken) {
_currentRefactoringCancellationToken?.cancel();
_currentRefactoringCancellationToken?.cancel(
reason:
'Another workspace/executeCommand request for a refactor was started',
);
_currentRefactoringCancellationToken = cancelToken;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class FixAllCommandHandler extends SimpleEditCommandHandler {
// Before we send an edit back, ensure the original file didn't change
// (or the request cancelled) while we were computing changes.
if (cancellationToken.isCancellationRequested) {
return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
return cancelled(cancellationToken);
}
// If the client modified the file, it's possible (though unlikely since
// we only just unlocked the queue and having had many 'await's) that the
Expand Down Expand Up @@ -106,7 +106,7 @@ class _FixAllOperation extends TemporaryOverlayOperation

Future<ErrorOr<WorkspaceEdit?>> _computeEditsImpl() async {
if (cancellationToken.isCancellationRequested) {
return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
return cancelled(cancellationToken);
}

var context = server.contextManager.getContextFor(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class OrganizeImportsCommandHandler extends SimpleEditCommandHandler {
var result = await requireResolvedUnit(path);

if (cancellationToken.isCancellationRequested) {
return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
return cancelled(cancellationToken);
}

return result.mapResult((result) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import 'dart:async';

import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/client_capabilities.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
import 'package:analysis_server/src/lsp/handlers/commands/abstract_refactor.dart';
Expand Down Expand Up @@ -80,13 +79,13 @@ class PerformRefactorCommandHandler extends AbstractRefactorCommandHandler {
}

if (cancelableToken.isCancellationRequested) {
return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
return cancelled(cancelableToken);
}

var change = await refactoring.createChange();

if (cancelableToken.isCancellationRequested) {
return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
return cancelled(cancelableToken);
}

if (change.edits.isEmpty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class SortMembersCommandHandler extends SimpleEditCommandHandler {
var result = session?.getParsedUnit(path);

if (cancellationToken.isCancellationRequested) {
return error(ErrorCodes.RequestCancelled, 'Request was cancelled');
return cancelled(cancellationToken);
}

if (result is! ParsedUnitResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class EditableArgumentsHandler
if (fileHasBeenModified(filePath, docIdentifier.version)) {
return fileModifiedError;
} else if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

// Compute the editable arguments for an invocation at `offset`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ class CompletionHandler
// Cancel any existing in-progress completion request in case the client did
// not do it explicitly, because the results will not be useful and it may
// delay processing this one.
previousRequestCancellationToken?.cancel();
previousRequestCancellationToken?.cancel(
reason: 'Another textDocument/completion request was started',
);
previousRequestCancellationToken = token.asCancelable();

var requestLatency = message.timeSinceRequest;
Expand Down Expand Up @@ -131,7 +133,7 @@ class CompletionHandler
await delayAfterResolveForTests;
}
if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

// Map the offset, propagating the previous failure if we didn't have a
Expand Down Expand Up @@ -401,7 +403,7 @@ class CompletionHandler
);

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

/// completeFunctionCalls should be suppressed if the target is an
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class CompletionResolveHandler
}

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

var builder = ChangeBuilder(session: session);
Expand All @@ -99,7 +99,7 @@ class CompletionResolveHandler
});

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

var changes = builder.sourceChange;
Expand Down Expand Up @@ -219,7 +219,7 @@ class CompletionResolveHandler
);

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

var description = packageDetails?.description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class InlayHintHandler
}

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

return result.mapResult((result) async {
Expand Down
8 changes: 4 additions & 4 deletions pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class RenameHandler extends LspMessageHandler<RenameParams, WorkspaceEdit?> {
// Check the rename is valid here.
var initStatus = await refactoring.checkInitialConditions();
if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}
if (initStatus.hasFatalError) {
return error(
Expand All @@ -203,7 +203,7 @@ class RenameHandler extends LspMessageHandler<RenameParams, WorkspaceEdit?> {
// Final validation.
var finalStatus = await refactoring.checkFinalConditions();
if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}
if (finalStatus.hasFatalError) {
return error(
Expand All @@ -227,7 +227,7 @@ class RenameHandler extends LspMessageHandler<RenameParams, WorkspaceEdit?> {
);

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

if (userChoice != UserPromptActions.renameAnyway) {
Expand All @@ -248,7 +248,7 @@ class RenameHandler extends LspMessageHandler<RenameParams, WorkspaceEdit?> {
refactoring.includePotential = false;
var change = await refactoring.createChange();
if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

// Before we send anything back, ensure the original file didn't change
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ abstract class AbstractSemanticTokensHandler<T>
var pluginHighlightRegions = getPluginResults(path).flattenedToList;

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

var encoder = SemanticTokenEncoder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class WillRenameFilesHandler
// nothing rather than interrupt the users file rename with an error.
var results = await refactoring.checkAllConditions();
if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

if (results.hasFatalError) {
Expand All @@ -98,7 +98,7 @@ class WillRenameFilesHandler
}

if (token.isCancellationRequested) {
return cancelled();
return cancelled(token);
}

server.checkConsistency(sessions);
Expand Down
Loading

0 comments on commit cdc17e2

Please sign in to comment.