Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

Commit ec223c7

Browse files
authored
feat: migrate to new plugins api (#1020)
* feat: migrate to new plugins api * chore: fix analyzer * build: update min sdk version * build: update analyzer version * chore: remove unsued analyzer ignores
1 parent e209a2d commit ec223c7

File tree

53 files changed

+323
-450
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+323
-450
lines changed

.github/workflows/package_analyze.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@ jobs:
130130
runs-on: ubuntu-latest
131131

132132
steps:
133-
- name: Install Dart 2.17.1
133+
- name: Install Dart 2.18.0
134134
uses: dart-lang/setup-dart@v1
135135
with:
136-
sdk: "2.17.1"
136+
sdk: "2.18.0"
137137

138138
- name: Checkout
139139
uses: actions/checkout@v3

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
## Unreleased
44

55
* feat: add logger and progress indication.
6-
* chore: changed min `SDK` version to `2.17.1`.
6+
* chore: changed min `SDK` version to `2.18.0`.
7+
* chore: restrict `analyzer` version to `>=5.1.0 <5.2.0`.
8+
* chore: restrict `analyzer_plugin` version to `>=0.11.0 <0.12.0`.
79

810
## 4.19.1
911

Lines changed: 76 additions & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
// ignore_for_file: public_member_api_docs
2-
32
import 'dart:async';
43

5-
import 'package:analyzer/dart/analysis/context_locator.dart';
4+
import 'package:analyzer/dart/analysis/analysis_context.dart';
5+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
66
import 'package:analyzer/dart/analysis/results.dart';
7-
import 'package:analyzer/file_system/physical_file_system.dart';
8-
// ignore: implementation_imports
9-
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
10-
// ignore: implementation_imports
11-
import 'package:analyzer/src/dart/analysis/context_builder.dart';
12-
// ignore: implementation_imports
13-
import 'package:analyzer/src/dart/analysis/driver.dart';
147
import 'package:analyzer_plugin/plugin/plugin.dart';
158
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
169

@@ -20,18 +13,14 @@ import '../analyzers/lint_analyzer/metrics/metrics_list/number_of_parameters_met
2013
import '../analyzers/lint_analyzer/metrics/metrics_list/source_lines_of_code/source_lines_of_code_metric.dart';
2114
import '../config_builder/config_builder.dart';
2215
import '../config_builder/models/analysis_options.dart';
23-
import '../utils/analyzer_utils.dart';
24-
import '../utils/yaml_utils.dart';
2516
import 'analyzer_plugin_utils.dart';
2617

27-
final _byteStore = createByteStore(PhysicalResourceProvider.INSTANCE);
28-
2918
class AnalyzerPlugin extends ServerPlugin {
3019
static const _analyzer = LintAnalyzer();
3120

32-
final _configs = <AnalysisDriverGeneric, LintAnalysisConfig>{};
21+
final _configs = <String, LintAnalysisConfig>{};
3322

34-
var _filesFromSetPriorityFilesRequest = <String>[];
23+
AnalysisContextCollection? _contextCollection;
3524

3625
@override
3726
String get contactInfo =>
@@ -46,172 +35,101 @@ class AnalyzerPlugin extends ServerPlugin {
4635
@override
4736
String get version => '1.0.0-alpha.0';
4837

49-
AnalyzerPlugin(super.resourceProvider);
50-
51-
@override
52-
void contentChanged(String path) {
53-
super.driverForPath(path)?.addFile(path);
54-
}
55-
56-
@override
57-
AnalysisDriverGeneric createAnalysisDriver(plugin.ContextRoot contextRoot) {
58-
final rootPath = contextRoot.root;
59-
final locator =
60-
ContextLocator(resourceProvider: resourceProvider).locateRoots(
61-
includedPaths: [rootPath],
62-
excludedPaths: contextRoot.exclude,
63-
optionsFile: contextRoot.optionsFile,
64-
);
65-
66-
if (locator.isEmpty) {
67-
final error = StateError('Unexpected empty context');
68-
channel.sendNotification(plugin.PluginErrorParams(
69-
true,
70-
error.message,
71-
error.stackTrace.toString(),
72-
).toNotification());
73-
74-
throw error;
75-
}
76-
77-
final builder = ContextBuilderImpl(resourceProvider: resourceProvider);
78-
final context = builder.createContext(
79-
contextRoot: locator.first,
80-
byteStore: _byteStore,
81-
);
82-
final dartDriver = context.driver;
83-
final config = _createConfig(dartDriver, rootPath);
84-
85-
if (config == null) {
86-
return dartDriver;
87-
}
88-
89-
// Temporary disable deprecation check
90-
//
91-
// final deprecations = checkConfigDeprecatedOptions(
92-
// config,
93-
// deprecatedOptions,
94-
// contextRoot.optionsFile!,
95-
// );
96-
// if (deprecations.isNotEmpty) {
97-
// channel.sendNotification(plugin.AnalysisErrorsParams(
98-
// contextRoot.optionsFile!,
99-
// deprecations.map((deprecation) => deprecation.error).toList(),
100-
// ).toNotification());
101-
// }
102-
103-
runZonedGuarded(
104-
() {
105-
dartDriver.results.listen((analysisResult) {
106-
if (analysisResult is ResolvedUnitResult) {
107-
_processResult(dartDriver, analysisResult);
108-
}
109-
});
110-
},
111-
(e, stackTrace) {
112-
channel.sendNotification(
113-
plugin.PluginErrorParams(false, e.toString(), stackTrace.toString())
114-
.toNotification(),
115-
);
116-
},
117-
);
118-
119-
return dartDriver;
120-
}
38+
AnalyzerPlugin({
39+
required super.resourceProvider,
40+
});
12141

12242
@override
123-
Future<plugin.AnalysisSetContextRootsResult> handleAnalysisSetContextRoots(
124-
plugin.AnalysisSetContextRootsParams parameters,
125-
) async {
126-
final result = await super.handleAnalysisSetContextRoots(parameters);
127-
// The super-call adds files to the driver, so we need to prioritize them so they get analyzed.
128-
_updatePriorityFiles();
43+
Future<void> afterNewContextCollection({
44+
required AnalysisContextCollection contextCollection,
45+
}) {
46+
_contextCollection = contextCollection;
12947

130-
return result;
131-
}
48+
contextCollection.contexts.forEach(_createConfig);
13249

133-
@override
134-
Future<plugin.AnalysisSetPriorityFilesResult> handleAnalysisSetPriorityFiles(
135-
plugin.AnalysisSetPriorityFilesParams parameters,
136-
) async {
137-
_filesFromSetPriorityFilesRequest = parameters.files;
138-
_updatePriorityFiles();
139-
140-
return plugin.AnalysisSetPriorityFilesResult();
50+
return super
51+
.afterNewContextCollection(contextCollection: contextCollection);
14152
}
14253

14354
@override
144-
Future<plugin.EditGetFixesResult> handleEditGetFixes(
145-
plugin.EditGetFixesParams parameters,
146-
) async {
55+
Future<void> analyzeFile({
56+
required AnalysisContext analysisContext,
57+
required String path,
58+
}) async {
14759
try {
148-
final driver = driverForPath(parameters.file) as AnalysisDriver;
149-
// ignore: deprecated_member_use
150-
final analysisResult = await driver.getResult2(parameters.file);
151-
152-
if (analysisResult is! ResolvedUnitResult) {
153-
return plugin.EditGetFixesResult([]);
154-
}
60+
final resolvedUnit =
61+
await analysisContext.currentSession.getResolvedUnit(path);
15562

156-
final fixes = _check(driver, analysisResult).where((fix) {
157-
final location = fix.error.location;
158-
159-
return location.file == parameters.file &&
160-
location.offset <= parameters.offset &&
161-
parameters.offset <= location.offset + location.length &&
162-
fix.fixes.isNotEmpty;
163-
}).toList();
63+
if (resolvedUnit is ResolvedUnitResult) {
64+
final analysisErrors = _getErrorsForResolvedUnit(
65+
resolvedUnit,
66+
analysisContext.contextRoot.root.path,
67+
);
16468

165-
return plugin.EditGetFixesResult(fixes);
69+
channel.sendNotification(
70+
plugin.AnalysisErrorsParams(
71+
path,
72+
analysisErrors.map((analysisError) => analysisError.error).toList(),
73+
).toNotification(),
74+
);
75+
} else {
76+
channel.sendNotification(
77+
plugin.AnalysisErrorsParams(path, []).toNotification(),
78+
);
79+
}
16680
} on Exception catch (e, stackTrace) {
16781
channel.sendNotification(
16882
plugin.PluginErrorParams(false, e.toString(), stackTrace.toString())
16983
.toNotification(),
17084
);
171-
172-
return plugin.EditGetFixesResult([]);
17385
}
17486
}
17587

176-
void _processResult(
177-
AnalysisDriver driver,
178-
ResolvedUnitResult analysisResult,
179-
) {
88+
@override
89+
Future<plugin.EditGetFixesResult> handleEditGetFixes(
90+
plugin.EditGetFixesParams parameters,
91+
) async {
18092
try {
181-
if (driver.analysisContext?.contextRoot.isAnalyzed(analysisResult.path) ??
182-
false) {
183-
final fixes = _check(driver, analysisResult);
184-
185-
channel.sendNotification(
186-
plugin.AnalysisErrorsParams(
187-
analysisResult.path,
188-
fixes.map((fix) => fix.error).toList(),
189-
).toNotification(),
190-
);
191-
} else {
192-
channel.sendNotification(
193-
plugin.AnalysisErrorsParams(analysisResult.path, []).toNotification(),
194-
);
93+
final path = parameters.file;
94+
final analysisContext = _contextCollection?.contextFor(path);
95+
final resolvedUnit =
96+
await analysisContext?.currentSession.getResolvedUnit(path);
97+
98+
if (analysisContext != null && resolvedUnit is ResolvedUnitResult) {
99+
final analysisErrors = _getErrorsForResolvedUnit(
100+
resolvedUnit,
101+
analysisContext.contextRoot.root.path,
102+
).where((analysisError) {
103+
final location = analysisError.error.location;
104+
105+
return location.file == parameters.file &&
106+
location.offset <= parameters.offset &&
107+
parameters.offset <= location.offset + location.length &&
108+
analysisError.fixes.isNotEmpty;
109+
}).toList();
110+
111+
return plugin.EditGetFixesResult(analysisErrors);
195112
}
196113
} on Exception catch (e, stackTrace) {
197114
channel.sendNotification(
198115
plugin.PluginErrorParams(false, e.toString(), stackTrace.toString())
199116
.toNotification(),
200117
);
201118
}
119+
120+
return plugin.EditGetFixesResult([]);
202121
}
203122

204-
Iterable<plugin.AnalysisErrorFixes> _check(
205-
AnalysisDriver driver,
123+
Iterable<plugin.AnalysisErrorFixes> _getErrorsForResolvedUnit(
206124
ResolvedUnitResult analysisResult,
125+
String rootPath,
207126
) {
208127
final result = <plugin.AnalysisErrorFixes>[];
209-
final config = _configs[driver];
128+
final config = _configs[rootPath];
210129

211130
if (config != null) {
212-
final root = driver.analysisContext?.contextRoot.root.path;
213-
214-
final report = _analyzer.runPluginAnalysis(analysisResult, config, root!);
131+
final report =
132+
_analyzer.runPluginAnalysis(analysisResult, config, rootPath);
215133

216134
if (report != null) {
217135
result.addAll([
@@ -237,69 +155,26 @@ class AnalyzerPlugin extends ServerPlugin {
237155
return result;
238156
}
239157

240-
LintAnalysisConfig? _createConfig(AnalysisDriver driver, String rootPath) {
241-
final file = driver.analysisContext?.contextRoot.optionsFile;
158+
void _createConfig(AnalysisContext analysisContext) {
159+
final rootPath = analysisContext.contextRoot.root.path;
160+
final file = analysisContext.contextRoot.optionsFile;
161+
242162
if (file != null && file.exists) {
243-
final options = AnalysisOptions(
244-
file.path,
245-
yamlMapToDartMap(
246-
AnalysisOptionsProvider(driver.sourceFactory)
247-
.getOptionsFromFile(file),
248-
),
249-
);
250-
final config = ConfigBuilder.getLintConfigFromOptions(options);
163+
final analysisOptions = analysisOptionsFromContext(analysisContext) ??
164+
analysisOptionsFromFilePath(file.parent.path, analysisContext);
165+
final config = ConfigBuilder.getLintConfigFromOptions(analysisOptions);
166+
251167
final lintConfig = ConfigBuilder.getLintAnalysisConfig(
252168
config,
253-
options.folderPath ?? rootPath,
169+
analysisOptions.folderPath ?? rootPath,
254170
classMetrics: const [],
255171
functionMetrics: [
256172
NumberOfParametersMetric(config: config.metrics),
257173
SourceLinesOfCodeMetric(config: config.metrics),
258174
],
259175
);
260176

261-
_configs[driver] = lintConfig;
262-
263-
return lintConfig;
264-
}
265-
266-
return null;
267-
}
268-
269-
/// AnalysisDriver doesn't fully resolve files that are added via `addFile`; they need to be either explicitly requested
270-
/// via `getResult`/etc, or added to `priorityFiles`.
271-
///
272-
/// This method updates `priorityFiles` on the driver to include:
273-
///
274-
/// - Any files prioritized by the analysis server via [handleAnalysisSetPriorityFiles]
275-
/// - All other files the driver has been told to analyze via addFile (in [ServerPlugin.handleAnalysisSetContextRoots])
276-
///
277-
/// As a result, [_processResult] will get called with resolved units, and thus all of our diagnostics
278-
/// will get run on all files in the repo instead of only the currently open/edited ones!
279-
void _updatePriorityFiles() {
280-
final filesToFullyResolve = {
281-
// Ensure these go first, since they're actually considered priority; ...
282-
..._filesFromSetPriorityFilesRequest,
283-
284-
// ... all other files need to be analyzed, but don't trump priority
285-
for (final driver2 in driverMap.values)
286-
...(driver2 as AnalysisDriver).addedFiles,
287-
};
288-
289-
// From ServerPlugin.handleAnalysisSetPriorityFiles.
290-
final filesByDriver = <AnalysisDriverGeneric, List<String>>{};
291-
for (final file in filesToFullyResolve) {
292-
final contextRoot = contextRootContaining(file);
293-
if (contextRoot != null) {
294-
// TODO(dkrutskikh): Which driver should we use if there is no context root?
295-
final driver = driverMap[contextRoot];
296-
if (driver != null) {
297-
filesByDriver.putIfAbsent(driver, () => <String>[]).add(file);
298-
}
299-
}
177+
_configs[rootPath] = lintConfig;
300178
}
301-
filesByDriver.forEach((driver, files) {
302-
driver.priorityFiles = files;
303-
});
304179
}
305180
}

lib/src/analyzer_plugin/analyzer_plugin_starter.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:analyzer_plugin/starter.dart';
66
import 'analyzer_plugin.dart';
77

88
void start(Iterable<String> _, SendPort sendPort) {
9-
ServerPluginStarter(AnalyzerPlugin(PhysicalResourceProvider.INSTANCE))
10-
.start(sendPort);
9+
ServerPluginStarter(
10+
AnalyzerPlugin(resourceProvider: PhysicalResourceProvider.INSTANCE),
11+
).start(sendPort);
1112
}

0 commit comments

Comments
 (0)