Revert "Refactor PubWorkspace into PackageConfigWorkspace"

This reverts commit 43fb59f4dc.

Reason for revert: Breaking Dart SDK -> Flutter Engine roller. See https://github.com/flutter/flutter/issues/142253

Original change's description:
> Refactor PubWorkspace into PackageConfigWorkspace
>
>  - use package_config.json as marker file for workspace.
>  - workspace can have multiple packages, they can be either PubPackages (marker pubspec.yaml) or BasicWorkspace.
>  - add package info (pubspec) to resolution salt.
>  - removed duplication of finding package_config.json from ContextLocator, as this is now done while creating workspace.
>  - some test/s setup/expectations were changed since we now use package config as marker for workspace instead of pubspec.
>
> Change-Id: I091a4a686c6b1d8c14858aefd9843a8d9c8efa25
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345346
> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
> Commit-Queue: Keerti Parthasarathy <keertip@google.com>
> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>

Change-Id: I59adf5b26d25e360bcf962323db688156774c767
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/348364
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Jackson Gardner <jacksongardner@google.com>
This commit is contained in:
Jackson Gardner 2024-01-25 21:00:47 +00:00 committed by Commit Queue
parent 14c0f42118
commit e9590179fe
27 changed files with 830 additions and 896 deletions

View file

