Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 6397e8b

Browse files
author
Dart CI
committed
Version 2.14.0-66.0.dev
Merge commit '9d015feeaf5617205dc431568c024fed7eec23d9' into 'dev'
2 parents d2b48a3 + 9d015fe commit 6397e8b

File tree

12 files changed

+592
-13
lines changed

12 files changed

+592
-13
lines changed

.dart_tool/package_config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"constraint, update this by running tools/generate_package_config.dart."
1212
],
1313
"configVersion": 2,
14-
"generated": "2021-04-29T10:51:01.320402",
14+
"generated": "2021-04-29T17:48:25.665083",
1515
"generator": "tools/generate_package_config.dart",
1616
"packages": [
1717
{

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ vars = {
7373

7474
# Revisions of /third_party/* dependencies.
7575
"args_rev": "d8fea36c10ef96797be02e3d132d572445cd86f4",
76-
"async_rev": "06774f59a7cf9780e08148298d438c1043e2b063",
76+
"async_rev": "cde00b89bd3c19e877b21de2c02282d4d311d0a5",
7777
"bazel_worker_rev": "0885637b037979afbf5bcd05fd748b309fd669c0",
7878
"benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
7979
"boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",

pkg/analysis_server/bin/server.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// @dart = 2.9
6+
57
import 'package:analysis_server/starter.dart';
68

79
/// Create and run an analysis server.

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,13 @@ abstract class CustomSemanticTokenModifiers {
104104
/// - parameter
105105
static const label = SemanticTokenModifiers('label');
106106

107+
/// A modifier applied to constructors to allow colouring them differently
108+
/// to class names that are not constructors.
109+
static const constructor = SemanticTokenModifiers('constructor');
110+
107111
/// All custom semantic token modifiers, used to populate the LSP Legend which must
108112
/// include all used modifiers.
109-
static const values = [control, label];
113+
static const values = [control, label, constructor];
110114
}
111115

112116
abstract class CustomSemanticTokenTypes {

pkg/analysis_server/lib/src/lsp/semantic_tokens/mapping.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ final highlightRegionTokenModifiers =
1515
HighlightRegionType.COMMENT_DOCUMENTATION: {
1616
SemanticTokenModifiers.documentation
1717
},
18+
HighlightRegionType.CONSTRUCTOR: {CustomSemanticTokenModifiers.constructor},
1819
HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION: {
1920
SemanticTokenModifiers.declaration
2021
},

pkg/analysis_server/test/lsp/semantic_tokens_test.dart

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,46 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
8282
expect(decoded, equals(expected));
8383
}
8484

85+
Future<void> test_class_constructors() async {
86+
final content = '''
87+
class MyClass {
88+
MyClass();
89+
MyClass.named();
90+
}
91+
92+
final a = MyClass();
93+
final b = MyClass.named();
94+
''';
95+
96+
final expected = [
97+
_Token('class', SemanticTokenTypes.keyword),
98+
_Token('MyClass', SemanticTokenTypes.class_),
99+
_Token('MyClass', SemanticTokenTypes.class_),
100+
_Token('MyClass', SemanticTokenTypes.class_),
101+
_Token('named', SemanticTokenTypes.class_,
102+
[CustomSemanticTokenModifiers.constructor]),
103+
_Token('final', SemanticTokenTypes.keyword),
104+
_Token('a', SemanticTokenTypes.variable,
105+
[SemanticTokenModifiers.declaration]),
106+
_Token('MyClass', SemanticTokenTypes.class_,
107+
[CustomSemanticTokenModifiers.constructor]),
108+
_Token('final', SemanticTokenTypes.keyword),
109+
_Token('b', SemanticTokenTypes.variable,
110+
[SemanticTokenModifiers.declaration]),
111+
_Token('MyClass', SemanticTokenTypes.class_,
112+
[CustomSemanticTokenModifiers.constructor]),
113+
_Token('named', SemanticTokenTypes.class_,
114+
[CustomSemanticTokenModifiers.constructor])
115+
];
116+
117+
await initialize();
118+
await openFile(mainFileUri, withoutMarkers(content));
119+
120+
final tokens = await getSemanticTokens(mainFileUri);
121+
final decoded = decodeSemanticTokens(content, tokens);
122+
expect(decoded, equals(expected));
123+
}
124+
85125
Future<void> test_class_fields() async {
86126
final content = '''
87127
class MyClass {
@@ -119,7 +159,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
119159
_Token('final', SemanticTokenTypes.keyword),
120160
_Token('a', SemanticTokenTypes.variable,
121161
[SemanticTokenModifiers.declaration]),
122-
_Token('MyClass', SemanticTokenTypes.class_),
162+
_Token('MyClass', SemanticTokenTypes.class_,
163+
[CustomSemanticTokenModifiers.constructor]),
123164
_Token('print', SemanticTokenTypes.function),
124165
_Token('a', SemanticTokenTypes.variable),
125166
_Token('myField', SemanticTokenTypes.property),
@@ -197,7 +238,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
197238
_Token('final', SemanticTokenTypes.keyword),
198239
_Token('a', SemanticTokenTypes.variable,
199240
[SemanticTokenModifiers.declaration]),
200-
_Token('MyClass', SemanticTokenTypes.class_),
241+
_Token('MyClass', SemanticTokenTypes.class_,
242+
[CustomSemanticTokenModifiers.constructor]),
201243
_Token('print', SemanticTokenTypes.function),
202244
_Token('a', SemanticTokenTypes.variable),
203245
_Token('myGetter', SemanticTokenTypes.property),
@@ -255,7 +297,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
255297
_Token('final', SemanticTokenTypes.keyword),
256298
_Token('a', SemanticTokenTypes.variable,
257299
[SemanticTokenModifiers.declaration]),
258-
_Token('MyClass', SemanticTokenTypes.class_),
300+
_Token('MyClass', SemanticTokenTypes.class_,
301+
[CustomSemanticTokenModifiers.constructor]),
259302
_Token('a', SemanticTokenTypes.variable),
260303
_Token('myMethod', SemanticTokenTypes.method),
261304
_Token('MyClass', SemanticTokenTypes.class_),
@@ -443,7 +486,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
443486
_Token('a', SemanticTokenTypes.variable,
444487
[SemanticTokenModifiers.declaration]),
445488
_Token('new', SemanticTokenTypes.keyword),
446-
_Token('Object', SemanticTokenTypes.class_),
489+
_Token('Object', SemanticTokenTypes.class_,
490+
[CustomSemanticTokenModifiers.constructor]),
447491
_Token('await', SemanticTokenTypes.keyword,
448492
[CustomSemanticTokenModifiers.control]),
449493
_Token('null', SemanticTokenTypes.keyword),

pkg/analyzer/lib/src/dart/micro/library_graph.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ class FileSystemState {
518518
/// to batch file reads in systems where file fetches are expensive.
519519
final void Function(List<String> paths)? prefetchFiles;
520520

521+
/// A function that returns true if the given file path is likely to be that
522+
/// of a file that is generated.
523+
final bool Function(String path)? isGenerated;
524+
521525
final FileSystemStateTimers timers2 = FileSystemStateTimers();
522526

523527
final FileSystemStateTestView testView = FileSystemStateTestView();
@@ -533,6 +537,7 @@ class FileSystemState {
533537
this.featureSetProvider,
534538
this.getFileDigest,
535539
this.prefetchFiles,
540+
this.isGenerated,
536541
);
537542

538543
/// Update the state to reflect the fact that the file with the given [path]
@@ -662,6 +667,19 @@ class FileSystemState {
662667
return file;
663668
}
664669

670+
/// Returns a list of files whose contents contains the given string.
671+
/// Generated files are not included in the search.
672+
List<String> getFilesContaining(String value) {
673+
var result = <String>[];
674+
_pathToFile.forEach((path, file) {
675+
var genFile = isGenerated == null ? false : isGenerated!(path);
676+
if (!genFile && file.getContent().contains(value)) {
677+
result.add(path);
678+
}
679+
});
680+
return result;
681+
}
682+
665683
String? getPathForUri(Uri uri) {
666684
var source = _sourceFactory.forUri2(uri);
667685
if (source == null) {

pkg/analyzer/lib/src/dart/micro/resolve_file.dart

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ import 'package:analyzer/src/dart/analysis/experiments.dart';
1818
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
1919
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
2020
import 'package:analyzer/src/dart/analysis/results.dart';
21+
import 'package:analyzer/src/dart/ast/utilities.dart';
2122
import 'package:analyzer/src/dart/micro/analysis_context.dart';
2223
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
2324
import 'package:analyzer/src/dart/micro/library_analyzer.dart';
2425
import 'package:analyzer/src/dart/micro/library_graph.dart';
26+
import 'package:analyzer/src/dart/micro/utils.dart';
2527
import 'package:analyzer/src/exception/exception.dart';
2628
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
2729
import 'package:analyzer/src/generated/source.dart';
@@ -36,11 +38,25 @@ import 'package:analyzer/src/task/options.dart';
3638
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
3739
import 'package:analyzer/src/util/performance/operation_performance.dart';
3840
import 'package:analyzer/src/workspace/workspace.dart';
41+
import 'package:collection/collection.dart';
3942
import 'package:yaml/yaml.dart';
4043

4144
const M = 1024 * 1024 /*1 MiB*/;
4245
const memoryCacheSize = 200 * M;
4346

47+
class CiderSearchMatch {
48+
final String path;
49+
final List<int> offsets;
50+
51+
CiderSearchMatch(this.path, this.offsets);
52+
53+
@override
54+
bool operator ==(Object object) =>
55+
object is CiderSearchMatch &&
56+
path == object.path &&
57+
const ListEquality<int>().equals(offsets, object.offsets);
58+
}
59+
4460
class FileContext {
4561
final AnalysisOptionsImpl analysisOptions;
4662
final FileState file;
@@ -54,13 +70,15 @@ class FileResolver {
5470
CiderByteStore byteStore;
5571
final SourceFactory sourceFactory;
5672

57-
/*
58-
* A function that returns the digest for a file as a String. The function
59-
* returns a non null value, can return an empty string if file does
60-
* not exist/has no contents.
61-
*/
73+
/// A function that returns the digest for a file as a String. The function
74+
/// returns a non null value, can return an empty string if file does
75+
/// not exist/has no contents.
6276
final String Function(String path) getFileDigest;
6377

78+
/// A function that returns true if the given file path is likely to be that
79+
/// of a file that is generated.
80+
final bool Function(String path)? isGenerated;
81+
6482
/// A function that fetches the given list of files. This function can be used
6583
/// to batch file reads in systems where file fetches are expensive.
6684
final void Function(List<String> paths)? prefetchFiles;
@@ -96,6 +114,7 @@ class FileResolver {
96114
String Function(String path) getFileDigest,
97115
void Function(List<String> paths)? prefetchFiles, {
98116
required Workspace workspace,
117+
bool Function(String path)? isGenerated,
99118
@deprecated Duration? libraryContextResetTimeout,
100119
}) : this.from(
101120
logger: logger,
@@ -104,6 +123,8 @@ class FileResolver {
104123
getFileDigest: getFileDigest,
105124
prefetchFiles: prefetchFiles,
106125
workspace: workspace,
126+
isGenerated: isGenerated,
127+
107128
// ignore: deprecated_member_use_from_same_package
108129
libraryContextResetTimeout: libraryContextResetTimeout,
109130
);
@@ -115,6 +136,7 @@ class FileResolver {
115136
required String Function(String path) getFileDigest,
116137
required void Function(List<String> paths)? prefetchFiles,
117138
required Workspace workspace,
139+
bool Function(String path)? isGenerated,
118140
CiderByteStore? byteStore,
119141
@deprecated Duration? libraryContextResetTimeout,
120142
}) : logger = logger,
@@ -123,6 +145,7 @@ class FileResolver {
123145
getFileDigest = getFileDigest,
124146
prefetchFiles = prefetchFiles,
125147
workspace = workspace,
148+
isGenerated = isGenerated,
126149
byteStore = byteStore ?? CiderCachedByteStore(memoryCacheSize);
127150

128151
/// Update the resolver to reflect the fact that the file with the given
@@ -164,6 +187,31 @@ class FileResolver {
164187
@deprecated
165188
void dispose() {}
166189

190+
/// Looks for references to the Element at the given offset and path. All the
191+
/// files currently cached by the resolver are searched, generated files are
192+
/// ignored.
193+
List<CiderSearchMatch> findReferences(int offset, String path,
194+
{OperationPerformanceImpl? performance}) {
195+
var references = <CiderSearchMatch>[];
196+
var unit = resolve(path: path);
197+
var node = NodeLocator(offset).searchWithin(unit.unit);
198+
var element = getElementOfNode(node);
199+
if (element != null) {
200+
// TODO(keertip): check if element is named constructor.
201+
var result = fsState!.getFilesContaining(element.displayName);
202+
result.forEach((filePath) {
203+
var resolved = resolve(path: filePath);
204+
var collector = ReferencesCollector(element);
205+
resolved.unit?.accept(collector);
206+
var offsets = collector.offsets;
207+
if (offsets.isNotEmpty) {
208+
references.add(CiderSearchMatch(filePath, offsets));
209+
}
210+
});
211+
}
212+
return references;
213+
}
214+
167215
ErrorsResult getErrors({
168216
required String path,
169217
OperationPerformanceImpl? performance,
@@ -555,6 +603,7 @@ class FileResolver {
555603
featureSetProvider,
556604
getFileDigest,
557605
prefetchFiles,
606+
isGenerated,
558607
);
559608
}
560609

0 commit comments

Comments
 (0)