diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart index e8ff835e510..79b82ede30c 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart @@ -351,13 +351,16 @@ class SuggestionBuilder { /// If [includeTrailingComma] is `true` then the completion text will include /// a trailing comma, such as when the closure is part of an argument list. void suggestClosure(FunctionType type, {bool includeTrailingComma = false}) { + var includeTypes = + request.fileState.analysisOptions.codeStyleOptions.specifyTypes; var indent = getRequestLineIndent(request); - var parametersString = buildClosureParameters(type); - // Build a version of the parameter string without keywords for the - // completion label because `required` is less useful and may push the - // end of the completion (`=>` vs `() {}`) off the end. - var parametersDisplayString = - buildClosureParameters(type, includeKeywords: false); + var parametersString = buildClosureParameters(type, + includeTypes: includeTypes, includeKeywords: true); + // Build a short version of the parameter string without keywords or types + // for the completion label because they're less useful there and may push + // the end of the completion (`=>` vs `() {}`) off the end. + var parametersDisplayString = buildClosureParameters(type, + includeKeywords: false, includeTypes: false); var blockBuffer = StringBuffer(parametersString); blockBuffer.writeln(' {'); diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart index e488fc0cab1..a7f0e27def8 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart @@ -31,8 +31,11 @@ Comparator completionComparator = (a, b) { return b.relevance.compareTo(a.relevance); }; -String buildClosureParameters(FunctionType type, - {bool includeKeywords = true}) { +String buildClosureParameters( + FunctionType type, { + required bool includeTypes, + required bool includeKeywords, +}) { var buffer = StringBuffer(); buffer.write('('); @@ -52,6 +55,10 @@ String buildClosureParameters(FunctionType type, hasOptionalPositional = true; buffer.write('['); } + if (includeTypes) { + buffer.write(parameter.type); + buffer.write(' '); + } var name = parameter.name; if (name.isEmpty) { name = 'p$i'; diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/closure_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/closure_test.dart index b317e91c8ad..631ccdd67c2 100644 --- a/pkg/analysis_server/test/services/completion/dart/declaration/closure_test.dart +++ b/pkg/analysis_server/test/services/completion/dart/declaration/closure_test.dart @@ -1,5 +1,8 @@ +import 'package:analysis_server/src/services/linter/lint_names.dart'; +import 'package:linter/src/rules.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; +import '../../../../analysis_server_base.dart'; import '../../../../client/completion_driver_test.dart'; void main() { @@ -116,6 +119,29 @@ ${' ' * 4} '''); } + Future test_lint_alwaysSpecifyTypes() async { + registerLintRules(); + writeTestPackageAnalysisOptionsFile( + AnalysisOptionsFileConfig(lints: [LintNames.always_specify_types]), + ); + + await computeSuggestions(''' +void Function(List a, Object? b, [dynamic c]) v = ^; +'''); + assertResponse(''' +suggestions + |(List a, Object? b, [dynamic c]) => | + kind: invocation + displayText: (a, b, [c]) => + (List a, Object? b, [dynamic c]) { +${' ' * 2} +} + kind: invocation + displayText: (a, b, [c]) {} + selection: 42 +'''); + } + Future test_parameters_optionalNamed() async { await computeSuggestions(''' void f({void Function(int a, {int b, int c}) closure}) {}