@ -373,8 +373,9 @@ class ContextManagerImpl implements ContextManager {
var analysisOptions = driver.getAnalysisOptionsForFile(file);
var content = file.readAsStringSync();
var lineInfo = LineInfo.fromContent(content);
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
var sdkVersionConstraint = (package is PubWorkspacePackage)
? package.sdkVersionConstraint
: null;
var errors = analyzeAnalysisOptions(
file.createSource(),
content,

View file

@ -111,7 +111,7 @@ class EditGetFixesHandler extends LegacyHandler
var package =
analysisContext.contextRoot.workspace.findPackageFor(optionsFile.path);
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
(package is PubWorkspacePackage) ? package.sdkVersionConstraint : null;
var errors = analyzeAnalysisOptions(
optionsFile.createSource(),
content,

View file

@ -62,7 +62,7 @@ class AnalysisOptionsCodeActionsProducer extends AbstractCodeActionsProducer {
final contextRoot = session.analysisContext.contextRoot;
final package = contextRoot.workspace.findPackageFor(optionsFile.path);
final sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
(package is PubWorkspacePackage) ? package.sdkVersionConstraint : null;
final errors = analyzeAnalysisOptions(
optionsFile.createSource(),

View file

@ -73,9 +73,8 @@ class DartFixPromptManager {
final constraintMap = <String, List<String?>>{};
for (final context in server.contextManager.analysisContexts) {
final workspace = context.contextRoot.workspace;
final sdkConstraints = workspace is PackageConfigWorkspace
? workspace.allPackages
.whereType<PubPackage>()
final sdkConstraints = workspace is PubWorkspace
? workspace.pubPackages
.map((p) => p.sdkVersionConstraint?.toString())
.toList()
: <String>[];

View file

@ -259,7 +259,6 @@ class PubPackageAnalysisServerTest extends ContextResolutionTest {
@override
void createDefaultFiles() {
writeTestPackageConfig();
writeTestPackagePubspecYamlFile('name: test');
writeTestPackageAnalysisOptionsFile(
AnalysisOptionsFileConfig(

View file

@ -111,7 +111,7 @@ class X extends A with M {}
// Subscribe to STATUS so we'll know when analysis is done.
server.serverServices = {ServerService.STATUS};
final projectRoot = convertPath('/foo');
final projectTestFile = convertPath('/foo/lib/test.dart');
final projectTestFile = convertPath('/foo/test.dart');
final projectPackageConfigFile =
convertPath('/foo/.dart_tool/package_config.json');

View file

@ -98,9 +98,6 @@ class AnalysisDomainPubTest extends _AnalysisDomainTest {
// Both a.dart and b.dart are analyzed.
assertNotificationsText(r'''
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -124,13 +121,9 @@ analyzer:
AnalysisFlush
/home/test/lib/a.dart
/home/test/lib/b.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -148,9 +141,6 @@ AnalysisErrors
// a.dart was analyzed
assertNotificationsText(r'''
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -168,13 +158,9 @@ analyzer:
assertNotificationsText(r'''
AnalysisFlush
/home/test/lib/a.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -196,9 +182,6 @@ analyzer:
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -232,9 +215,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
_createFilesWithErrors([
@ -268,9 +248,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/b.dart
errors: notEmpty
@ -314,9 +291,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/b.dart
errors: notEmpty
@ -350,9 +324,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -389,9 +360,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -436,9 +404,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: notEmpty
@ -460,13 +425,9 @@ AnalysisErrors
AnalysisFlush
/home/test/analysis_options.yaml
/home/test/lib/test.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: empty
@ -491,9 +452,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -513,7 +471,6 @@ dependencies: true
AnalysisFlush
/home/test/analysis_options.yaml
/home/test/lib/a.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
@ -540,9 +497,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -581,9 +535,6 @@ analyzer:
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -609,13 +560,9 @@ AnalysisFlush
/home/test/analysis_options.yaml
/home/test/lib/a.dart
/home/test/lib/c.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -649,9 +596,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/AndroidManifest.xml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -694,9 +638,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -744,9 +685,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/b.dart
errors: notEmpty
@ -796,9 +734,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/b.dart
errors: notEmpty
@ -837,9 +772,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data/foo.yaml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -885,9 +817,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -932,9 +861,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: empty
@ -986,9 +912,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: notEmpty
@ -1009,13 +932,9 @@ AnalysisErrors
AnalysisFlush
/home/test/analysis_options.yaml
/home/test/lib/test.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: empty
@ -1044,9 +963,6 @@ analyzer:
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1063,10 +979,6 @@ AnalysisErrors
AnalysisFlush
/home/test/analysis_options.yaml
/home/test/lib/a.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1101,9 +1013,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/AndroidManifest.xml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -1138,9 +1047,6 @@ AnalysisFlush
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1212,9 +1118,6 @@ AnalysisFlush
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1260,9 +1163,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/b.dart
errors: empty
@ -1300,9 +1200,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: empty
@ -1346,9 +1243,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: empty
@ -1368,13 +1262,9 @@ AnalysisErrors
AnalysisFlush
/home/test/analysis_options.yaml
/home/test/lib/test.dart
/home/test/pubspec.yaml
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: notEmpty
@ -1398,9 +1288,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1469,9 +1356,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/foo/lib/a.dart
errors: empty
@ -1628,9 +1512,6 @@ AnalysisFlush
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1692,9 +1573,6 @@ analyzer:
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1734,9 +1612,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1785,9 +1660,6 @@ analyzer:
await server.onAnalysisComplete;
assertNotificationsText(r'''
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1817,9 +1689,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/AndroidManifest.xml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1838,9 +1707,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1857,9 +1723,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1876,9 +1739,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1943,9 +1803,6 @@ void f(A a) {}
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: empty
@ -1963,9 +1820,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: notEmpty
@ -2005,9 +1859,6 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/test.dart
errors: notEmpty

View file

@ -35,9 +35,9 @@ class ChangeWorkspaceFoldersTest extends AbstractLspAnalysisServerTest {
workspaceFolder2Uri = pathContext.toUri(workspaceFolder2Path);
workspaceFolder3Uri = pathContext.toUri(workspaceFolder3Path);
newPackageConfigJsonFile(workspaceFolder1Path, '');
newPackageConfigJsonFile(workspaceFolder2Path, '');
newPackageConfigJsonFile(workspaceFolder3Path, '');
newPubspecYamlFile(workspaceFolder1Path, '');
newPubspecYamlFile(workspaceFolder2Path, '');
newPubspecYamlFile(workspaceFolder3Path, '');
nonFileWorkspaceFolderUri = Uri.parse('dart-foo:/foo.dart');
}
@ -261,12 +261,11 @@ class ChangeWorkspaceFoldersTest extends AbstractLspAnalysisServerTest {
final nestedFileUri = pathContext.toUri(nestedFilePath);
newFile(nestedFilePath, '');
// Ensure no package config in tree.
// Ensure no pubspecs in tree.
deleteFile(
join(
workspaceFolder1Path,
file_paths.dotDartTool,
file_paths.packageConfigJson,
file_paths.pubspecYaml,
),
);

View file

@ -57,7 +57,7 @@ class SourceFactoryImpl implements SourceFactory {
if (resolver is PackageMapUriResolver) {
return resolver.packageMap;
}
if (resolver is PackageConfigPackageUriResolver) {
if (resolver is PackageBuildPackageUriResolver) {
return resolver.packageMap;
}
}

View file

@ -193,26 +193,25 @@ class ContextLocatorImpl implements ContextLocator {
Folder? packagesFolderToChooseRoot;
if (defaultPackagesFile != null) {
packagesFile = defaultPackagesFile;
// If the packages file is in .dart_tool directory, use the grandparent
// folder, else use the parent folder.
packagesFolderToChooseRoot =
_findPackagesFile(packagesFile.parent)?.parent ?? packagesFile.parent;
} else {
var foundPackages = _findPackagesFile(parent);
packagesFile = foundPackages?.file;
packagesFolderToChooseRoot = foundPackages?.parent;
}
var buildGnFile = _findBuildGnFile(parent);
var rootFolder = _lowest([
optionsFolderToChooseRoot,
packagesFolderToChooseRoot,
buildGnFile?.parent,
]);
// If default packages file is given, create workspace for it.
var workspace = _createWorkspace(
folder: parent,
packagesFile: packagesFile,
buildGnFile: buildGnFile,
);
if (workspace is! BasicWorkspace) {
rootFolder = _lowest([
rootFolder,
@ -220,17 +219,6 @@ class ContextLocatorImpl implements ContextLocator {
]);
}
if (workspace is PackageConfigWorkspace) {
packagesFile ??= workspace.packageConfigFile;
// If the default packages folder is a parent of the workspace root,
// choose that as the root.
if (rootFolder != null && packagesFolderToChooseRoot != null) {
if (packagesFolderToChooseRoot.contains(rootFolder.path)) {
rootFolder = packagesFolderToChooseRoot;
}
}
}
if (rootFolder == null) {
rootFolder = defaultRootFolder();
if (workspace is BasicWorkspace) {
@ -418,8 +406,8 @@ class ContextLocatorImpl implements ContextLocator {
Workspace? workspace;
workspace = BlazeWorkspace.find(resourceProvider, rootPath,
lookForBuildFileSubstitutes: false);
workspace = _mostSpecificWorkspace(workspace,
PackageConfigWorkspace.find(resourceProvider, packages, rootPath));
workspace = _mostSpecificWorkspace(
workspace, PubWorkspace.find(resourceProvider, packages, rootPath));
workspace ??= BasicWorkspace.find(resourceProvider, packages, rootPath);
return workspace;
}

View file

@ -192,10 +192,10 @@ class ContextLocatorImpl2 implements ContextLocator {
Folder? packagesFolderToChooseRoot;
if (defaultPackagesFile != null) {
packagesFile = defaultPackagesFile;
// If the packages file is in .dart_tool directory, use the grandparent
// folder, else use the parent folder.
packagesFolderToChooseRoot =
_findPackagesFile(packagesFile.parent)?.parent ?? packagesFile.parent;
} else {
var foundPackages = _findPackagesFile(parent);
packagesFile = foundPackages?.file;
packagesFolderToChooseRoot = foundPackages?.parent;
}
var buildGnFile = _findBuildGnFile(parent);
@ -211,7 +211,6 @@ class ContextLocatorImpl2 implements ContextLocator {
packagesFile: packagesFile,
buildGnFile: buildGnFile,
);
if (workspace is! BasicWorkspace) {
rootFolder = _lowest([
rootFolder,
@ -219,17 +218,6 @@ class ContextLocatorImpl2 implements ContextLocator {
]);
}
if (workspace is PackageConfigWorkspace) {
packagesFile ??= workspace.packageConfigFile;
// If the default packages folder is a parent of the workspace root,
// choose that as the root.
if (rootFolder != null && packagesFolderToChooseRoot != null) {
if (packagesFolderToChooseRoot.contains(rootFolder.path)) {
rootFolder = packagesFolderToChooseRoot;
}
}
}
if (rootFolder == null) {
rootFolder = defaultRootFolder();
if (workspace is BasicWorkspace) {
@ -426,8 +414,8 @@ class ContextLocatorImpl2 implements ContextLocator {
Workspace? workspace;
workspace = BlazeWorkspace.find(resourceProvider, rootPath,
lookForBuildFileSubstitutes: false);
workspace = _mostSpecificWorkspace(workspace,
PackageConfigWorkspace.find(resourceProvider, packages, rootPath));
workspace = _mostSpecificWorkspace(
workspace, PubWorkspace.find(resourceProvider, packages, rootPath));
workspace ??= BasicWorkspace.find(resourceProvider, packages, rootPath);
return workspace;
}

View file

@ -56,7 +56,6 @@ import 'package:analyzer/src/utilities/extensions/async.dart';
import 'package:analyzer/src/utilities/extensions/collection.dart';
import 'package:analyzer/src/utilities/extensions/string.dart';
import 'package:analyzer/src/utilities/uri_cache.dart';
import 'package:analyzer/src/workspace/pub.dart';
import 'package:meta/meta.dart';
/// This class computes analysis results for Dart files.
@ -1762,10 +1761,6 @@ class AnalysisDriver {
String _getResolvedUnitSignature(LibraryFileKind library, FileState file) {
ApiSignature signature = ApiSignature();
signature.addUint32List(_saltForResolution);
if (file.workspacePackage is PubPackage) {
signature.addString(
(file.workspacePackage as PubPackage).pubspecContent ?? '');
}
signature.addString(library.file.uriStr);
signature.addString(library.libraryCycle.apiSignature);
signature.addString(file.uriStr);

View file

@ -10,7 +10,7 @@ abstract class FileStateFilter {
/// Return a filter of files that can be accessed by the [file].
factory FileStateFilter(FileState file) {
var workspacePackage = file.workspacePackage;
if (workspacePackage is PubPackage) {
if (workspacePackage is PubWorkspacePackage) {
return _PubFilter(workspacePackage, file.path);
} else {
return _AnyFilter();
@ -57,13 +57,13 @@ class _AnyFilter implements FileStateFilter {
}
class _PubFilter implements FileStateFilter {
final PubPackage targetPackage;
final PubWorkspacePackage targetPackage;
final String? targetPackageName;
final bool targetPackageIsAnalysisServer;
final bool targetInLib;
final Set<String> dependencies;
factory _PubFilter(PubPackage package, String path) {
factory _PubFilter(PubWorkspacePackage package, String path) {
var inLib = package.workspace.provider
.getFolder(package.root)
.getChildAssumingFolder('lib')
@ -112,7 +112,7 @@ class _PubFilter implements FileStateFilter {
return false;
} else {
var filePackage = file.workspacePackage;
return filePackage is PubPackage &&
return filePackage is PubWorkspacePackage &&
filePackage.root == targetPackage.root;
}
}

View file

@ -501,7 +501,7 @@ class LibraryAnalyzer {
//
var package = file.workspacePackage;
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
(package is PubWorkspacePackage) ? package.sdkVersionConstraint : null;
if (sdkVersionConstraint != null) {
SdkConstraintVerifier verifier = SdkConstraintVerifier(
errorReporter,

View file

@ -63,7 +63,7 @@ class BasicWorkspacePackage extends WorkspacePackage {
final String root;
@override
final SimpleWorkspace workspace;
final BasicWorkspace workspace;
BasicWorkspacePackage(this.root, this.workspace);

View file

@ -13,12 +13,12 @@ import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/uri.dart';
import 'package:analyzer/src/utilities/uri_cache.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/simple.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart';
/// Check if the given list of path components contains a package build
/// generated directory, it would have the following path segments,
@ -37,29 +37,26 @@ bool _isPackageBuildGeneratedPath(List<String> pathComponents, int startIndex) {
/// Instances of the class `PackageBuildFileUriResolver` resolve `file` URI's by
/// first resolving file uri's in the expected way, and then by looking in the
/// corresponding generated directories.
class PackageConfigFileUriResolver extends ResourceUriResolver {
final PackageConfigWorkspace workspace;
class PackageBuildFileUriResolver extends ResourceUriResolver {
final PubWorkspace workspace;
PackageConfigFileUriResolver(this.workspace) : super(workspace.provider);
PackageBuildFileUriResolver(this.workspace) : super(workspace.provider);
@override
Uri pathToUri(String path) {
var pathContext = workspace.provider.pathContext;
if (pathContext.isWithin(workspace.root, path)) {
var package = workspace.findPackageFor(path);
if (package is PubPackage) {
var relative = pathContext.relative(path, from: workspace.root);
var components = pathContext.split(relative);
if (components.length > 4 &&
_isPackageBuildGeneratedPath(components, 0) &&
components[3] == package._name) {
var canonicalPath = pathContext.joinAll([
workspace.root,
...components.skip(4),
]);
return pathContext.toUri(canonicalPath);
}
var relative = pathContext.relative(path, from: workspace.root);
var components = pathContext.split(relative);
if (components.length > 4 &&
_isPackageBuildGeneratedPath(components, 0) &&
components[3] == workspace.projectPackageName) {
var canonicalPath = pathContext.joinAll([
workspace.root,
...components.skip(4),
]);
return pathContext.toUri(canonicalPath);
}
}
@ -86,13 +83,13 @@ class PackageConfigFileUriResolver extends ResourceUriResolver {
/// The [UriResolver] that can resolve `package` URIs in
/// [PackageBuildWorkspace].
class PackageConfigPackageUriResolver extends UriResolver {
final PackageConfigWorkspace _workspace;
class PackageBuildPackageUriResolver extends UriResolver {
final PubWorkspace _workspace;
final UriResolver _normalUriResolver;
final Context _context;
PackageConfigPackageUriResolver(
PackageConfigWorkspace workspace, this._normalUriResolver)
PackageBuildPackageUriResolver(
PubWorkspace workspace, this._normalUriResolver)
: _workspace = workspace,
_context = workspace.provider.pathContext;
@ -157,53 +154,118 @@ class PackageConfigPackageUriResolver extends UriResolver {
}
}
/// Information about a Package Config workspace.
class PackageConfigWorkspace extends SimpleWorkspace {
/// The associated package config file.
final File packageConfigFile;
/// Information about a Pub workspace.
class PubWorkspace extends SimpleWorkspace {
/// The name of the directory that identifies the root of the workspace. Note,
/// the presence of this file does not show package:build is used. For that,
/// the subdirectory [_dartToolBuildName] must exist. A `pub` subdirectory
/// will usually exist in non-package:build projects too.
static const String _dartToolRootName = '.dart_tool';
/// The contents of the package config file.
late final String? _packageConfigContent;
/// The name of the subdirectory in [_dartToolRootName] that distinguishes
/// projects built with package:build.
static const String _dartToolBuildName = 'build';
final Map<String, WorkspacePackage> _workspacePackages = {};
static const List<String> _generatedPathParts = [
'.dart_tool',
'build',
'generated'
];
factory PackageConfigWorkspace(
ResourceProvider provider, //Packages packages,
/// The singular package in this workspace.
///
/// Each Pub workspace is itself one package.
late final PubWorkspacePackage _theOnlyPackage;
/// The associated pubspec file.
final File _pubspecFile;
/// The content of the `pubspec.yaml` file.
/// We read it once, so that all usages return consistent results.
final String? _pubspecContent;
/// The name of the package under development as defined in pubspec.yaml. This
/// matches the behavior of package:build.
@visibleForTesting
final String projectPackageName;
/// `.dart_tool/build/generated` in [root].
final String? _generatedRootPath;
/// [projectPackageName] in [_generatedRootPath].
final String? _generatedThisPath;
/// Indicates whether this workspace uses package build.
@visibleForTesting
final bool usesPackageBuild;
factory PubWorkspace(ResourceProvider provider, Packages packages,
String root, File pubspecFile) {
var folder = pubspecFile.parent;
final dartToolDir = folder.getChildAssumingFolder(_dartToolRootName);
final dartToolBuildDir =
dartToolDir.getChildAssumingFolder(_dartToolBuildName);
var pubspecContent = _fileContentOrNull(pubspecFile);
String? generatedRootPath;
String? generatedThisPath;
var projectPackageName = '';
var usesPackageBuild = false;
// Found the .dart_tool file, that's our project root. We also require a
// pubspec, to know the package name that package:build will assume.
try {
final yaml = loadYaml(pubspecContent!) as YamlMap;
projectPackageName = yaml['name'] as String;
if (dartToolBuildDir.exists) {
generatedRootPath =
provider.pathContext.joinAll([folder.path, ..._generatedPathParts]);
generatedThisPath =
provider.pathContext.join(generatedRootPath, projectPackageName);
usesPackageBuild = true;
}
} catch (_) {}
return PubWorkspace._(
provider,
packages,
root,
pubspecFile,
pubspecContent,
generatedRootPath,
generatedThisPath,
projectPackageName,
usesPackageBuild);
}
PubWorkspace._(
ResourceProvider provider,
Packages packages,
String root,
File packageConfigFile,
Packages packages) {
// Use the default packages if there is one.
var newPackages = packages == Packages.empty
? parsePackageConfigJsonFile(provider, packageConfigFile)
: packages;
return PackageConfigWorkspace._(
provider,
newPackages,
root,
packageConfigFile,
);
this._pubspecFile,
this._pubspecContent,
this._generatedRootPath,
this._generatedThisPath,
this.projectPackageName,
this.usesPackageBuild)
: super(provider, packages, root) {
_theOnlyPackage = PubWorkspacePackage(root, this);
}
PackageConfigWorkspace._(
super.provider, super.packages, super.root, this.packageConfigFile) {
_packageConfigContent = packageConfigFile.readAsStringSync();
}
Iterable<WorkspacePackage> get allPackages =>
_workspacePackages.values.toSet();
@override
bool get isConsistentWithFileSystem {
return _fileContentOrNull(packageConfigFile) == _packageConfigContent;
return _fileContentOrNull(_pubspecFile) == _pubspecContent;
}
@override
UriResolver get packageUriResolver {
return PackageConfigPackageUriResolver(
this, PackageMapUriResolver(provider, packageMap));
if (usesPackageBuild) {
return PackageBuildPackageUriResolver(
this, PackageMapUriResolver(provider, packageMap));
}
return PackageMapUriResolver(provider, packageMap);
}
List<PubWorkspacePackage> get pubPackages => [_theOnlyPackage];
/// For some package file, which may or may not be a package source (it could
/// be in `bin/`, `web/`, etc), find where its built counterpart will exist if
/// its a generated source.
@ -230,7 +292,7 @@ class PackageConfigWorkspace extends SimpleWorkspace {
@internal
@override
void contributeToResolutionSalt(ApiSignature buffer) {
buffer.addString(_packageConfigContent ?? '');
buffer.addString(_pubspecContent ?? '');
}
@override
@ -238,15 +300,18 @@ class PackageConfigWorkspace extends SimpleWorkspace {
DartSdk? sdk,
SummaryDataStore? summaryData,
) {
if (usesPackageBuild && summaryData != null) {
throw UnsupportedError(
'Summary files are not supported in a package:build workspace.');
}
var resolvers = <UriResolver>[];
if (sdk != null) {
resolvers.add(DartUriResolver(sdk));
}
if (summaryData != null) {
resolvers.add(InSummaryUriResolver(summaryData));
}
resolvers.add(packageUriResolver);
resolvers.add(PackageConfigFileUriResolver(this));
if (usesPackageBuild) {
resolvers.add(PackageBuildFileUriResolver(this));
}
resolvers.add(ResourceUriResolver(provider));
return SourceFactory(resolvers);
}
@ -261,13 +326,10 @@ class PackageConfigWorkspace extends SimpleWorkspace {
var context = provider.pathContext;
assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
try {
final package = findPackageFor(filePath);
if (package is PubPackage) {
final relativePath = context.relative(filePath, from: package.root);
final file = builtFile(relativePath, package._name ?? '');
if (file!.exists) {
return file;
}
final relativePath = context.relative(filePath, from: root);
final file = builtFile(relativePath, projectPackageName);
if (file!.exists) {
return file;
}
return provider.getFile(filePath);
} catch (_) {
@ -275,50 +337,26 @@ class PackageConfigWorkspace extends SimpleWorkspace {
}
}
/// Find the [PubPackage] that contains the given file path. The path
/// Find the [PubWorkspacePackage] that contains the given file path. The path
/// can be for a source file or a generated file. Generated files are located
/// in the '.dart_tool/build/generated' folder of the containing package.
@override
WorkspacePackage? findPackageFor(String filePath) {
PubWorkspacePackage? findPackageFor(String filePath) {
var pathContext = provider.pathContext;
// Must be in this workspace.
if (!pathContext.isWithin(root, filePath)) {
return null;
}
List<String> paths = [];
var folder = provider.getFile(filePath).parent;
for (var current in folder.withAncestors) {
var package = _workspacePackages[current.path];
if (package != null) {
for (var path in paths) {
_workspacePackages[path] = package;
}
return package;
}
var pubspec = current.getChildAssumingFile(file_paths.pubspecYaml);
if (pubspec.exists) {
if (_isInThirdPartyDart(pubspec)) {
if (usesPackageBuild) {
// If generated, must be for this package.
if (pathContext.isWithin(_generatedRootPath!, filePath)) {
if (!pathContext.isWithin(_generatedThisPath!, filePath)) {
return null;
}
var package = PubPackage(current.path, this, pubspec);
for (var path in paths) {
_workspacePackages[path] = package;
}
_workspacePackages[current.path] = package;
return package;
}
if (current.path == root) {
var package = BasicWorkspacePackage(root, this);
for (var path in paths) {
_workspacePackages[path] = package;
}
return package;
}
paths.add(current.path);
}
return null;
return _theOnlyPackage;
}
/// Unlike the way that sources are resolved against `.packages` (if foo
@ -332,22 +370,23 @@ class PackageConfigWorkspace extends SimpleWorkspace {
return context.join('lib', filePath);
}
/// Find the package config workspace that contains the given [filePath].
/// A [PackageConfigWorkspace] is rooted at the innermost package-config file.
static PackageConfigWorkspace? find(
/// Find the pub workspace that contains the given [filePath].
/// A [PubWorkspace] is rooted at the innermost pubspec/package-config pair,
/// or if that's not found, then the outermost pubspec.
static PubWorkspace? find(
ResourceProvider provider,
Packages packages,
String filePath,
) {
var start = provider.getFolder(filePath);
for (var current in start.withAncestors) {
var packageConfigFile = current
.getChildAssumingFolder(file_paths.dotDartTool)
.getChildAssumingFile(file_paths.packageConfigJson);
if (packageConfigFile.exists) {
var pubspec = current.getChildAssumingFile(file_paths.pubspecYaml);
if (pubspec.exists) {
if (_isInThirdPartyDart(pubspec)) {
return null;
}
var root = current.path;
return PackageConfigWorkspace(
provider, root, packageConfigFile, packages);
return PubWorkspace(provider, packages, root, pubspec);
}
}
return null;
@ -376,12 +415,12 @@ class PackageConfigWorkspace extends SimpleWorkspace {
}
}
/// Information about a package defined in a [PackageConfigWorkspace].
/// Information about a package defined in a [PubWorkspace].
///
/// Separate from [Packages] or package maps, this class is designed to simply
/// understand whether arbitrary file paths represent libraries declared within
/// a given package in a [PackageConfigWorkspace].
class PubPackage extends WorkspacePackage {
/// a given package in a [PubWorkspace].
class PubWorkspacePackage extends WorkspacePackage {
static const List<String> _generatedPathParts = [
file_paths.dotDartTool,
file_paths.packageBuild,
@ -391,11 +430,10 @@ class PubPackage extends WorkspacePackage {
@override
final String root;
final String? _name;
Pubspec? _pubspec;
final String? _pubspecContent;
final Pubspec? _pubspec;
/// A flag to indicate if we've tried to parse the pubspec.
bool _parsedPubspec = false;
VersionConstraint? _sdkVersionConstraint;
@ -403,30 +441,30 @@ class PubPackage extends WorkspacePackage {
bool _parsedSdkConstraint = false;
@override
final PackageConfigWorkspace workspace;
final PubWorkspace workspace;
factory PubPackage(
String root, PackageConfigWorkspace workspace, File pubspecFile) {
var pubspecContent = pubspecFile.readAsStringSync();
var pubspec = Pubspec.parse(pubspecContent);
var packageName = pubspec.name?.value.text;
return PubPackage._(root, workspace, pubspecContent, pubspec, packageName);
PubWorkspacePackage(this.root, this.workspace);
/// Get the associated parsed [Pubspec], or `null` if there was an error in
/// reading or parsing.
Pubspec? get pubspec {
if (!_parsedPubspec) {
_parsedPubspec = true;
final content = workspace._pubspecContent;
if (content != null) {
_pubspec = Pubspec.parse(content);
}
}
return _pubspec;
}
PubPackage._(this.root, this.workspace, this._pubspecContent, this._pubspec,
this._name);
Pubspec? get pubspec => _pubspec;
String? get pubspecContent => _pubspecContent;
/// The version range for the SDK specified for this package , or `null` if
/// it is ill-formatted or not set.
VersionConstraint? get sdkVersionConstraint {
if (!_parsedSdkConstraint) {
_parsedSdkConstraint = true;
var sdkValue = _pubspec?.environment?.sdk?.value.text;
var sdkValue = pubspec?.environment?.sdk?.value.text;
if (sdkValue != null) {
try {
_sdkVersionConstraint = VersionConstraint.parse(sdkValue);
@ -446,7 +484,7 @@ class PubPackage extends WorkspacePackage {
// TODO(keertip): Check to see if we can use information from package
// config to find out if a file is in this package.
var packageName = uri.pathSegments[0];
return packageName == _name;
return packageName == workspace.projectPackageName;
}
if (uri.isScheme('file')) {

View file

@ -229,19 +229,25 @@ class AnalysisContextCollectionTest with ResourceProviderMixin {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
newSinglePackageConfigJsonFile(
packagePath: testPackageRootPath,
name: 'test',
);
newFile('$testPackageRootPath/lib/a.dart', '');
_assertWorkspaceCollectionText(workspaceRootPath, r'''
contexts
/home
/home/test
packagesFile: /home/test/.dart_tool/package_config.json
workspace: workspace_0
analyzedFiles
/home/test/lib/a.dart
uri: file:///home/test/lib/a.dart
uri: package:test/a.dart
workspacePackage_0_0
workspaces
workspace_0: BasicWorkspace
root: /home
root: /home/test
workspacePackage_0_0
''');
}
@ -289,15 +295,15 @@ analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
analysisOptions_1: /home/test/lib/nested/analysis_options.yaml
workspaces
workspace_0: PackageConfigWorkspace
workspace_0: PubWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubPackage
workspacePackage_0_0: PubWorkspacePackage
root: /home/test
workspace_1: PackageConfigWorkspace
workspace_1: PubWorkspace
root: /home/test
pubPackages
workspacePackage_1_0: PubPackage
workspacePackage_1_0: PubWorkspacePackage
root: /home/test
''');
}
@ -345,15 +351,15 @@ contexts
uri: package:nested/b.dart
workspacePackage_1_0
workspaces
workspace_0: PackageConfigWorkspace
workspace_0: PubWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubPackage
workspacePackage_0_0: PubWorkspacePackage
root: /home/test
workspace_1: PackageConfigWorkspace
workspace_1: PubWorkspace
root: /home/test/nested
pubPackages
workspacePackage_1_0: PubPackage
workspacePackage_1_0: PubWorkspacePackage
root: /home/test/nested
''');
}
@ -384,10 +390,10 @@ contexts
uri: package:test/a.dart
workspacePackage_0_0
workspaces
workspace_0: PackageConfigWorkspace
workspace_0: PubWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubPackage
workspacePackage_0_0: PubWorkspacePackage
root: /home/test
sdkVersionConstraint: ^3.0.0
''');
@ -424,10 +430,10 @@ contexts
analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
workspaces
workspace_0: PackageConfigWorkspace
workspace_0: PubWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubPackage
workspacePackage_0_0: PubWorkspacePackage
root: /home/test
''');
}
@ -483,15 +489,15 @@ analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
analysisOptions_1: /home/test/analysis_options.yaml
workspaces
workspace_0: PackageConfigWorkspace
workspace_0: PubWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubPackage
workspacePackage_0_0: PubWorkspacePackage
root: /home/test
workspace_1: PackageConfigWorkspace
workspace_1: PubWorkspace
root: /home/test/nested
pubPackages
workspacePackage_1_0: PubPackage
workspacePackage_1_0: PubWorkspacePackage
root: /home/test/nested
''');
}
@ -684,14 +690,14 @@ class _AnalysisContextCollectionPrinter {
_idOfWorkspacePackage(workspace.theOnlyPackage),
);
});
case PackageConfigWorkspace():
sink.writelnWithIndent('$id: PackageConfigWorkspace');
case PubWorkspace():
sink.writelnWithIndent('$id: PubWorkspace');
sink.withIndent(() {
final root = resourceProvider.getFolder(workspace.root);
sink.writelnWithIndent('root: ${root.posixPath}');
sink.writeElements(
'pubPackages',
workspace.allPackages.toList(),
workspace.pubPackages.toList(),
_writeWorkspacePackage,
);
});
@ -710,8 +716,8 @@ class _AnalysisContextCollectionPrinter {
final root = resourceProvider.getFolder(package.root);
sink.writelnWithIndent('root: ${root.posixPath}');
});
case PubPackage():
sink.writelnWithIndent('$id: PubPackage');
case PubWorkspacePackage():
sink.writelnWithIndent('$id: PubWorkspacePackage');
sink.withIndent(() {
final root = resourceProvider.getFolder(package.root);
sink.writelnWithIndent('root: ${root.posixPath}');

View file

@ -20,6 +20,7 @@ import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/blaze.dart';
import 'package:analyzer/src/workspace/pub.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@ -143,24 +144,6 @@ class ContextBuilderImplTest with ResourceProviderMixin {
expect(context.sdkRoot, sdkRoot);
}
void test_sourceFactory_basicWorkspace() {
var projectPath = convertPath('/home/my');
newFile('/home/my/pubspec.yaml', '');
// no package uri resolution information
var analysisContext = _createSingleAnalysisContext(projectPath);
expect(analysisContext.contextRoot.workspace, isA<BasicWorkspace>());
expect(
analysisContext.uriResolvers,
unorderedEquals([
isA<DartUriResolver>(),
isA<PackageMapUriResolver>(),
isA<ResourceUriResolver>(),
]),
);
}
void test_sourceFactory_blazeWorkspace() {
var projectPath = convertPath('/workspace/my/module');
newFile('/workspace/${file_paths.blazeWorkspaceMarker}', '');
@ -180,6 +163,23 @@ class ContextBuilderImplTest with ResourceProviderMixin {
);
}
void test_sourceFactory_pubWorkspace() {
var projectPath = convertPath('/home/my');
newFile('/home/my/pubspec.yaml', '');
var analysisContext = _createSingleAnalysisContext(projectPath);
expect(analysisContext.contextRoot.workspace, isA<PubWorkspace>());
expect(
analysisContext.uriResolvers,
unorderedEquals([
isA<DartUriResolver>(),
isA<PackageMapUriResolver>(),
isA<ResourceUriResolver>(),
]),
);
}
/// Return a single expected analysis context at the [path].
DriverBasedAnalysisContext _createSingleAnalysisContext(String path) {
var roots = ContextLocatorImpl(

View file

@ -668,7 +668,7 @@ analyzer:
);
expect(roots, hasLength(1));
ContextRoot root = findRoot(roots, getFolder('/home'));
ContextRoot root = findRoot(roots, getFolder('/'));
expect(
root.includedPaths, unorderedEquals([testFile1.path, testFile2.path]));
expect(root.excludedPaths, isEmpty);
@ -761,13 +761,13 @@ analyzer:
_assertAnalyzedFiles2(root, [fooFile, barFile]);
}
void test_locateRoots_multiple_files_differentWorkspaces_packageConfig() {
void test_locateRoots_multiple_files_differentWorkspaces_pub() {
var rootPath = '/home';
var fooPath = '$rootPath/foo';
var barPath = '$rootPath/bar';
newPackageConfigJsonFile(fooPath, '');
newPackageConfigJsonFile(barPath, '');
newPubspecYamlFile(fooPath, '');
newPubspecYamlFile(barPath, '');
var fooFile = newFile('$fooPath/lib/foo.dart', '');
var barFile = newFile('$barPath/lib/bar.dart', '');
@ -781,7 +781,7 @@ analyzer:
expect(fooRoot.includedPaths, unorderedEquals([fooFile.path]));
expect(fooRoot.excludedPaths, isEmpty);
expect(fooRoot.optionsFile, isNull);
expect(fooRoot.packagesFile, isNotNull);
expect(fooRoot.packagesFile, isNull);
_assertPubWorkspace(fooRoot.workspace, fooPath);
_assertAnalyzedFiles2(fooRoot, [fooFile]);
@ -789,7 +789,7 @@ analyzer:
expect(barRoot.includedPaths, unorderedEquals([barFile.path]));
expect(barRoot.excludedPaths, isEmpty);
expect(barRoot.optionsFile, isNull);
expect(barRoot.packagesFile, isNotNull);
expect(barRoot.packagesFile, isNull);
_assertPubWorkspace(barRoot.workspace, barPath);
_assertAnalyzedFiles2(barRoot, [barFile]);
}
@ -1774,7 +1774,7 @@ ${getFolder(outPath).path}
}
void _assertPubWorkspace(Workspace workspace, String posixRoot) {
workspace as PackageConfigWorkspace;
workspace as PubWorkspace;
var root = convertPath(posixRoot);
expect(workspace.root, root);
}

View file

@ -653,7 +653,7 @@ analyzer:
/// When there is a packages file in a containing directory, that would
/// control analysis of the files, but we provide an override, we ignore
/// and don't look into containing directories, so the context root can be
/// the don't look into containing directories, so the context root can be
/// just the file system root.
void
test_locateRoots_multiple_fileAndSiblingFile_hasPackages_overridePackages() {
@ -668,7 +668,7 @@ analyzer:
);
expect(roots, hasLength(1));
ContextRoot root = findRoot(roots, getFolder('/home'));
ContextRoot root = findRoot(roots, getFolder('/'));
expect(
root.includedPaths, unorderedEquals([testFile1.path, testFile2.path]));
expect(root.excludedPaths, isEmpty);
@ -761,13 +761,13 @@ analyzer:
_assertAnalyzedFiles2(root, [fooFile, barFile]);
}
void test_locateRoots_multiple_files_differentWorkspaces_packageConfig() {
void test_locateRoots_multiple_files_differentWorkspaces_pub() {
var rootPath = '/home';
var fooPath = '$rootPath/foo';
var barPath = '$rootPath/bar';
newPackageConfigJsonFile(fooPath, '');
newPackageConfigJsonFile(barPath, '');
newPubspecYamlFile(fooPath, '');
newPubspecYamlFile(barPath, '');
var fooFile = newFile('$fooPath/lib/foo.dart', '');
var barFile = newFile('$barPath/lib/bar.dart', '');
@ -781,7 +781,7 @@ analyzer:
expect(fooRoot.includedPaths, unorderedEquals([fooFile.path]));
expect(fooRoot.excludedPaths, isEmpty);
expect(fooRoot.optionsFile, isNull);
expect(fooRoot.packagesFile, isNotNull);
expect(fooRoot.packagesFile, isNull);
_assertPubWorkspace(fooRoot.workspace, fooPath);
_assertAnalyzedFiles2(fooRoot, [fooFile]);
@ -789,7 +789,7 @@ analyzer:
expect(barRoot.includedPaths, unorderedEquals([barFile.path]));
expect(barRoot.excludedPaths, isEmpty);
expect(barRoot.optionsFile, isNull);
expect(barRoot.packagesFile, isNotNull);
expect(barRoot.packagesFile, isNull);
_assertPubWorkspace(barRoot.workspace, barPath);
_assertAnalyzedFiles2(barRoot, [barFile]);
}
@ -1746,6 +1746,7 @@ ${getFolder(outPath).path}
expect(package1Root.packagesFile, packagesFile);
}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/53874')
void test_multiple_packages_monorepo() {
var rootPath = convertPath('/test/outer');
Folder rootFolder = newFolder(rootPath);
@ -1825,7 +1826,7 @@ ${getFolder(outPath).path}
}
void _assertPubWorkspace(Workspace workspace, String posixRoot) {
workspace as PackageConfigWorkspace;
workspace as PubWorkspace;
var root = convertPath(posixRoot);
expect(workspace.root, root);
}

View file

@ -231,9 +231,17 @@ abstract class ContextResolutionTest
expect(workspace, TypeMatcher<GnWorkspace>());
}
void assertPackageConfigWorkspaceFor(File file) {
void assertPackageBuildWorkspaceFor(File file) {
var workspace = contextFor(file).contextRoot.workspace;
expect(workspace, TypeMatcher<PackageConfigWorkspace>());
expect(
workspace,
isA<PubWorkspace>()
.having((e) => e.usesPackageBuild, 'usesPackageBuild', true));
}
void assertPubWorkspaceFor(File file) {
var workspace = contextFor(file).contextRoot.workspace;
expect(workspace, TypeMatcher<PubWorkspace>());
}
AnalysisContext contextFor(File file) {

View file

@ -11,7 +11,7 @@ import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DeprecatedMemberUse_PackageConfigWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_BasicWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_BlazeWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_GnWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_PackageBuildWorkspaceTest);
@ -19,173 +19,7 @@ main() {
}
@reflectiveTest
class DeprecatedMemberUse_BlazeWorkspaceTest
extends BlazeWorkspaceResolutionTest {
test_dart() async {
newFile('$workspaceRootPath/foo/bar/lib/a.dart', r'''
@deprecated
class A {}
''');
await assertErrorsInCode(r'''
import 'package:foo.bar/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 41, 1),
]);
}
test_thirdPartyDart() async {
newFile('$workspaceThirdPartyDartPath/aaa/lib/a.dart', r'''
@deprecated
class A {}
''');
assertBlazeWorkspaceFor(testFile);
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
}
@reflectiveTest
class DeprecatedMemberUse_GnWorkspaceTest extends ContextResolutionTest {
@override
List<String> get collectionIncludedPaths => [workspaceRootPath];
String get genPath => '$outPath/dartlang/gen';
String get myPackageLibPath => '$myPackageRootPath/lib';
String get myPackageRootPath => '$workspaceRootPath/my';
Folder get outFolder => getFolder(outPath);
String get outPath => '$workspaceRootPath/out/default';
@override
File get testFile => getFile('$myPackageLibPath/my.dart');
String get workspaceRootPath => '/workspace';
@override
void setUp() {
super.setUp();
newFolder('$workspaceRootPath/.jiri_root');
newFile('$workspaceRootPath/.fx-build-dir', '''
${outFolder.path}
''');
newBuildGnFile(myPackageRootPath, '');
}
test_differentPackage() async {
newBuildGnFile('$workspaceRootPath/aaa', '');
var myPackageConfig = getFile('$genPath/my/my_package_config.json');
_writeWorkspacePackagesFile(myPackageConfig, {
'aaa': '$workspaceRootPath/aaa/lib',
'my': myPackageLibPath,
});
newFile('$workspaceRootPath/aaa/lib/a.dart', r'''
@deprecated
class A {}
''');
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
@override
void verifyCreatedCollection() {
super.verifyCreatedCollection();
assertGnWorkspaceFor(testFile);
}
void _writeWorkspacePackagesFile(
File file, Map<String, String> nameToLibPath) {
var packages = nameToLibPath.entries.map((entry) => '''{
"languageVersion": "2.2",
"name": "${entry.key}",
"packageUri": ".",
"rootUri": "${toUriStr(entry.value)}"
}''');
newFile(file.path, '''{
"configVersion": 2,
"packages": [ ${packages.join(', ')} ]
}''');
}
}
@reflectiveTest
class DeprecatedMemberUse_PackageBuildWorkspaceTest
extends _PackageConfigWorkspaceBase {
test_generated() async {
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: '$workspaceRootPath/aaa'),
);
newPubspecYamlFile(testPackageRootPath, 'name: test');
_newTestPackageGeneratedFile(
packageName: 'aaa',
pathInLib: 'a.dart',
content: r'''
@deprecated
class A {}
''',
);
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
test_lib() async {
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: '$workspaceRootPath/aaa'),
);
newFile('$workspaceRootPath/aaa/lib/a.dart', r'''
@deprecated
class A {}
''');
newPubspecYamlFile(testPackageRootPath, 'name: test');
_createTestPackageBuildMarker();
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
}
@reflectiveTest
class DeprecatedMemberUse_PackageConfigWorkspaceTest
extends PubPackageResolutionTest {
class DeprecatedMemberUse_BasicWorkspaceTest extends PubPackageResolutionTest {
String get externalLibPath => '$workspaceRootPath/aaa/lib/a.dart';
String get externalLibUri => 'package:aaa/a.dart';
@ -2028,11 +1862,176 @@ void f() {
@override
void verifyCreatedCollection() {
super.verifyCreatedCollection();
assertPackageConfigWorkspaceFor(testFile);
assertBasicWorkspaceFor(testFile);
}
}
class _PackageConfigWorkspaceBase extends PubPackageResolutionTest {
@reflectiveTest
class DeprecatedMemberUse_BlazeWorkspaceTest
extends BlazeWorkspaceResolutionTest {
test_dart() async {
newFile('$workspaceRootPath/foo/bar/lib/a.dart', r'''
@deprecated
class A {}
''');
await assertErrorsInCode(r'''
import 'package:foo.bar/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 41, 1),
]);
}
test_thirdPartyDart() async {
newFile('$workspaceThirdPartyDartPath/aaa/lib/a.dart', r'''
@deprecated
class A {}
''');
assertBlazeWorkspaceFor(testFile);
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
}
@reflectiveTest
class DeprecatedMemberUse_GnWorkspaceTest extends ContextResolutionTest {
@override
List<String> get collectionIncludedPaths => [workspaceRootPath];
String get genPath => '$outPath/dartlang/gen';
String get myPackageLibPath => '$myPackageRootPath/lib';
String get myPackageRootPath => '$workspaceRootPath/my';
Folder get outFolder => getFolder(outPath);
String get outPath => '$workspaceRootPath/out/default';
@override
File get testFile => getFile('$myPackageLibPath/my.dart');
String get workspaceRootPath => '/workspace';
@override
void setUp() {
super.setUp();
newFolder('$workspaceRootPath/.jiri_root');
newFile('$workspaceRootPath/.fx-build-dir', '''
${outFolder.path}
''');
newBuildGnFile(myPackageRootPath, '');
}
test_differentPackage() async {
newBuildGnFile('$workspaceRootPath/aaa', '');
var myPackageConfig = getFile('$genPath/my/my_package_config.json');
_writeWorkspacePackagesFile(myPackageConfig, {
'aaa': '$workspaceRootPath/aaa/lib',
'my': myPackageLibPath,
});
newFile('$workspaceRootPath/aaa/lib/a.dart', r'''
@deprecated
class A {}
''');
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
@override
void verifyCreatedCollection() {
super.verifyCreatedCollection();
assertGnWorkspaceFor(testFile);
}
void _writeWorkspacePackagesFile(
File file, Map<String, String> nameToLibPath) {
var packages = nameToLibPath.entries.map((entry) => '''{
"languageVersion": "2.2",
"name": "${entry.key}",
"packageUri": ".",
"rootUri": "${toUriStr(entry.value)}"
}''');
newFile(file.path, '''{
"configVersion": 2,
"packages": [ ${packages.join(', ')} ]
}''');
}
}
@reflectiveTest
class DeprecatedMemberUse_PackageBuildWorkspaceTest
extends _PackageBuildWorkspaceBase {
test_generated() async {
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: '$workspaceRootPath/aaa'),
);
newPubspecYamlFile(testPackageRootPath, 'name: test');
_newTestPackageGeneratedFile(
packageName: 'aaa',
pathInLib: 'a.dart',
content: r'''
@deprecated
class A {}
''',
);
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
test_lib() async {
writeTestPackageConfig(
PackageConfigFileBuilder()
..add(name: 'aaa', rootPath: '$workspaceRootPath/aaa'),
);
newFile('$workspaceRootPath/aaa/lib/a.dart', r'''
@deprecated
class A {}
''');
newPubspecYamlFile(testPackageRootPath, 'name: test');
_createTestPackageBuildMarker();
await assertErrorsInCode(r'''
import 'package:aaa/a.dart';
void f(A a) {}
''', [
error(HintCode.DEPRECATED_MEMBER_USE, 37, 1),
]);
}
}
class _PackageBuildWorkspaceBase extends PubPackageResolutionTest {
String get testPackageGeneratedPath {
return '$testPackageRootPath/.dart_tool/build/generated';
}
@ -2040,7 +2039,7 @@ class _PackageConfigWorkspaceBase extends PubPackageResolutionTest {
@override
void verifyCreatedCollection() {
super.verifyCreatedCollection();
assertPackageConfigWorkspaceFor(testFile);
assertPackageBuildWorkspaceFor(testFile);
}
void _createTestPackageBuildMarker() {

View file

@ -604,8 +604,8 @@ dependencies:
class C { }
''');
expect(context.package, TypeMatcher<PubPackage>());
final pubPackage = context.package as PubPackage;
expect(context.package, TypeMatcher<PubWorkspacePackage>());
final pubPackage = context.package as PubWorkspacePackage;
final pubspec = pubPackage.pubspec!;
final argsDep = pubspec.dependencies!

View file

@ -7,20 +7,17 @@ import 'package:analyzer/source/source.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/generated/source.dart' show UriResolver;
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/pub.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../generated/test_support.dart';
import '../dart/resolution/context_collection_resolution.dart';
import 'workspace_test_support.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PubPackageTest);
defineReflectiveTests(PackageConfigWorkspaceTest);
defineReflectiveTests(PubWorkspacePackageTest);
defineReflectiveTests(PubWorkspaceTest);
defineReflectiveTests(PackageBuildFileUriResolverTest);
defineReflectiveTests(PackageBuildPackageUriResolverTest);
});
@ -51,8 +48,8 @@ class MockUriResolver implements UriResolver {
@reflectiveTest
class PackageBuildFileUriResolverTest with ResourceProviderMixin {
late final PackageConfigWorkspace workspace;
late final PackageConfigFileUriResolver resolver;
late final PubWorkspace workspace;
late final PackageBuildFileUriResolver resolver;
File get testFile => getFile('$testPackageLibPath/test.dart');
@ -70,17 +67,20 @@ class PackageBuildFileUriResolverTest with ResourceProviderMixin {
void setUp() {
newFolder(testPackageGeneratedLibPath);
newPubspecYamlFile(testPackageRootPath, 'name: test');
var config = PackageConfigFileBuilder();
config.add(name: 'test', rootPath: convertPath(testPackageRootPath));
newPackageConfigJsonFile(
testPackageRootPath, config.toContent(toUriStr: toUriStr));
workspace = PackageConfigWorkspace.find(
workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
Packages({
'test': Package(
name: 'test',
rootFolder: getFolder(testPackageRootPath),
libFolder: getFolder(testPackageLibPath),
languageVersion: null,
),
}),
convertPath(testPackageRootPath),
)!;
resolver = PackageConfigFileUriResolver(workspace);
resolver = PackageBuildFileUriResolver(workspace);
expect(workspace.isBlaze, isFalse);
}
@ -146,8 +146,8 @@ class PackageBuildFileUriResolverTest with ResourceProviderMixin {
@reflectiveTest
class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
late final PackageConfigWorkspace workspace;
late final PackageConfigPackageUriResolver resolver;
late final PubWorkspace workspace;
late final PackageBuildPackageUriResolver resolver;
late final MockUriResolver packageUriResolver;
Uri addPackageSource(String path, String uriStr, {bool create = true}) {
@ -161,7 +161,6 @@ class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
void setUp() {
newPubspecYamlFile('/workspace', 'name: project');
newPackageConfigJsonFile('/workspace', '');
}
void test_resolveAbsolute_generated() {
@ -222,17 +221,20 @@ class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
newFile(path, '');
}
}
var config = PackageConfigFileBuilder();
config.add(name: 'project', rootPath: '/workspace');
newPackageConfigJsonFile(
workspacePath, config.toContent(toUriStr: toUriStr));
workspace = PackageConfigWorkspace.find(
workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
Packages({
'project': Package(
name: 'project',
rootFolder: getFolder('/workspace'),
libFolder: getFolder('/workspace'),
languageVersion: null,
),
}),
convertPath(workspacePath),
)!;
packageUriResolver = MockUriResolver();
resolver = PackageConfigPackageUriResolver(workspace, packageUriResolver);
resolver = PackageBuildPackageUriResolver(workspace, packageUriResolver);
}
Source _assertResolveUri(
@ -251,286 +253,9 @@ class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
}
@reflectiveTest
class PackageConfigWorkspaceTest with ResourceProviderMixin {
void test_builtFile_currentProject() {
newFolder('/workspace/.dart_tool/build');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final libFile = newFile(
'/workspace/.dart_tool/build/generated/project/lib/file.dart', '');
expect(
workspace.builtFile(convertPath('lib/file.dart'), 'project'), libFile);
}
void test_builtFile_importedPackage() {
newFolder('/workspace/.dart_tool/build');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project', 'foo']);
final libFile =
newFile('/workspace/.dart_tool/build/generated/foo/lib/file.dart', '');
expect(workspace.builtFile(convertPath('lib/file.dart'), 'foo'), libFile);
}
void test_builtFile_notInPackagesGetsHidden() {
newFolder('/workspace/.dart_tool/build');
// Ensure package:bar is not configured.
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project', 'foo']);
// Create a generated file in package:bar.
newFile('/workspace/.dart_tool/build/generated/bar/lib/file.dart', '');
// Bar not in packages, file should not be returned.
expect(workspace.builtFile('lib/file.dart', 'bar'), isNull);
}
void test_find_directory() {
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
expect(workspace.isBlaze, isFalse);
expect(workspace.root, convertPath('/workspace'));
}
void test_find_file() {
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
expect(workspace.root, convertPath('/workspace'));
}
void test_find_hasBuild_hasPubspec_malformed_dontGoToUp() {
newFolder('/workspace/.dart_tool/build/generated');
newFolder('/workspace/aaa/.dart_tool/build/generated');
newPubspecYamlFile('/workspace/aaa', '*');
PackageConfigWorkspace workspace = _createWorkspace('/workspace/aaa', []);
expect(workspace, isNotNull);
expect(workspace.root, convertPath('/workspace/aaa'));
}
void test_find_hasDartToolAndPubspec() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
PackageConfigWorkspace workspace = _createWorkspace('/workspace', []);
expect(workspace.root, convertPath('/workspace'));
}
void test_find_hasDartToolAndPubspec_inParentDirectory() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newFolder('/workspace/opened/up/a/child/dir/.dart_tool/build');
newPubspecYamlFile('/workspace/opened/up/a/child/dir', 'name: subproject');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace/opened/up/a/child/dir', ['project']);
expect(workspace.root, convertPath('/workspace/opened/up/a/child/dir'));
}
void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloDartTool() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newFolder('/workspace/opened/up/a/child/dir');
newFolder('/workspace/opened/up/a/child/dir/.dart_tool/build');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
expect(workspace.root, convertPath('/workspace'));
}
void test_find_hasDartToolNoBuild() {
// Edge case: an empty .dart_tool directory. Don't assume package:build.
newFolder('/workspace/.dart_tool');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
expect(workspace, isNotNull);
}
void test_find_hasDartToolNoPackageConfig() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
var workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace, isNull);
}
void test_find_hasDartToolPubButNotBuild() {
// Dart projects will have this directory, that don't use package:build.
newFolder('/workspace/.dart_tool/pub');
newPackageConfigJsonFile('/workspace', '');
var workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace!.root, convertPath('/workspace'));
}
void test_find_hasMalformedPubspec() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newPubspecYamlFile('/workspace', 'not: yaml: here! 1111');
newPackageConfigJsonFile('/workspace', '');
var workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace?.root, convertPath('/workspace'));
}
void test_find_hasPubspec_noDartTool_dontGoUp() {
newFolder('/workspace/.dart_tool/build/generated');
newPackageConfigJsonFile('/workspace/aaa', '');
newPubspecYamlFile('/workspace/aaa', '*');
var workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace/aaa/lib'),
);
expect(workspace?.root, convertPath('/workspace/aaa'));
}
void test_find_hasPubspecNoDartTool() {
var workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace, isNull);
}
void test_findFile_bin() {
newFolder('/workspace/.dart_tool/build/generated/project/bin');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final binFile = newFile('/workspace/bin/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/bin/file.dart')), binFile);
}
void test_findFile_binGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/bin');
newPubspecYamlFile('/workspace', 'name: project');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final binFile = newFile(
'/workspace/.dart_tool/build/generated/project/bin/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/bin/file.dart')), binFile);
}
void test_findFile_libGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newPubspecYamlFile('/workspace', 'name: project');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final libFile = newFile(
'/workspace/.dart_tool/build/generated/project/lib/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/lib/file.dart')), libFile);
}
void test_findFile_test() {
newFolder('/workspace/.dart_tool/build/generated/project/test');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final testFile = newFile('/workspace/test/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/test/file.dart')), testFile);
}
void test_findFile_testGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/test');
newPubspecYamlFile('/workspace', 'name: project');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final testFile = newFile(
'/workspace/.dart_tool/build/generated/project/test/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/test/file.dart')), testFile);
}
void test_findFile_web() {
newFolder('/workspace/.dart_tool/build/generated/project/web');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final webFile = newFile('/workspace/web/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/web/file.dart')), webFile);
}
void test_findFile_webGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/web');
newPubspecYamlFile('/workspace', 'name: project');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
final webFile = newFile(
'/workspace/.dart_tool/build/generated/project/web/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/web/file.dart')), webFile);
}
void test_isConsistentWithFileSystem() {
newFolder('/workspace/.dart_tool/build/generated/project/bin');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project']);
expect(workspace.isConsistentWithFileSystem, isTrue);
newPackageConfigJsonFile('/workspace', 'project:/workspace');
expect(workspace.isConsistentWithFileSystem, isFalse);
}
void test_multiple_packages() {
var aFilePath = '/workspace/a/lib/a.dart';
var bFilePath = '/workspace/b/b.dart';
_addResources(['/workspace/a/lib/', '/workspace/b/', aFilePath, bFilePath]);
newPubspecYamlFile('/workspace/a', 'name: a');
PackageConfigWorkspace workspace =
_createWorkspace('/workspace', ['project', 'foo']);
expect(workspace.root, convertPath('/workspace'));
workspace.findPackageFor(convertPath(aFilePath));
workspace.findPackageFor(convertPath(bFilePath));
expect(workspace.allPackages,
unorderedEquals([isA<PubPackage>(), isA<BasicWorkspacePackage>()]));
}
void _addResources(List<String> paths) {
for (String path in paths) {
if (path.endsWith('/')) {
newFolder(path.substring(0, path.length - 1));
} else {
newFile(path, '');
}
}
}
PackageConfigWorkspace _createWorkspace(
String root, List<String> packageNames) {
var config = PackageConfigFileBuilder();
for (var name in packageNames) {
config.add(name: name, rootPath: convertPath('/packages/$name'));
}
newPackageConfigJsonFile(root, config.toContent(toUriStr: toUriStr));
return PackageConfigWorkspace.find(
resourceProvider,
Packages.empty,
convertPath(root),
)!;
}
}
@reflectiveTest
class PubPackageTest extends WorkspacePackageTest {
late final PackageConfigWorkspace myWorkspace;
late final WorkspacePackage myPackage;
class PubWorkspacePackageTest extends WorkspacePackageTest {
late final PubWorkspace myWorkspace;
late final PubWorkspacePackage myPackage;
String get fooPackageLibPath => '$fooPackageRootPath/lib';
@ -553,29 +278,45 @@ class PubPackageTest extends WorkspacePackageTest {
// workspace 1 with packages 'p1' and 'workspace'
newPubspecYamlFile('/workspace', 'name: project');
var config = PackageConfigFileBuilder();
config.add(name: 'p1', rootPath: '/.pubcache/p1');
config.add(name: 'workspace', rootPath: '/workspace');
newPackageConfigJsonFile(
'/workspace', config.toContent(toUriStr: toUriStr));
workspace = PackageConfigWorkspace.find(
workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
Packages({
'p1': Package(
name: 'p1',
rootFolder: getFolder('/.pubcache/p1'),
libFolder: getFolder('/.pubcache/p1/lib'),
languageVersion: null,
),
'workspace': Package(
name: 'workspace',
rootFolder: getFolder('/workspace'),
libFolder: getFolder('/workspace/lib'),
languageVersion: null,
),
}),
convertPath('/workspace'),
)!;
expect(workspace.isBlaze, isFalse);
// workspace 2 with packages 'my' and 'foo'
newPubspecYamlFile(myPackageRootPath, 'name: my');
config = PackageConfigFileBuilder();
config.add(name: 'my', rootPath: myPackageRootPath);
config.add(name: 'foo', rootPath: fooPackageRootPath);
newPackageConfigJsonFile(
myPackageRootPath, config.toContent(toUriStr: toUriStr));
newFolder(myPackageGeneratedPath);
myWorkspace = PackageConfigWorkspace.find(
myWorkspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
Packages({
'my': Package(
name: 'my',
rootFolder: getFolder(myPackageRootPath),
libFolder: getFolder(myPackageLibPath),
languageVersion: null,
),
'foo': Package(
name: 'foo',
rootFolder: getFolder(fooPackageRootPath),
libFolder: getFolder(fooPackageLibPath),
languageVersion: null,
),
}),
convertPath(myPackageRootPath),
)!;
final fakeFile = getFile('$myPackageLibPath/fake.dart');
@ -608,6 +349,28 @@ class PubPackageTest extends WorkspacePackageTest {
);
}
test_contains_fileUri_generated() {
var myGeneratedPath = '$myPackageGeneratedPath/my/test/a.dart';
newFile(myGeneratedPath, '');
var fooGeneratedPath = '$myPackageGeneratedPath/foo/test/a.dart';
newFile(fooGeneratedPath, '');
expect(
myPackage.contains(
_sourceWithFileUri(myGeneratedPath),
),
isTrue,
);
expect(
myPackage.contains(
_sourceWithFileUri(fooGeneratedPath),
),
isFalse,
);
}
test_contains_packageUri() {
expect(
myPackage.contains(
@ -672,6 +435,22 @@ class PubPackageTest extends WorkspacePackageTest {
expect(package.workspace, myWorkspace);
}
test_findPackageFor_my_generated_other() {
expect(
myWorkspace.findPackageFor(
convertPath('$myPackageGeneratedPath/foo/lib/a.dart'),
),
isNull,
);
expect(
myWorkspace.findPackageFor(
convertPath('$myPackageGeneratedPath/foo/test/a.dart'),
),
isNull,
);
}
test_findPackageFor_my_generated_testFile() {
var package = myWorkspace.findPackageFor(
convertPath('$myPackageGeneratedPath/my/test/a.dart'),
@ -746,6 +525,288 @@ class PubPackageTest extends WorkspacePackageTest {
}
}
@reflectiveTest
class PubWorkspaceTest with ResourceProviderMixin {
void test_builtFile_currentProject() {
newFolder('/workspace/.dart_tool/build');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final libFile = newFile(
'/workspace/.dart_tool/build/generated/project/lib/file.dart', '');
expect(
workspace.builtFile(convertPath('lib/file.dart'), 'project'), libFile);
}
void test_builtFile_importedPackage() {
newFolder('/workspace/.dart_tool/build');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project', 'foo']);
final libFile =
newFile('/workspace/.dart_tool/build/generated/foo/lib/file.dart', '');
expect(workspace.builtFile(convertPath('lib/file.dart'), 'foo'), libFile);
}
void test_builtFile_notInPackagesGetsHidden() {
newFolder('/workspace/.dart_tool/build');
newPubspecYamlFile('/workspace', 'name: project');
// Ensure package:bar is not configured.
PubWorkspace workspace = _createWorkspace('/workspace', ['project', 'foo']);
// Create a generated file in package:bar.
newFile('/workspace/.dart_tool/build/generated/bar/lib/file.dart', '');
// Bar not in packages, file should not be returned.
expect(workspace.builtFile('lib/file.dart', 'bar'), isNull);
}
void test_find_directory() {
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
expect(workspace.isBlaze, isFalse);
expect(workspace.root, convertPath('/workspace'));
}
void test_find_fail_notAbsolute() {
expect(
() => PubWorkspace.find(
resourceProvider, Packages.empty, convertPath('not_absolute')),
throwsA(TypeMatcher<ArgumentError>()));
}
void test_find_file() {
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace =
_createWorkspace('/workspace/lib/lib1.dart', ['project']);
expect(workspace.root, convertPath('/workspace'));
}
void test_find_hasBuild_hasPubspec_malformed_dontGoToUp() {
newFolder('/workspace/.dart_tool/build/generated');
newPubspecYamlFile('/workspace', 'name: project');
newFolder('/workspace/aaa/.dart_tool/build/generated');
newPubspecYamlFile('/workspace/aaa', '*');
newPackageConfigJsonFile('/workspace/aaa', '');
PubWorkspace workspace = _createWorkspace('/workspace/aaa/lib', []);
expect(workspace, isNotNull);
expect(workspace.root, convertPath('/workspace/aaa'));
}
void test_find_hasDartToolAndPubspec() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', []);
expect(workspace.root, convertPath('/workspace'));
expect(workspace.projectPackageName, 'project');
}
void test_find_hasDartToolAndPubspec_inParentDirectory() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newFolder('/workspace/opened/up/a/child/dir/.dart_tool/build');
newPubspecYamlFile('/workspace/opened/up/a/child/dir', 'name: subproject');
newPackageConfigJsonFile('/workspace/opened/up/a/child/dir', '');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace =
_createWorkspace('/workspace/opened/up/a/child/dir', ['project']);
expect(workspace.root, convertPath('/workspace/opened/up/a/child/dir'));
expect(workspace.projectPackageName, 'subproject');
}
void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloDartTool() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newFolder('/workspace/opened/up/a/child/dir');
newFolder('/workspace/opened/up/a/child/dir/.dart_tool/build');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace =
_createWorkspace('/workspace/opened/up/a/child/dir', ['project']);
expect(workspace.root, convertPath('/workspace'));
expect(workspace.projectPackageName, 'project');
}
void test_find_hasDartToolNoBuild() {
// Edge case: an empty .dart_tool directory. Don't assume package:build.
newFolder('/workspace/.dart_tool');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
expect(workspace, isNotNull);
expect(workspace.usesPackageBuild, isFalse);
}
void test_find_hasDartToolNoPubspec() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
var workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace, isNull);
}
void test_find_hasDartToolPubButNotBuild() {
// Dart projects will have this directory, that don't use package:build.
newFolder('/workspace/.dart_tool/pub');
newPubspecYamlFile('/workspace', 'name: project');
var workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace!.root, convertPath('/workspace'));
expect(workspace.usesPackageBuild, isFalse);
}
void test_find_hasMalformedPubspec() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newPubspecYamlFile('/workspace', 'not: yaml: here! 1111');
var workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace?.root, convertPath('/workspace'));
}
void test_find_hasPubspec_noDartTool_dontGoUp() {
newFolder('/workspace/.dart_tool/build/generated');
newPubspecYamlFile('/workspace', 'name: project');
newPubspecYamlFile('/workspace/aaa', '*');
var workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace/aaa/lib'),
);
expect(workspace?.root, convertPath('/workspace/aaa'));
expect(workspace?.usesPackageBuild, isFalse);
}
void test_find_hasPubspecNoDartTool() {
newPubspecYamlFile('/workspace', 'name: project');
var workspace = PubWorkspace.find(
resourceProvider,
Packages.empty,
convertPath('/workspace'),
);
expect(workspace?.root, convertPath('/workspace'));
expect(workspace?.usesPackageBuild, isFalse);
}
void test_find_missingPubspec() {
var workspace = PubWorkspace.find(resourceProvider, Packages.empty,
convertPath('/workspace/lib/lib1.dart'));
expect(workspace, isNull);
}
void test_findFile_bin() {
newFolder('/workspace/.dart_tool/build/generated/project/bin');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final binFile = newFile('/workspace/bin/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/bin/file.dart')), binFile);
}
void test_findFile_binGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/bin');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final binFile = newFile(
'/workspace/.dart_tool/build/generated/project/bin/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/bin/file.dart')), binFile);
}
void test_findFile_libGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/lib');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final libFile = newFile(
'/workspace/.dart_tool/build/generated/project/lib/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/lib/file.dart')), libFile);
}
void test_findFile_test() {
newFolder('/workspace/.dart_tool/build/generated/project/test');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final testFile = newFile('/workspace/test/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/test/file.dart')), testFile);
}
void test_findFile_testGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/test');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final testFile = newFile(
'/workspace/.dart_tool/build/generated/project/test/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/test/file.dart')), testFile);
}
void test_findFile_web() {
newFolder('/workspace/.dart_tool/build/generated/project/web');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final webFile = newFile('/workspace/web/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/web/file.dart')), webFile);
}
void test_findFile_webGenerated() {
newFolder('/workspace/.dart_tool/build/generated/project/web');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
final webFile = newFile(
'/workspace/.dart_tool/build/generated/project/web/file.dart', '');
expect(
workspace.findFile(convertPath('/workspace/web/file.dart')), webFile);
}
void test_isConsistentWithFileSystem() {
newFolder('/workspace/.dart_tool/build/generated/project/bin');
newPubspecYamlFile('/workspace', 'name: project');
PubWorkspace workspace = _createWorkspace('/workspace', ['project']);
expect(workspace.isConsistentWithFileSystem, isTrue);
newPubspecYamlFile('/workspace', 'name: my2');
expect(workspace.isConsistentWithFileSystem, isFalse);
}
PubWorkspace _createWorkspace(String root, List<String> packageNames) {
var packageMap = <String, Package>{};
for (var name in packageNames) {
packageMap[name] = Package(
name: name,
rootFolder: getFolder('/packages/$name'),
libFolder: getFolder('/packages/$name/lib'),
languageVersion: null,
);
}
return PubWorkspace.find(
resourceProvider,
Packages(packageMap),
convertPath(root),
)!;
}
}
class _MockSource implements Source {
final String path;

View file

@ -252,8 +252,9 @@ class Driver implements CommandLineStarter {
var contextRoot =
analysisDriver.currentSession.analysisContext.contextRoot;
var package = contextRoot.workspace.findPackageFor(file.path);
var sdkVersionConstraint =
(package is PubPackage) ? package.sdkVersionConstraint : null;
var sdkVersionConstraint = (package is PubWorkspacePackage)
? package.sdkVersionConstraint
: null;
var errors = analyzeAnalysisOptions(
file.createSource(),
content,

View file

@ -34,7 +34,7 @@ export 'package:analyzer/src/lint/linter.dart'
export 'package:analyzer/src/lint/pub.dart' show PSEntry, PubspecVisitor;
export 'package:analyzer/src/lint/util.dart' show FileSpelunker;
export 'package:analyzer/src/services/lint.dart' show lintRegistry;
export 'package:analyzer/src/workspace/pub.dart' show PubPackage;
export 'package:analyzer/src/workspace/pub.dart' show PubWorkspacePackage;
const loggedAnalyzerErrorExitCode = 63;

View file

@ -65,7 +65,7 @@ class DependOnReferencedPackages extends LintRule {
NodeLintRegistry registry, LinterContext context) {
// Only lint if we have a pubspec.
var package = context.package;
if (package is! PubPackage) return;
if (package is! PubWorkspacePackage) return;
var pubspec = package.pubspec;
if (pubspec == null) return;
var name = pubspec.name?.value.text;