Version 3.15.0-145.0.dev Merge ff8d9b658754ac09bec3ac7aba4f1afe27a6c09f into dev
diff --git a/DEPS b/DEPS index c9ed3b0..f312545 100644 --- a/DEPS +++ b/DEPS
@@ -133,22 +133,22 @@ ### /third_party/pkg dependencies # 'tools/rev_sdk_deps.dart' will rev pkg dependencies to their latest; put an # EOL comment after a dependency to instead pin at the current revision. - "core_rev": "36f57a994965785d641e436b7dd3aa8a18a26f62", - "dartdoc_rev": "03ec6df6228ac8257a737261d17e746c665b1e13", - "ecosystem_rev": "54e16739d9c15ef0b77e050242c16226ad9235f9", + "core_rev": "fa0c6b77d67b6837eb2891e251c40cdfbeab1f4d", + "dartdoc_rev": "7e2508c61a41443c99b78f5ca26ddc456cf0c1c2", + "ecosystem_rev": "1d2b5ff862c6b93cd86dd06eadac4c9f4d5d6c20", "flute_rev": "b84119fba67016a80c3eb80765762bcc4d0d0b8d", - "http_rev": "4646fe66ca78423f28333ca7f46c543dc902daf8", + "http_rev": "2bac218a1115a58addd140d7a7eaabf803d57631", "i18n_rev": "7475ce643ed6210e5e787b310bb5bc24de9a2158", "leak_tracker_rev": "f5620600a5ce1c44f65ddaa02001e200b096e14c", # rolled manually "material_color_utilities_rev": "799b6ba2f3f1c28c67cc7e0b4f18e0c7d7f3c03e", - "native_rev": "6287745caa4c742a975a7958387fa07b909e9957", + "native_rev": "b21ef2da3c580377f9465eac7f8ce22a097c0de6", "protobuf_rev": "19191c8c5881d4a63db804bbed26fa1dcdd17ed0", "pub_rev": "9df389a76385f82c1165c7cf93b78807b5ea8890", # rolled manually - "shelf_rev": "9946de555f1eb3abd8ae5054848b9c3c2bd36e4d", + "shelf_rev": "b175e9f1407994c751c1c1c976c3c80e2971e85c", "sync_http_rev": "6666fff944221891182e1f80bf56569338164d72", "tar_rev": "201952a191be34a993f4ae182612c891ea4ef0a2", - "test_rev": "2a9e01756f42123102a34faf2964130ba7e0f77a", - "tools_rev": "727fd9c2fac0efe5eb60d23ef8a24ef90b1326d0", + "test_rev": "3533ae1e81fdf9aab93f1d579cddeb5c5b3a2839", + "tools_rev": "589d844c4e0c363ca6d2811eb328aede33f0cf30", "vector_math_rev": "cf3b5db7340d317dd3489e5a35434b408020a852", "web_rev": "4e60e61e55e1e2111f0fec9d19efff577c0dc671", "webdriver_rev": "8e5c611ea242efdc9f597a8a37c38a9c586120ee",
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart index d56215f..1c7ae5f 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
@@ -116,7 +116,7 @@ var paramString = hasParams ? (parameters == '()' ? '()' : '(…)') : ''; var name = declaration.name; - var containerName = declaration.className ?? declaration.mixinName; + var containerName = declaration.containerName; // Constructors are always prefixed with the class name, and we never show // 'new'. var fullName = switch ((isConstructor, name)) {
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart index 92e44af..83c03ca 100644 --- a/pkg/analysis_server/test/lsp/server_abstract.dart +++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -895,6 +895,14 @@ }); } + void setWorkspaceSymbolKinds(List<SymbolKind> kinds) { + workspaceCapabilities = extendWorkspaceCapabilities(workspaceCapabilities, { + 'symbol': { + 'symbolKind': {'valueSet': kinds.map((k) => k.toJson()).toList()}, + }, + }); + } + WorkspaceClientCapabilities _withResourceOperationKinds( WorkspaceClientCapabilities source, List<ResourceOperationKind> kinds,
diff --git a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart index 5dcc5a0..62e5455 100644 --- a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart +++ b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
@@ -310,6 +310,48 @@ expect(await getWorkspaceSymbols('LocalClass12345'), isNotEmpty); } + Future<void> test_enum() async { + const content = ''' +enum NamedEnum { x } +'''; + var code = TestCode.parse(content); + newFile(mainFilePath, code.code); + + failTestOnErrorDiagnostic = false; + await provideConfig(initialize, { + 'includeDependenciesInWorkspaceSymbols': false, + }); + + var symbols = await getWorkspaceSymbols('Named'); + expect(symbols, hasLength(1)); + var symbol = symbols.single; + expect(symbol.containerName, isNull); + expect(symbol.name, 'NamedEnum'); + expect(symbol.kind, SymbolKind.Enum); + } + + Future<void> test_enum_member() async { + setWorkspaceSymbolKinds([SymbolKind.Enum, SymbolKind.EnumMember]); + + const content = ''' +enum NamedEnum { namedEnumConstant } +'''; + var code = TestCode.parse(content); + newFile(mainFilePath, code.code); + + failTestOnErrorDiagnostic = false; + await provideConfig(initialize, { + 'includeDependenciesInWorkspaceSymbols': false, + }); + + var symbols = await getWorkspaceSymbols('namedEnumCon'); + expect(symbols, hasLength(1)); + var symbol = symbols.single; + expect(symbol.containerName, 'NamedEnum'); + expect(symbol.name, 'namedEnumConstant'); + expect(symbol.kind, SymbolKind.EnumMember); + } + Future<void> test_enum_unnamed() async { const content = ''' enum { @@ -365,6 +407,28 @@ expect(namedExtensions.containerName, isNull); } + Future<void> test_extensionType_member() async { + const content = ''' +extension NamedExtensionType on int { + void namedMethod() {} +} +'''; + var code = TestCode.parse(content); + newFile(mainFilePath, code.code); + + failTestOnErrorDiagnostic = false; + await provideConfig(initialize, { + 'includeDependenciesInWorkspaceSymbols': false, + }); + + var symbols = await getWorkspaceSymbols('namedMet'); + expect(symbols, hasLength(1)); + var symbol = symbols.single; + expect(symbol.containerName, 'NamedExtensionType'); + expect(symbol.name, 'namedMethod()'); + expect(symbol.kind, SymbolKind.Method); + } + Future<void> test_extensionType_method() async { const content = r''' extension type E(int it) {
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart index c1a3755..63d1306 100644 --- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart +++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -932,10 +932,11 @@ required MetricsSuggestionListener listener, required CompletionMetrics metrics, }) async { + assert(expectedCompletion.syntacticEntity.length >= options.prefixLength); var stopwatch = Stopwatch()..start(); var request = DartCompletionRequest.forResolvedUnit( resolvedUnit: resolvedUnitResult, - offset: expectedCompletion.offset, + offset: expectedCompletion.offset + options.prefixLength, ); var opType = OpType.forCompletion(request.target, request.offset); @@ -1038,10 +1039,16 @@ var charsBeforeTop = _computeCharsBeforeTop( expectedCompletion, suggestions, + targetRank: rank, ); metrics.charsBeforeTop.addValue(charsBeforeTop); metrics.charsBeforeTopFive.addValue( - _computeCharsBeforeTop(expectedCompletion, suggestions, minRank: 5), + _computeCharsBeforeTop( + expectedCompletion, + suggestions, + targetRank: rank, + minRank: 5, + ), ); metrics.insertionLengthTheoretical.addValue( expectedCompletion.completion.length - charsBeforeTop, @@ -1548,21 +1555,36 @@ @override void setupForResolution(AnalysisContext context) {} + /// Computes the number of characters that need to be typed before [target] + /// with [targetRank] would be in the top [minRank] results. int _computeCharsBeforeTop( ExpectedCompletion target, List<CandidateSuggestion> suggestions, { + required int targetRank, int minRank = 1, }) { - var rank = placementInSuggestionList(suggestions, target).rank; - if (rank <= minRank) { + if (targetRank <= minRank) { return 0; } + // Ranks are 1-based, so `target` is at index `targetRank - 1`. Only + // suggestions before `targetIndex` can still rank ahead of `target` after + // filtering, so we only need to check those, not the entire list. + var targetIndex = targetRank - 1; var expected = target.completion; for (var i = 1; i < expected.length + 1; i++) { var prefix = expected.substring(0, i); - var filteredSuggestions = _filterSuggestions(prefix, suggestions); - rank = placementInSuggestionList(filteredSuggestions, target).rank; - if (rank <= minRank) { + var newRank = 1; + for (var j = 0; j < targetIndex; j++) { + // TODO(brianwilkerson): Replace `startsWith` with a more realistic + // filtering algorithm. + if (suggestions[j].completion.startsWith(prefix)) { + newRank++; + if (newRank > minRank) { + break; + } + } + } + if (newRank <= minRank) { return i; } } @@ -1591,17 +1613,6 @@ return collector.suggestions; } - List<CandidateSuggestion> _filterSuggestions( - String prefix, - List<CandidateSuggestion> suggestions, - ) { - // TODO(brianwilkerson): Replace this with a more realistic filtering - // algorithm. - return suggestions - .where((suggestion) => suggestion.completion.startsWith(prefix)) - .toList(); - } - void _printWorstResults(String title, List<CompletionResult> worstResults) { List<String> suggestionRow(int rank, SuggestionData data) { var suggestion = data.suggestion;
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics_base.dart b/pkg/analysis_server/tool/code_completion/completion_metrics_base.dart index c2aabec..bcb3d37 100644 --- a/pkg/analysis_server/tool/code_completion/completion_metrics_base.dart +++ b/pkg/analysis_server/tool/code_completion/completion_metrics_base.dart
@@ -171,12 +171,11 @@ var length = expectedCompletion.syntacticEntity.length; assert(offset >= 0); assert(length > 0); + assert(length >= prefixLength); var tokenEndOffset = offset + length; - if (length >= prefixLength) { - // Rather than removing the whole token, remove the characters after - // the given prefix length. - offset += prefixLength; - } + // Rather than removing the whole token, remove the characters after + // the given prefix length. + offset += prefixLength; if (overlay == OverlayMode.removeToken) { return content.substring(0, offset) + content.substring(tokenEndOffset); } else if (overlay == OverlayMode.removeRestOfFile) {
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics_client.dart b/pkg/analysis_server/tool/code_completion/completion_metrics_client.dart index 1e8a09c..251d2ba 100644 --- a/pkg/analysis_server/tool/code_completion/completion_metrics_client.dart +++ b/pkg/analysis_server/tool/code_completion/completion_metrics_client.dart
@@ -540,10 +540,11 @@ ExpectedCompletion expectedCompletion, AnalysisContext context, ) async { + assert(expectedCompletion.syntacticEntity.length >= options.prefixLength); var stopwatch = Stopwatch()..start(); var suggestionsData = await client.requestCompletion( expectedCompletion.filePath, - expectedCompletion.offset, + expectedCompletion.offset + options.prefixLength, 1000, ); stopwatch.stop();
diff --git a/pkg/analysis_server/tool/code_completion/visitors.dart b/pkg/analysis_server/tool/code_completion/visitors.dart index dc57a7e..fca6cc3 100644 --- a/pkg/analysis_server/tool/code_completion/visitors.dart +++ b/pkg/analysis_server/tool/code_completion/visitors.dart
@@ -150,6 +150,8 @@ /// The offset from the location of each entity passed to /// [safelyRecordEntity], to be used as the column for each /// [ExpectedCompletion] created. + /// + /// Entities shorter than this offset are ignored. final int _caretOffset; /// The completions that are expected to be produced in the file being @@ -182,14 +184,15 @@ protocol.CompletionSuggestionKind? kind, protocol.ElementKind? elementKind, }) { - // Only record if this entity is not null, has a length, etc. - if (entity != null && entity.offset >= 0 && entity.length > 0) { + // Only record if this entity is not null, has offset/length, etc. and is at + // least at long as the caret offset. + if (entity != null && + entity.offset >= 0 && + entity.length > 0 && + entity.length >= _caretOffset) { var location = lineInfo.getLocation(entity.offset); var lineNumber = location.lineNumber; - var columnNumber = location.columnNumber; - if (entity.length >= _caretOffset) { - columnNumber += _caretOffset; - } + var columnNumber = location.columnNumber + _caretOffset; bool isKeyword() => kind == protocol.CompletionSuggestionKind.KEYWORD;
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart index 400e744..572381d 100644 --- a/pkg/analyzer/lib/src/dart/analysis/search.dart +++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -144,10 +144,18 @@ final int column; final int codeOffset; final int codeLength; - final String? className; - final String? mixinName; final String? parameters; + /// The name of the containing element, if it is an [InstanceElement]. + final String? containerName; + + /// The name of the containing element if it is an interface element but not + /// a mixin or enum. + final String? className; + + /// The name of the containing element if it is a mixin. + final String? mixinName; + new( this.fileIndex, this.lineInfo, @@ -158,6 +166,7 @@ this.column, this.codeOffset, this.codeLength, + this.containerName, this.className, this.mixinName, this.parameters, @@ -1534,6 +1543,11 @@ var enclosing = element.enclosingElement; + String? containerName = switch (enclosing) { + InstanceElement() => enclosing.name, + _ => null, + }; + String? className; String? mixinName; if (enclosing is EnumElement) { @@ -1607,6 +1621,7 @@ locationStart.columnNumber, fragmentImpl.codeOffset ?? 0, fragmentImpl.codeLength ?? 0, + containerName, className, mixinName, parameters,
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart index 0b9ce49..11bb444 100644 --- a/pkg/analyzer/test/src/dart/analysis/search_test.dart +++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -315,29 +315,35 @@ FIELD f offset: 16 2:7 codeOffset: 12 + 5 + containerName: C className: C CONSTRUCTOR new offset: 21 3:3 codeOffset: 21 + 4 + containerName: C className: C parameters: () CONSTRUCTOR named offset: 30 4:5 codeOffset: 28 + 10 + containerName: C className: C parameters: () GETTER g offset: 49 5:11 codeOffset: 41 + 15 + containerName: C className: C SETTER s offset: 68 6:12 codeOffset: 59 + 16 + containerName: C className: C parameters: (dynamic _) METHOD m offset: 83 7:8 codeOffset: 78 + 11 + containerName: C className: C parameters: () ''', @@ -467,12 +473,15 @@ ENUM_CONSTANT a offset: 11 2:3 codeOffset: 11 + 1 + containerName: E ENUM_CONSTANT bb offset: 14 2:6 codeOffset: 14 + 2 + containerName: E ENUM_CONSTANT ccc offset: 18 2:10 codeOffset: 18 + 3 + containerName: E ''', ); } @@ -529,16 +538,20 @@ FIELD f offset: 27 2:7 codeOffset: 23 + 5 + containerName: E GETTER g offset: 40 3:11 codeOffset: 32 + 15 + containerName: E SETTER s offset: 59 4:12 codeOffset: 50 + 16 + containerName: E parameters: (dynamic _) METHOD m offset: 74 5:8 codeOffset: 69 + 11 + containerName: E parameters: () ''', ); @@ -572,20 +585,24 @@ CONSTRUCTOR new offset: 15 1:16 codeOffset: 15 + 9 + containerName: E className: E parameters: (int it) GETTER g offset: 37 2:11 codeOffset: 29 + 15 + containerName: E className: E SETTER s offset: 56 3:12 codeOffset: 47 + 16 + containerName: E className: E parameters: (dynamic _) METHOD m offset: 71 4:8 codeOffset: 66 + 11 + containerName: E className: E parameters: () ''', @@ -688,19 +705,23 @@ FIELD f offset: 16 2:7 codeOffset: 12 + 5 + containerName: M mixinName: M GETTER g offset: 29 3:11 codeOffset: 21 + 15 + containerName: M mixinName: M SETTER s offset: 48 4:12 codeOffset: 39 + 16 + containerName: M mixinName: M parameters: (dynamic _) METHOD m offset: 63 5:8 codeOffset: 58 + 11 + containerName: M mixinName: M parameters: () ''', @@ -786,10 +807,12 @@ GETTER g offset: 20 2:11 codeOffset: 12 + 15 + containerName: C className: C METHOD m offset: 35 3:8 codeOffset: 30 + 26 + containerName: C className: C parameters: (int a, double b) FUNCTION f @@ -869,16 +892,19 @@ METHOD m1 offset: 24 2:8 codeOffset: 19 + 30 + containerName: A className: A parameters: (Map<int, String> a) METHOD m2 offset: 57 3:8 codeOffset: 52 + 26 + containerName: A className: A parameters: (Map<T, U> a) METHOD m3 offset: 86 4:8 codeOffset: 81 + 50 + containerName: A className: A parameters: (Map<Map<T2, U2>, Map<U1, T>> a) ''', @@ -1351,11 +1377,13 @@ CONSTRUCTOR bar offset: 18 2:7 codeOffset: 14 + 26 + containerName: Foo className: Foo parameters: () METHOD bar offset: 48 5:8 codeOffset: 43 + 24 + containerName: Foo className: Foo parameters: () ''', @@ -11147,6 +11175,11 @@ '${declaration.codeLength}', ); + var containerName = declaration.containerName; + if (containerName != null) { + buffer.writeln(' containerName: $containerName'); + } + var className = declaration.className; if (className != null) { buffer.writeln(' className: $className');
diff --git a/tools/VERSION b/tools/VERSION index cd4b230..b5f2339 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 3 MINOR 15 PATCH 0 -PRERELEASE 144 +PRERELEASE 145 PRERELEASE_PATCH 0