Skip to content

Commit 7a16a44

Browse files
DanTupCommit Queue
authored andcommitted
[analysis_server] Add support for type inlay hints for dot shorthands
Fixes #61841 Change-Id: I0697c9a05639e723aec32e84b1680f72a2241d5c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/458300 Commit-Queue: Brian Wilkerson <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Kallen Tu <[email protected]>
1 parent f8ccea7 commit 7a16a44

File tree

5 files changed

+135
-9
lines changed

5 files changed

+135
-9
lines changed

pkg/analysis_server/lib/src/computer/computer_inlay_hint.dart

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ class DartInlayHintComputer {
3838
_lineInfo = result.lineInfo,
3939
_config = config ?? LspClientInlayHintsConfiguration(null);
4040

41+
/// Adds a type hint before [period] showing a label for the type [type].
42+
void addDotShorthandTypePrefix(Token period, DartType? type) {
43+
if (type == null) {
44+
return;
45+
}
46+
47+
_addTypePrefix(
48+
period,
49+
type,
50+
_InlayHintKind.dotShorthandType,
51+
paddingRight: false,
52+
);
53+
}
54+
4155
/// Adds a parameter name hint before [nodeOrToken] showing a the name for
4256
/// [parameter].
4357
///
@@ -80,15 +94,20 @@ class DartInlayHintComputer {
8094
///
8195
/// Padding will be added between the hint and [entity] automatically.
8296
void addParameterTypePrefix(SyntacticEntity entity, DartType type) {
83-
_addTypePrefix(entity, type, _InlayHintKind.parameterType);
97+
_addTypePrefix(
98+
entity,
99+
type,
100+
_InlayHintKind.parameterType,
101+
paddingRight: true,
102+
);
84103
}
85104

86105
/// Adds a return type hint before [token] showing a label for the type
87106
/// [type].
88107
///
89108
/// Padding will be added between the hint and [token] automatically.
90109
void addReturnTypePrefix(Token token, DartType type) {
91-
_addTypePrefix(token, type, _InlayHintKind.returnType);
110+
_addTypePrefix(token, type, _InlayHintKind.returnType, paddingRight: true);
92111
}
93112

94113
/// Adds a type hint for [nodeOrToken] showing a label for type arguments
@@ -128,7 +147,12 @@ class DartInlayHintComputer {
128147
///
129148
/// Padding will be added between the hint and [entity] automatically.
130149
void addVariableTypePrefix(SyntacticEntity entity, DartType type) {
131-
_addTypePrefix(entity, type, _InlayHintKind.variableType);
150+
_addTypePrefix(
151+
entity,
152+
type,
153+
_InlayHintKind.variableType,
154+
paddingRight: true,
155+
);
132156
}
133157

134158
List<InlayHint> compute() {
@@ -157,6 +181,7 @@ class DartInlayHintComputer {
157181
/// Record [hint] if the user configuration has [kind] enabled.
158182
void _addHint(InlayHint hint, _InlayHintKind kind) {
159183
var isEnabled = switch (kind) {
184+
_InlayHintKind.dotShorthandType => _config.dotShorthandTypesEnabled,
160185
_InlayHintKind.parameterNameLiteral =>
161186
_config.parameterNamesMode != InlayHintsParameterNamesMode.none,
162187
_InlayHintKind.parameterNameNonLiteral =>
@@ -174,12 +199,15 @@ class DartInlayHintComputer {
174199

175200
/// Adds a type hint before [nodeOrToken] showing a label for the type [type].
176201
///
177-
/// Padding will be added between the hint and [nodeOrToken] automatically.
202+
/// If [paddingRight] is `true`, padding will be added to the right of the
203+
/// type name automatically (which is desired except in the case where the
204+
/// following character is a `.` such as a dot shorthand).
178205
void _addTypePrefix(
179206
SyntacticEntity nodeOrToken,
180207
DartType type,
181-
_InlayHintKind inlayHintKind,
182-
) {
208+
_InlayHintKind inlayHintKind, {
209+
required bool paddingRight,
210+
}) {
183211
var offset = nodeOrToken.offset;
184212
var position = toPosition(_lineInfo.getLocation(offset));
185213
var labelParts = <InlayHintLabelPart>[];
@@ -189,7 +217,7 @@ class DartInlayHintComputer {
189217
label: Either2<List<InlayHintLabelPart>, String>.t1(labelParts),
190218
position: position,
191219
kind: InlayHintKind.Type,
192-
paddingRight: true,
220+
paddingRight: paddingRight,
193221
),
194222
inlayHintKind,
195223
);
@@ -356,6 +384,29 @@ class _DartInlayHintComputerVisitor extends GeneralizingAstVisitor<void> {
356384
}
357385
}
358386

387+
@override
388+
void visitDotShorthandConstructorInvocation(
389+
DotShorthandConstructorInvocation node,
390+
) {
391+
super.visitDotShorthandConstructorInvocation(node);
392+
393+
_computer.addDotShorthandTypePrefix(node.period, node.staticType);
394+
}
395+
396+
@override
397+
void visitDotShorthandInvocation(DotShorthandInvocation node) {
398+
super.visitDotShorthandInvocation(node);
399+
400+
_computer.addDotShorthandTypePrefix(node.period, node.staticType);
401+
}
402+
403+
@override
404+
void visitDotShorthandPropertyAccess(DotShorthandPropertyAccess node) {
405+
super.visitDotShorthandPropertyAccess(node);
406+
407+
_computer.addDotShorthandTypePrefix(node.period, node.staticType);
408+
}
409+
359410
@override
360411
void visitFunctionDeclaration(FunctionDeclaration node) {
361412
super.visitFunctionDeclaration(node);
@@ -489,10 +540,11 @@ class _DartInlayHintComputerVisitor extends GeneralizingAstVisitor<void> {
489540
///
490541
/// Each of these can be mapped into a configuration setting that controls it.
491542
enum _InlayHintKind {
543+
dotShorthandType,
492544
parameterNameLiteral,
493545
parameterNameNonLiteral,
494-
returnType,
495546
parameterType,
496-
variableType,
547+
returnType,
497548
typeArgument,
549+
variableType,
498550
}

pkg/analysis_server/lib/src/lsp/client_configuration.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class LspClientConfiguration {
184184
/// "dart.inlayHints": false, // Disables all Inlay Hints
185185
///
186186
/// "dart.inlayHints": {
187+
/// "dotShorthandTypes": { "enabled": true },
187188
/// "parameterNames": { "enabled": "literal" },
188189
/// "parameterTypes": { "enabled": true },
189190
/// "returnTypes": { "enabled": false },
@@ -192,6 +193,7 @@ class LspClientConfiguration {
192193
/// }
193194
/// ```
194195
class LspClientInlayHintsConfiguration {
196+
late bool _dotShorthandTypes;
195197
late InlayHintsParameterNamesMode _parameterNames;
196198
late bool _parameterTypes;
197199
late bool _returnTypes;
@@ -202,6 +204,7 @@ class LspClientInlayHintsConfiguration {
202204
var map = userPreference is Map<String, Object?> ? userPreference : null;
203205
var boolean = userPreference is bool ? userPreference : null;
204206

207+
_dotShorthandTypes = _getEnabled(map, 'dotShorthandTypes', boolean ?? true);
205208
_parameterNames = _getParameterNamesMode(
206209
map,
207210
boolean ?? true
@@ -214,6 +217,9 @@ class LspClientInlayHintsConfiguration {
214217
_variableTypes = _getEnabled(map, 'variableTypes', boolean ?? true);
215218
}
216219

220+
/// Whether dot shorthand type inlay hints are enabled.
221+
bool get dotShorthandTypesEnabled => _dotShorthandTypes;
222+
217223
/// Which kind of parameter names to show inlay hints for.
218224
InlayHintsParameterNamesMode get parameterNamesMode => _parameterNames;
219225

pkg/analysis_server/test/lsp/client_configuration_test.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,35 @@ class ClientConfigurationTest with ResourceProviderMixin {
6767
/// for each kind of hint.
6868
@reflectiveTest
6969
class InlayHintsConfigurationTest {
70+
void test_dotShorthandTypes_disabled() {
71+
var options = [
72+
LspClientInlayHintsConfiguration(false),
73+
LspClientInlayHintsConfiguration({'dotShorthandTypes': false}),
74+
LspClientInlayHintsConfiguration({
75+
'dotShorthandTypes': {'enabled': false},
76+
}),
77+
];
78+
79+
for (var option in options) {
80+
expect(option.dotShorthandTypesEnabled, false);
81+
}
82+
}
83+
84+
void test_dotShorthandTypes_enabled() {
85+
var options = [
86+
LspClientInlayHintsConfiguration(null),
87+
LspClientInlayHintsConfiguration(true),
88+
LspClientInlayHintsConfiguration({'dotShorthandTypes': true}),
89+
LspClientInlayHintsConfiguration({
90+
'dotShorthandTypes': {'enabled': true},
91+
}),
92+
];
93+
94+
for (var option in options) {
95+
expect(option.dotShorthandTypesEnabled, true);
96+
}
97+
}
98+
7099
void test_parameterNames_all() {
71100
var options = [
72101
LspClientInlayHintsConfiguration(null),

pkg/analysis_server/test/lsp/inlay_hint_test.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,44 @@ final a = 1;
385385
expect(hintsAfterChange, isNotEmpty);
386386
}
387387

388+
Future<void> test_dotShorthand_constructorInvocation() async {
389+
var content = '''
390+
class A {
391+
const A.named();
392+
}
393+
394+
A newA() => .named();
395+
''';
396+
var expected = '''
397+
class A {
398+
const A.named();
399+
}
400+
401+
A newA() => (Type:A).named();
402+
''';
403+
await _expectHints(content, expected);
404+
}
405+
406+
Future<void> test_dotShorthand_invocation() async {
407+
var content = '''
408+
int a = .parse('1');
409+
''';
410+
var expected = '''
411+
int a = (Type:int).parse((Parameter:source:) '1');
412+
''';
413+
await _expectHints(content, expected);
414+
}
415+
416+
Future<void> test_dotShorthand_propertyAccess() async {
417+
var content = '''
418+
Duration zero() => .zero;
419+
''';
420+
var expected = '''
421+
Duration zero() => (Type:Duration).zero;
422+
''';
423+
await _expectHints(content, expected);
424+
}
425+
388426
Future<void> test_forElement() async {
389427
var content = '''
390428
void f() {

pkg/analysis_server/tool/lsp_spec/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Client workspace settings are requested with `workspace/configuration` during in
4545
- `dart.documentation` (`none`, `summary`, `full`): The kind of dartdocs to include in requests that can return large numbers of results such as Code Completion. If not set, defaults to `full`.
4646
- `dart.includeDependenciesInWorkspaceSymbols` (`bool?`): Whether to include symbols from dependencies and Dart/Flutter SDKs in Workspace Symbol results. If not set, defaults to `true`.
4747
- `dart.inlayHints` (`bool?` | `Object?`): Whether to show Inlay Hints. When set to `true`, enables all inlay hints with default settings. When set to `false`, disables all inlay hints. Can also be an object to configure individual hint types as defined below. Defaults to `true`.
48+
- `dotShorthandTypes` (`{ "enabled": bool }`): Whether to show Inlay Hints for dot shorthand types.
4849
- `parameterNames` (`{ "enabled": true | false | "none" | "literal" | "all" }`): Controls parameter name hints.
4950
- `"none"` or `false`: show no parameter name hints
5051
- `"literal"`: show hints only for arguments with literal values

0 commit comments

Comments
 (0)