Skip to content

Commit e4aad3f

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Issue 2694. Include pubspec.yaml content into the resolution salt.
Bug: https://github.com/dart-lang/linter/issues/2694 Change-Id: I239863703c70c6bd810be6847606e5fc6695073a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202265 Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 1b4d7ec commit e4aad3f

File tree

5 files changed

+137
-1
lines changed

5 files changed

+137
-1
lines changed

pkg/analyzer/lib/src/dart/analysis/driver.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import 'package:analyzer/src/summary/idl.dart';
4343
import 'package:analyzer/src/summary/package_bundle_reader.dart';
4444
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
4545
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
46+
import 'package:analyzer/src/workspace/pub.dart';
4647
import 'package:meta/meta.dart';
4748

4849
/// This class computes [AnalysisResult]s for Dart files.
@@ -141,6 +142,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
141142

142143
/// The salt to mix into all hashes used as keys for linked data.
143144
final Uint32List _saltForResolution = Uint32List(3 +
145+
AnalysisOptionsImpl.signatureLength +
144146
AnalysisOptionsImpl.signatureLength +
145147
_declaredVariablesSignatureLength);
146148

@@ -1899,6 +1901,25 @@ class AnalysisDriver implements AnalysisDriverGeneric {
18991901
_saltForResolution[index] = enableDebugResolutionMarkers ? 1 : 0;
19001902
index++;
19011903

1904+
// TODO(scheglov) Just combine everything into one signature.
1905+
{
1906+
var buffer = ApiSignature();
1907+
1908+
var workspace = analysisContext?.contextRoot.workspace;
1909+
// TODO(scheglov) Generalize?
1910+
if (workspace is PubWorkspace) {
1911+
buffer.addString(workspace.pubspecContent ?? '');
1912+
}
1913+
1914+
var bytes = buffer.toByteList();
1915+
_saltForResolution.setAll(
1916+
index,
1917+
// TODO(scheglov) Add a special method to ApiSignature?
1918+
Uint8List.fromList(bytes).buffer.asUint32List(),
1919+
);
1920+
index += AnalysisOptionsImpl.signatureLength;
1921+
}
1922+
19021923
_saltForResolution.setAll(index, _analysisOptions.signature);
19031924
index += AnalysisOptionsImpl.signatureLength;
19041925

pkg/analyzer/lib/src/workspace/package_build.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ class PackageBuildWorkspace extends Workspace implements PubWorkspace {
190190
UriResolver get packageUriResolver => PackageBuildPackageUriResolver(
191191
this, PackageMapUriResolver(provider, packageMap));
192192

193+
@override
194+
String? get pubspecContent {
195+
try {
196+
return _pubspecFile.readAsStringSync();
197+
} catch (_) {}
198+
}
199+
193200
/// For some package file, which may or may not be a package source (it could
194201
/// be in `bin/`, `web/`, etc), find where its built counterpart will exist if
195202
/// its a generated source.

pkg/analyzer/lib/src/workspace/pub.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ class PubWorkspace extends SimpleWorkspace {
3131
_theOnlyPackage = PubWorkspacePackage(root, this);
3232
}
3333

34+
/// Return the content of the pubspec file, `null` if cannot be read.
35+
String? get pubspecContent {
36+
try {
37+
return _pubspecFile.readAsStringSync();
38+
} catch (_) {}
39+
}
40+
3441
@override
3542
WorkspacePackage? findPackageFor(String filePath) {
3643
final Folder folder = provider.getFolder(filePath);

pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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+
import 'package:analyzer/dart/analysis/results.dart';
56
import 'package:analyzer/error/error.dart';
67
import 'package:analyzer/src/dart/error/lint_codes.dart';
78
import 'package:test/test.dart';
@@ -144,6 +145,66 @@ void f() {
144145
_assertNoLinkedCycles();
145146
}
146147

148+
test_lint_dependOnReferencedPackage_update_pubspec_addDependency() async {
149+
useEmptyByteStore();
150+
151+
var aaaPackageRootPath = '$packagesRootPath/aaa';
152+
newFile('$aaaPackageRootPath/lib/a.dart', content: '');
153+
154+
writeTestPackageConfig(
155+
PackageConfigFileBuilder()
156+
..add(name: 'aaa', rootPath: aaaPackageRootPath),
157+
);
158+
159+
// Configure with the lint.
160+
writeTestPackageAnalysisOptionsFile(
161+
AnalysisOptionsFileConfig(lints: ['depend_on_referenced_packages']),
162+
);
163+
164+
// Configure without dependencies, but with a (required) name.
165+
// So, the lint rule will be activated.
166+
writeTestPackagePubspecYamlFile(
167+
PubspecYamlFileConfig(
168+
name: 'my_test',
169+
dependencies: [],
170+
),
171+
);
172+
173+
newFile(testFilePath, content: r'''
174+
// ignore:unused_import
175+
import 'package:aaa/a.dart';
176+
''');
177+
178+
// We don't have a dependency on `package:aaa`, so there is a lint.
179+
_assertHasLintReported(
180+
await _computeTestFileErrors(),
181+
'depend_on_referenced_packages',
182+
);
183+
184+
// The summary for the library was linked.
185+
_assertContainsLinkedCycle({testFilePath}, andClear: true);
186+
187+
// We will recreate it with new pubspec.yaml content.
188+
// But we will reuse the byte store, so can reuse summaries.
189+
disposeAnalysisContextCollection();
190+
191+
// Add dependency on `package:aaa`.
192+
writeTestPackagePubspecYamlFile(
193+
PubspecYamlFileConfig(
194+
name: 'my_test',
195+
dependencies: [
196+
PubspecYamlFileDependency(name: 'aaa'),
197+
],
198+
),
199+
);
200+
201+
// With dependency on `package:aaa` added, no lint is reported.
202+
expect(await _computeTestFileErrors(), isEmpty);
203+
204+
// Lints don't affect summaries, nothing should be linked.
205+
_assertNoLinkedCycles();
206+
}
207+
147208
test_lints() async {
148209
useEmptyByteStore();
149210

@@ -204,4 +265,17 @@ void f() {
204265
void _assertNoLinkedCycles() {
205266
expect(_linkedCycles, isEmpty);
206267
}
268+
269+
/// Note that we intentionally use this method, we don't want to use
270+
/// [resolveFile] instead. Resolving a file will force to produce its
271+
/// resolved AST, and as a result to recompute the errors.
272+
///
273+
/// But this method is used to check returning errors from the cache, or
274+
/// recomputing when the cache key is expected to be different.
275+
Future<List<AnalysisError>> _computeTestFileErrors() async {
276+
var errorsResult = await contextFor(testFilePath)
277+
.currentSession
278+
.getErrors2(testFilePath) as ErrorsResult;
279+
return errorsResult.errors;
280+
}
207281
}

pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,22 +347,49 @@ class PubPackageResolutionTest extends ContextResolutionTest {
347347
}
348348

349349
class PubspecYamlFileConfig {
350+
final String? name;
350351
final String? sdkVersion;
352+
final List<PubspecYamlFileDependency> dependencies;
351353

352-
PubspecYamlFileConfig({this.sdkVersion});
354+
PubspecYamlFileConfig({
355+
this.name,
356+
this.sdkVersion,
357+
this.dependencies = const [],
358+
});
353359

354360
String toContent() {
355361
var buffer = StringBuffer();
356362

363+
if (name != null) {
364+
buffer.writeln('name: $name');
365+
}
366+
357367
if (sdkVersion != null) {
358368
buffer.writeln('environment:');
359369
buffer.writeln(" sdk: '$sdkVersion'");
360370
}
361371

372+
if (dependencies.isNotEmpty) {
373+
buffer.writeln('dependencies:');
374+
for (var dependency in dependencies) {
375+
buffer.writeln(' ${dependency.name}: ${dependency.version}');
376+
}
377+
}
378+
362379
return buffer.toString();
363380
}
364381
}
365382

383+
class PubspecYamlFileDependency {
384+
final String name;
385+
final String version;
386+
387+
PubspecYamlFileDependency({
388+
required this.name,
389+
this.version = 'any',
390+
});
391+
}
392+
366393
mixin WithNoImplicitCastsMixin on PubPackageResolutionTest {
367394
Future<void> assertErrorsWithNoImplicitCasts(
368395
String code,

0 commit comments

Comments
 (0)