Reland Workspace changes.

Fix lints that were showing up in flutter code.

Change-Id: Id5e2cbae347fd2c5d73418ce5af6ce579b62e1a0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349629
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
This commit is contained in:
Keerti Parthasarathy 2024-02-05 17:33:09 +00:00 committed by Commit Queue
parent 43a60fe0a1
commit 11e4f4574f
29 changed files with 969 additions and 841 deletions

View file

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

View file

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

View file

@ -285,6 +285,7 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
@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/test.dart');
final projectTestFile = convertPath('/foo/lib/test.dart');
final projectPackageConfigFile =
convertPath('/foo/.dart_tool/package_config.json');

View file

@ -98,6 +98,9 @@ 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
@ -121,9 +124,13 @@ 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
@ -141,6 +148,9 @@ AnalysisErrors
// a.dart was analyzed
assertNotificationsText(r'''
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -158,9 +168,13 @@ 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
@ -182,6 +196,9 @@ 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
@ -215,6 +232,9 @@ AnalysisErrors
AnalysisErrors
file: /home/test/analysis_options.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
_createFilesWithErrors([
@ -248,6 +268,9 @@ 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
@ -291,6 +314,9 @@ 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
@ -324,6 +350,9 @@ 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
@ -360,6 +389,9 @@ 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
@ -404,6 +436,9 @@ 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
@ -425,9 +460,13 @@ 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
@ -452,6 +491,9 @@ 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
@ -471,6 +513,7 @@ 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
@ -497,6 +540,9 @@ 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
@ -535,6 +581,9 @@ 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
@ -560,9 +609,13 @@ 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
@ -596,6 +649,9 @@ 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
@ -638,6 +694,9 @@ 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
@ -685,6 +744,9 @@ 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
@ -734,6 +796,9 @@ 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
@ -772,6 +837,9 @@ 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
@ -817,6 +885,9 @@ 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
@ -861,6 +932,9 @@ 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
@ -912,6 +986,9 @@ 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
@ -932,9 +1009,13 @@ 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
@ -963,6 +1044,9 @@ 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
@ -979,6 +1063,10 @@ 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
@ -1013,6 +1101,9 @@ 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
@ -1047,6 +1138,9 @@ 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
@ -1118,6 +1212,9 @@ 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
@ -1163,6 +1260,9 @@ 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
@ -1200,6 +1300,9 @@ 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
@ -1243,6 +1346,9 @@ 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
@ -1262,9 +1368,13 @@ 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
@ -1288,6 +1398,9 @@ 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
@ -1356,6 +1469,9 @@ 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
@ -1512,6 +1628,9 @@ 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
@ -1573,6 +1692,9 @@ 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
@ -1612,6 +1734,9 @@ 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
@ -1660,6 +1785,9 @@ analyzer:
await server.onAnalysisComplete;
assertNotificationsText(r'''
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
AnalysisErrors
file: /home/test/lib/a.dart
errors: notEmpty
@ -1689,6 +1817,9 @@ AnalysisErrors
AnalysisErrors
file: /home/test/AndroidManifest.xml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1707,6 +1838,9 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: notEmpty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1723,6 +1857,9 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1739,6 +1876,9 @@ AnalysisErrors
AnalysisErrors
file: /home/test/lib/fix_data.yaml
errors: empty
AnalysisErrors
file: /home/test/pubspec.yaml
errors: empty
''');
}
@ -1803,6 +1943,9 @@ 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
@ -1820,6 +1963,9 @@ 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
@ -1859,6 +2005,9 @@ 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);
newPubspecYamlFile(workspaceFolder1Path, '');
newPubspecYamlFile(workspaceFolder2Path, '');
newPubspecYamlFile(workspaceFolder3Path, '');
newPackageConfigJsonFile(workspaceFolder1Path, '');
newPackageConfigJsonFile(workspaceFolder2Path, '');
newPackageConfigJsonFile(workspaceFolder3Path, '');
nonFileWorkspaceFolderUri = Uri.parse('dart-foo:/foo.dart');
}
@ -261,11 +261,12 @@ class ChangeWorkspaceFoldersTest extends AbstractLspAnalysisServerTest {
final nestedFileUri = pathContext.toUri(nestedFilePath);
newFile(nestedFilePath, '');
// Ensure no pubspecs in tree.
// Ensure no package config in tree.
deleteFile(
join(
workspaceFolder1Path,
file_paths.pubspecYaml,
file_paths.dotDartTool,
file_paths.packageConfigJson,
),
);

View file

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

View file

@ -199,25 +199,26 @@ class ContextLocatorImpl implements ContextLocator {
Folder? packagesFolderToChooseRoot;
if (defaultPackagesFile != null) {
packagesFile = defaultPackagesFile;
} else {
var foundPackages = _findPackagesFile(parent);
packagesFile = foundPackages?.file;
packagesFolderToChooseRoot = foundPackages?.parent;
// 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;
}
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,
@ -225,6 +226,17 @@ 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) {
@ -422,8 +434,8 @@ class ContextLocatorImpl implements ContextLocator {
Workspace? workspace;
workspace = BlazeWorkspace.find(resourceProvider, rootPath,
lookForBuildFileSubstitutes: false);
workspace = _mostSpecificWorkspace(
workspace, PubWorkspace.find(resourceProvider, packages, rootPath));
workspace = _mostSpecificWorkspace(workspace,
PackageConfigWorkspace.find(resourceProvider, packages, rootPath));
workspace ??= BasicWorkspace.find(resourceProvider, packages, rootPath);
return workspace;
}

View file

@ -56,6 +56,7 @@ 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.
@ -1806,6 +1807,10 @@ 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.addUint32List(library.file.analysisOptions.signature);

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 PubWorkspacePackage) {
if (workspacePackage is PubPackage) {
return _PubFilter(workspacePackage, file.path);
} else {
return _AnyFilter();
@ -57,13 +57,13 @@ class _AnyFilter implements FileStateFilter {
}
class _PubFilter implements FileStateFilter {
final PubWorkspacePackage targetPackage;
final PubPackage targetPackage;
final String? targetPackageName;
final bool targetPackageIsAnalysisServer;
final bool targetInLib;
final Set<String> dependencies;
factory _PubFilter(PubWorkspacePackage package, String path) {
factory _PubFilter(PubPackage 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 PubWorkspacePackage &&
return filePackage is PubPackage &&
filePackage.root == targetPackage.root;
}
}

View file

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

View file

@ -63,10 +63,13 @@ class BasicWorkspacePackage extends WorkspacePackage {
final String root;
@override
final BasicWorkspace workspace;
final SimpleWorkspace workspace;
BasicWorkspacePackage(this.root, this.workspace);
@override
bool get canHavePublicApi => false;
@override
bool contains(Source source) {
// When dealing with a BasicWorkspace, [source] will always have a valid

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,26 +37,29 @@ 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 PackageBuildFileUriResolver extends ResourceUriResolver {
final PubWorkspace workspace;
class PackageConfigFileUriResolver extends ResourceUriResolver {
final PackageConfigWorkspace workspace;
PackageBuildFileUriResolver(this.workspace) : super(workspace.provider);
PackageConfigFileUriResolver(this.workspace) : super(workspace.provider);
@override
Uri pathToUri(String path) {
var pathContext = workspace.provider.pathContext;
if (pathContext.isWithin(workspace.root, path)) {
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);
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);
}
}
}
@ -83,13 +86,13 @@ class PackageBuildFileUriResolver extends ResourceUriResolver {
/// The [UriResolver] that can resolve `package` URIs in
/// [PackageBuildWorkspace].
class PackageBuildPackageUriResolver extends UriResolver {
final PubWorkspace _workspace;
class PackageConfigPackageUriResolver extends UriResolver {
final PackageConfigWorkspace _workspace;
final UriResolver _normalUriResolver;
final Context _context;
PackageBuildPackageUriResolver(
PubWorkspace workspace, this._normalUriResolver)
PackageConfigPackageUriResolver(
PackageConfigWorkspace workspace, this._normalUriResolver)
: _workspace = workspace,
_context = workspace.provider.pathContext;
@ -154,118 +157,53 @@ class PackageBuildPackageUriResolver extends UriResolver {
}
}
/// 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';
/// Information about a Package Config workspace.
class PackageConfigWorkspace extends SimpleWorkspace {
/// The associated package config file.
final File packageConfigFile;
/// The name of the subdirectory in [_dartToolRootName] that distinguishes
/// projects built with package:build.
static const String _dartToolBuildName = 'build';
/// The contents of the package config file.
late final String? _packageConfigContent;
static const List<String> _generatedPathParts = [
'.dart_tool',
'build',
'generated'
];
final Map<String, WorkspacePackage> _workspacePackages = {};
/// 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,
factory PackageConfigWorkspace(
ResourceProvider provider, //Packages packages,
String root,
this._pubspecFile,
this._pubspecContent,
this._generatedRootPath,
this._generatedThisPath,
this.projectPackageName,
this.usesPackageBuild)
: super(provider, packages, root) {
_theOnlyPackage = PubWorkspacePackage(root, this);
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,
);
}
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(_pubspecFile) == _pubspecContent;
return _fileContentOrNull(packageConfigFile) == _packageConfigContent;
}
@override
UriResolver get packageUriResolver {
if (usesPackageBuild) {
return PackageBuildPackageUriResolver(
this, PackageMapUriResolver(provider, packageMap));
}
return PackageMapUriResolver(provider, packageMap);
return PackageConfigPackageUriResolver(
this, 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.
@ -292,7 +230,7 @@ class PubWorkspace extends SimpleWorkspace {
@internal
@override
void contributeToResolutionSalt(ApiSignature buffer) {
buffer.addString(_pubspecContent ?? '');
buffer.addString(_packageConfigContent ?? '');
}
@override
@ -300,18 +238,15 @@ class PubWorkspace 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));
}
resolvers.add(packageUriResolver);
if (usesPackageBuild) {
resolvers.add(PackageBuildFileUriResolver(this));
if (summaryData != null) {
resolvers.add(InSummaryUriResolver(summaryData));
}
resolvers.add(packageUriResolver);
resolvers.add(PackageConfigFileUriResolver(this));
resolvers.add(ResourceUriResolver(provider));
return SourceFactory(resolvers);
}
@ -326,10 +261,13 @@ class PubWorkspace extends SimpleWorkspace {
var context = provider.pathContext;
assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
try {
final relativePath = context.relative(filePath, from: root);
final file = builtFile(relativePath, projectPackageName);
if (file!.exists) {
return file;
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;
}
}
return provider.getFile(filePath);
} catch (_) {
@ -337,26 +275,50 @@ class PubWorkspace extends SimpleWorkspace {
}
}
/// Find the [PubWorkspacePackage] that contains the given file path. The path
/// Find the [PubPackage] 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
PubWorkspacePackage? findPackageFor(String filePath) {
WorkspacePackage? findPackageFor(String filePath) {
var pathContext = provider.pathContext;
// Must be in this workspace.
if (!pathContext.isWithin(root, filePath)) {
return null;
}
if (usesPackageBuild) {
// If generated, must be for this package.
if (pathContext.isWithin(_generatedRootPath!, filePath)) {
if (!pathContext.isWithin(_generatedThisPath!, filePath)) {
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)) {
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 _theOnlyPackage;
return null;
}
/// Unlike the way that sources are resolved against `.packages` (if foo
@ -370,23 +332,22 @@ class PubWorkspace extends SimpleWorkspace {
return context.join('lib', filePath);
}
/// 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(
/// Find the package config workspace that contains the given [filePath].
/// A [PackageConfigWorkspace] is rooted at the innermost package-config file.
static PackageConfigWorkspace? find(
ResourceProvider provider,
Packages packages,
String filePath,
) {
var start = provider.getFolder(filePath);
for (var current in start.withAncestors) {
var pubspec = current.getChildAssumingFile(file_paths.pubspecYaml);
if (pubspec.exists) {
if (_isInThirdPartyDart(pubspec)) {
return null;
}
var packageConfigFile = current
.getChildAssumingFolder(file_paths.dotDartTool)
.getChildAssumingFile(file_paths.packageConfigJson);
if (packageConfigFile.exists) {
var root = current.path;
return PubWorkspace(provider, packages, root, pubspec);
return PackageConfigWorkspace(
provider, root, packageConfigFile, packages);
}
}
return null;
@ -415,12 +376,12 @@ class PubWorkspace extends SimpleWorkspace {
}
}
/// Information about a package defined in a [PubWorkspace].
/// Information about a package defined in a [PackageConfigWorkspace].
///
/// 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 [PubWorkspace].
class PubWorkspacePackage extends WorkspacePackage {
/// a given package in a [PackageConfigWorkspace].
class PubPackage extends WorkspacePackage {
static const List<String> _generatedPathParts = [
file_paths.dotDartTool,
file_paths.packageBuild,
@ -430,10 +391,11 @@ class PubWorkspacePackage extends WorkspacePackage {
@override
final String root;
Pubspec? _pubspec;
final String? _name;
/// A flag to indicate if we've tried to parse the pubspec.
bool _parsedPubspec = false;
final String? _pubspecContent;
final Pubspec? _pubspec;
VersionConstraint? _sdkVersionConstraint;
@ -441,30 +403,30 @@ class PubWorkspacePackage extends WorkspacePackage {
bool _parsedSdkConstraint = false;
@override
final PubWorkspace workspace;
final PackageConfigWorkspace workspace;
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;
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);
}
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);
@ -484,7 +446,7 @@ class PubWorkspacePackage 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 == workspace.projectPackageName;
return packageName == _name;
}
if (uri.isScheme('file')) {

View file

@ -59,6 +59,10 @@ abstract class Workspace {
/// understand whether arbitrary file paths represent libraries declared within
/// a given package in a Workspace.
abstract class WorkspacePackage {
/// Return `true` if this package can have public apis, that is, the package
/// has marker files like pubspec.yaml or BUILD.
bool get canHavePublicApi => true;
/// Return the experiments enabled for all files in the package.
///
/// Return `null` if this package does not have enabled experiments.

View file

@ -271,31 +271,23 @@ class AnalysisContextCollectionTest with ResourceProviderMixin {
test_basicWorkspace() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
newSinglePackageConfigJsonFile(
packagePath: testPackageRootPath,
name: 'test',
);
newFile('$testPackageRootPath/lib/a.dart', '');
_assertWorkspaceCollectionText(workspaceRootPath, r'''
contexts
/home/test
packagesFile: /home/test/.dart_tool/package_config.json
/home
workspace: workspace_0
analyzedFiles
/home/test/lib/a.dart
uri: package:test/a.dart
workspacePackage_0_0
workspaces
workspace_0: BasicWorkspace
root: /home/test
root: /home
workspacePackage_0_0
''');
}
test_pubWorkspace_multipleAnalysisOptions() async {
test_packageConfigWorkspace_multipleAnalysisOptions() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -334,15 +326,15 @@ analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
analysisOptions_1: /home/test/lib/nested/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
''');
}
test_pubWorkspace_multipleAnalysisOptions_overridingOptions() async {
test_packageConfigWorkspace_multipleAnalysisOptions_overridingOptions() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -385,15 +377,15 @@ contexts
analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
''');
}
test_pubWorkspace_multipleAnalysisOptions_overridingOptions_outsideWorspaceRoot() async {
test_packageConfigWorkspace_multipleAnalysisOptions_overridingOptions_outsideWorspaceRoot() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -438,15 +430,15 @@ contexts
analysisOptions
analysisOptions_0: /outside/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
''');
}
test_pubWorkspace_multiplePackageConfigs() async {
test_packageConfigWorkspace_multiplePackageConfigs() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -489,20 +481,20 @@ contexts
uri: package:nested/b.dart
workspacePackage_1_0
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
workspace_1: PubWorkspace
workspace_1: PackageConfigWorkspace
root: /home/test/nested
pubPackages
workspacePackage_1_0: PubWorkspacePackage
workspacePackage_1_0: PubPackage
root: /home/test/nested
''');
}
test_pubWorkspace_sdkVersionConstraint() async {
test_packageConfigWorkspace_sdkVersionConstraint() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
@ -528,16 +520,16 @@ contexts
uri: package:test/a.dart
workspacePackage_0_0
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
sdkVersionConstraint: ^3.0.0
''');
}
test_pubWorkspace_singleAnalysisOptions() async {
test_packageConfigWorkspace_singleAnalysisOptions() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -568,15 +560,15 @@ contexts
analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
''');
}
test_pubWorkspace_singleAnalysisOptions_multipleContexts() async {
test_packageConfigWorkspace_singleAnalysisOptions_multipleContexts() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -625,15 +617,15 @@ contexts
analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
workspace_1: PubWorkspace
workspace_1: PackageConfigWorkspace
root: /home/test/nested
pubPackages
workspacePackage_1_0: PubWorkspacePackage
workspacePackage_1_0: PubPackage
root: /home/test/nested
''');
}
@ -694,7 +686,7 @@ class AnalysisContextCollectionTest_SingleOptionsPerContext
bool get enableSingleOptionContexts => true;
@override
test_pubWorkspace_multipleAnalysisOptions() async {
test_packageConfigWorkspace_multipleAnalysisOptions() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -737,21 +729,21 @@ analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
analysisOptions_1: /home/test/lib/nested/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
workspace_1: PubWorkspace
workspace_1: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_1_0: PubWorkspacePackage
workspacePackage_1_0: PubPackage
root: /home/test
''');
}
@override
test_pubWorkspace_multipleAnalysisOptions_overridingOptions() async {
test_packageConfigWorkspace_multipleAnalysisOptions_overridingOptions() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -794,16 +786,16 @@ contexts
analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
''');
}
@override
test_pubWorkspace_singleAnalysisOptions_multipleContexts() async {
test_packageConfigWorkspace_singleAnalysisOptions_multipleContexts() async {
final workspaceRootPath = '/home';
final testPackageRootPath = '$workspaceRootPath/test';
final testPackageLibPath = '$testPackageRootPath/lib';
@ -854,15 +846,15 @@ analysisOptions
analysisOptions_0: /home/test/analysis_options.yaml
analysisOptions_1: /home/test/analysis_options.yaml
workspaces
workspace_0: PubWorkspace
workspace_0: PackageConfigWorkspace
root: /home/test
pubPackages
workspacePackage_0_0: PubWorkspacePackage
workspacePackage_0_0: PubPackage
root: /home/test
workspace_1: PubWorkspace
workspace_1: PackageConfigWorkspace
root: /home/test/nested
pubPackages
workspacePackage_1_0: PubWorkspacePackage
workspacePackage_1_0: PubPackage
root: /home/test/nested
''');
}
@ -979,7 +971,11 @@ class _AnalysisContextCollectionPrinter {
sink.writelnWithIndent(file.posixPath);
sink.withIndent(() {
final fileState = fsState.getFileForPath(file.path);
sink.writelnWithIndent('uri: ${fileState.uri}');
var uri = fileState.uri;
// If file uri, don't print it out, causes test failure on Windows.
if (uri.scheme != 'file') {
sink.writelnWithIndent('uri: $uri');
}
final analysisOptions = fileState.analysisOptions;
if (analysisOptions.file != null) {
@ -1013,14 +1009,14 @@ class _AnalysisContextCollectionPrinter {
_idOfWorkspacePackage(workspace.theOnlyPackage),
);
});
case PubWorkspace():
sink.writelnWithIndent('$id: PubWorkspace');
case PackageConfigWorkspace():
sink.writelnWithIndent('$id: PackageConfigWorkspace');
sink.withIndent(() {
final root = resourceProvider.getFolder(workspace.root);
sink.writelnWithIndent('root: ${root.posixPath}');
sink.writeElements(
'pubPackages',
workspace.pubPackages.toList(),
workspace.allPackages.toList(),
_writeWorkspacePackage,
);
});
@ -1039,8 +1035,8 @@ class _AnalysisContextCollectionPrinter {
final root = resourceProvider.getFolder(package.root);
sink.writelnWithIndent('root: ${root.posixPath}');
});
case PubWorkspacePackage():
sink.writelnWithIndent('$id: PubWorkspacePackage');
case PubPackage():
sink.writelnWithIndent('$id: PubPackage');
sink.withIndent(() {
final root = resourceProvider.getFolder(package.root);
sink.writelnWithIndent('root: ${root.posixPath}');

View file

@ -20,7 +20,6 @@ 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';
@ -144,6 +143,24 @@ 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}', '');
@ -163,23 +180,6 @@ 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

@ -664,7 +664,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
/// the don't look into containing directories, so the context root can be
/// and don't look into containing directories, so the context root can be
/// just the file system root.
void
test_locateRoots_multiple_fileAndSiblingFile_hasPackages_overridePackages() {
@ -679,7 +679,7 @@ analyzer:
);
expect(roots, hasLength(1));
ContextRoot root = findRoot(roots, getFolder('/'));
ContextRoot root = findRoot(roots, getFolder('/home'));
expect(
root.includedPaths, unorderedEquals([testFile1.path, testFile2.path]));
expect(root.excludedPaths, isEmpty);
@ -772,13 +772,13 @@ analyzer:
_assertAnalyzedFiles2(root, [fooFile, barFile]);
}
void test_locateRoots_multiple_files_differentWorkspaces_pub() {
void test_locateRoots_multiple_files_differentWorkspaces_packageConfig() {
var rootPath = '/home';
var fooPath = '$rootPath/foo';
var barPath = '$rootPath/bar';
newPubspecYamlFile(fooPath, '');
newPubspecYamlFile(barPath, '');
newPackageConfigJsonFile(fooPath, '');
newPackageConfigJsonFile(barPath, '');
var fooFile = newFile('$fooPath/lib/foo.dart', '');
var barFile = newFile('$barPath/lib/bar.dart', '');
@ -792,7 +792,7 @@ analyzer:
expect(fooRoot.includedPaths, unorderedEquals([fooFile.path]));
expect(fooRoot.excludedPaths, isEmpty);
expect(fooRoot.optionsFile, isNull);
expect(fooRoot.packagesFile, isNull);
expect(fooRoot.packagesFile, isNotNull);
_assertPubWorkspace(fooRoot.workspace, fooPath);
_assertAnalyzedFiles2(fooRoot, [fooFile]);
@ -800,7 +800,7 @@ analyzer:
expect(barRoot.includedPaths, unorderedEquals([barFile.path]));
expect(barRoot.excludedPaths, isEmpty);
expect(barRoot.optionsFile, isNull);
expect(barRoot.packagesFile, isNull);
expect(barRoot.packagesFile, isNotNull);
_assertPubWorkspace(barRoot.workspace, barPath);
_assertAnalyzedFiles2(barRoot, [barFile]);
}
@ -1731,7 +1731,6 @@ ${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);
@ -1811,7 +1810,7 @@ ${getFolder(outPath).path}
}
void _assertPubWorkspace(Workspace workspace, String posixRoot) {
workspace as PubWorkspace;
workspace as PackageConfigWorkspace;
var root = convertPath(posixRoot);
expect(workspace.root, root);
}

View file

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

View file

@ -11,7 +11,7 @@ import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DeprecatedMemberUse_BasicWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_PackageConfigWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_BlazeWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_GnWorkspaceTest);
defineReflectiveTests(DeprecatedMemberUse_PackageBuildWorkspaceTest);
@ -19,7 +19,173 @@ main() {
}
@reflectiveTest
class DeprecatedMemberUse_BasicWorkspaceTest extends PubPackageResolutionTest {
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 {
String get externalLibPath => '$workspaceRootPath/aaa/lib/a.dart';
String get externalLibUri => 'package:aaa/a.dart';
@ -1862,176 +2028,11 @@ void f() {
@override
void verifyCreatedCollection() {
super.verifyCreatedCollection();
assertBasicWorkspaceFor(testFile);
assertPackageConfigWorkspaceFor(testFile);
}
}
@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 {
class _PackageConfigWorkspaceBase extends PubPackageResolutionTest {
String get testPackageGeneratedPath {
return '$testPackageRootPath/.dart_tool/build/generated';
}
@ -2039,7 +2040,7 @@ class _PackageBuildWorkspaceBase extends PubPackageResolutionTest {
@override
void verifyCreatedCollection() {
super.verifyCreatedCollection();
assertPackageBuildWorkspaceFor(testFile);
assertPackageConfigWorkspaceFor(testFile);
}
void _createTestPackageBuildMarker() {

View file

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

View file

@ -7,17 +7,20 @@ 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(PubWorkspacePackageTest);
defineReflectiveTests(PubWorkspaceTest);
defineReflectiveTests(PubPackageTest);
defineReflectiveTests(PackageConfigWorkspaceTest);
defineReflectiveTests(PackageBuildFileUriResolverTest);
defineReflectiveTests(PackageBuildPackageUriResolverTest);
});
@ -48,8 +51,8 @@ class MockUriResolver implements UriResolver {
@reflectiveTest
class PackageBuildFileUriResolverTest with ResourceProviderMixin {
late final PubWorkspace workspace;
late final PackageBuildFileUriResolver resolver;
late final PackageConfigWorkspace workspace;
late final PackageConfigFileUriResolver resolver;
File get testFile => getFile('$testPackageLibPath/test.dart');
@ -67,20 +70,17 @@ 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 = PubWorkspace.find(
workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages({
'test': Package(
name: 'test',
rootFolder: getFolder(testPackageRootPath),
libFolder: getFolder(testPackageLibPath),
languageVersion: null,
),
}),
Packages.empty,
convertPath(testPackageRootPath),
)!;
resolver = PackageBuildFileUriResolver(workspace);
resolver = PackageConfigFileUriResolver(workspace);
expect(workspace.isBlaze, isFalse);
}
@ -146,8 +146,8 @@ class PackageBuildFileUriResolverTest with ResourceProviderMixin {
@reflectiveTest
class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
late final PubWorkspace workspace;
late final PackageBuildPackageUriResolver resolver;
late final PackageConfigWorkspace workspace;
late final PackageConfigPackageUriResolver resolver;
late final MockUriResolver packageUriResolver;
Uri addPackageSource(String path, String uriStr, {bool create = true}) {
@ -161,6 +161,7 @@ class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
void setUp() {
newPubspecYamlFile('/workspace', 'name: project');
newPackageConfigJsonFile('/workspace', '');
}
void test_resolveAbsolute_generated() {
@ -221,20 +222,17 @@ class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
newFile(path, '');
}
}
workspace = PubWorkspace.find(
var config = PackageConfigFileBuilder();
config.add(name: 'project', rootPath: '/workspace');
newPackageConfigJsonFile(
workspacePath, config.toContent(toUriStr: toUriStr));
workspace = PackageConfigWorkspace.find(
resourceProvider,
Packages({
'project': Package(
name: 'project',
rootFolder: getFolder('/workspace'),
libFolder: getFolder('/workspace'),
languageVersion: null,
),
}),
Packages.empty,
convertPath(workspacePath),
)!;
packageUriResolver = MockUriResolver();
resolver = PackageBuildPackageUriResolver(workspace, packageUriResolver);
resolver = PackageConfigPackageUriResolver(workspace, packageUriResolver);
}
Source _assertResolveUri(
@ -253,9 +251,286 @@ class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
}
@reflectiveTest
class PubWorkspacePackageTest extends WorkspacePackageTest {
late final PubWorkspace myWorkspace;
late final PubWorkspacePackage myPackage;
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;
String get fooPackageLibPath => '$fooPackageRootPath/lib';
@ -278,45 +553,29 @@ class PubWorkspacePackageTest extends WorkspacePackageTest {
// workspace 1 with packages 'p1' and 'workspace'
newPubspecYamlFile('/workspace', 'name: project');
workspace = PubWorkspace.find(
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(
resourceProvider,
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,
),
}),
Packages.empty,
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 = PubWorkspace.find(
myWorkspace = PackageConfigWorkspace.find(
resourceProvider,
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,
),
}),
Packages.empty,
convertPath(myPackageRootPath),
)!;
final fakeFile = getFile('$myPackageLibPath/fake.dart');
@ -349,28 +608,6 @@ class PubWorkspacePackageTest 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(
@ -435,22 +672,6 @@ class PubWorkspacePackageTest 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'),
@ -525,288 +746,6 @@ class PubWorkspacePackageTest 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,9 +252,8 @@ class Driver implements CommandLineStarter {
var contextRoot =
analysisDriver.currentSession.analysisContext.contextRoot;
var package = contextRoot.workspace.findPackageFor(file.path);
var sdkVersionConstraint = (package is PubWorkspacePackage)
? package.sdkVersionConstraint
: null;
var sdkVersionConstraint =
(package is PubPackage) ? 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 PubWorkspacePackage;
export 'package:analyzer/src/workspace/pub.dart' show PubPackage;
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! PubWorkspacePackage) return;
if (package is! PubPackage) return;
var pubspec = package.pubspec;
if (pubspec == null) return;
var name = pubspec.name?.value.text;

View file

@ -83,6 +83,10 @@ class PublicMemberApiDocs extends LintRule {
@override
void registerNodeProcessors(
NodeLintRegistry registry, LinterContext context) {
var package = context.package;
if (package != null && !package.canHavePublicApi) {
return;
}
if (!isInLibDir(context.currentUnit.unit, context.package)) {
return;
}

View file

@ -176,6 +176,8 @@ class PubPackageResolutionTest extends _ContextResolutionTest {
List<String> get experiments => ['macros'];
List<String> get lintRules => _lintRules;
/// The path that is not in [workspaceRootPath], contains external packages.
String get packagesRootPath => '/packages';
@ -315,6 +317,16 @@ class PubPackageResolutionTest extends _ContextResolutionTest {
}
}
/// Assert that the number of diagnostics that have been gathered matches the
/// number of [expectedDiagnostics] and that they have the expected error
/// descriptions and locations. The order in which the diagnostics were
/// gathered is ignored.
Future<void> assertDiagnosticsInFile(
String path, List<ExpectedDiagnostic> expectedDiagnostics) async {
await _resolveFile(path);
await assertDiagnosticsIn(errors, expectedDiagnostics);
}
/// Assert that there are no diagnostics in the given [code].
Future<void> assertNoDiagnostics(String code) async =>
assertDiagnostics(code, const []);
@ -323,6 +335,10 @@ class PubPackageResolutionTest extends _ContextResolutionTest {
Future<void> assertNoDiagnosticsIn(List<AnalysisError> errors) =>
assertDiagnosticsIn(errors, const []);
/// Assert that there are no diagnostics in the given file.
Future<void> assertNoDiagnosticsInFile(String path) async =>
assertDiagnosticsInFile(path, const []);
/// Assert that no diagnostics are reported when resolving [content].
Future<void> assertNoPubspecDiagnostics(String content) async {
newFile(testPackagePubspecPath, content);
@ -361,6 +377,7 @@ class PubPackageResolutionTest extends _ContextResolutionTest {
writeTestPackageConfig(
PackageConfigFileBuilder(),
);
writeTestPackagePubspecYamlFile(PubspecYamlFileConfig(name: 'test'));
}
void writePackageConfig(String path, PackageConfigFileBuilder config) {

View file

@ -11,6 +11,7 @@ main() {
defineReflectiveTests(PublicMemberApiDocsTest);
defineReflectiveTests(PublicMemberApiDocsTestDirTest);
defineReflectiveTests(PublicMemberApiDocsExtensionTypesTest);
defineReflectiveTests(PublicMemberApiDocsTestPackageTest);
});
}
@ -366,3 +367,46 @@ typedef T = void Function();
''');
}
}
@reflectiveTest
class PublicMemberApiDocsTestPackageTest extends LintRuleTest {
String get filePath => '$fixturePackageLibPath/a.dart';
String get fixturePackageLibPath => '$myPackageRootPath/test/fixture/lib';
@override
String get lintRule => 'public_member_api_docs';
String get myPackageRootPath => '$workspaceRootPath/myPackage';
@override
void setUp() {
super.setUp();
writePackageConfig(
'$myPackageRootPath/.dart_tool/package_config.json',
PackageConfigFileBuilder(),
);
newPubspecYamlFile(myPackageRootPath,
PubspecYamlFileConfig(name: 'myPackage').toContent());
newAnalysisOptionsYamlFile(
myPackageRootPath,
AnalysisOptionsFileConfig(
experiments: experiments,
lints: lintRules,
propagateLinterExceptions: true,
).toContent(),
);
newFolder(fixturePackageLibPath);
writePackageConfig(
'$myPackageRootPath/test/fixture/.dart_tool/package_config.json',
PackageConfigFileBuilder()..add(name: 'fixture', rootPath: '../lib'));
}
test_inTestLibDir() async {
newFile(filePath, '''
String? b;
typedef T = void Function();
''');
await assertNoDiagnosticsInFile(filePath);
}
}