diff --git a/CHANGELOG.md b/CHANGELOG.md index 1422dd87bc..53dcfbcfcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +* fix: use empty analysis options exclude to properly resolve units and speed up commands analysis. + ## 4.18.1 * fix: fix regression in is! checks for [`avoid-unnecessary-type-assertions`](https://dartcodemetrics.dev/docs/rules/common/avoid-unnecessary-type-assertions). diff --git a/lib/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analyzer.dart b/lib/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analyzer.dart index f499895449..63ba122bbc 100644 --- a/lib/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analyzer.dart +++ b/lib/src/analyzers/unnecessary_nullable_analyzer/unnecessary_nullable_analyzer.dart @@ -4,7 +4,6 @@ import 'dart:io'; import 'package:analyzer/dart/analysis/analysis_context.dart'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; @@ -84,19 +83,9 @@ class UnnecessaryNullableAnalyzer { invocationsUsages.merge(invocationsUsage); } - declarationsUsages[filePath] = _analyzeDeclarationsUsage(unit); - } - - final notAnalyzedFiles = filePaths.difference(analyzedFiles); - for (final filePath in notAnalyzedFiles) { - if (unnecessaryNullableAnalysisConfig.analyzerExcludedPatterns + if (!unnecessaryNullableAnalysisConfig.analyzerExcludedPatterns .any((pattern) => pattern.matches(filePath))) { - final unit = await resolveFile2(path: filePath); - - final invocationsUsage = _analyzeInvocationsUsage(unit); - if (invocationsUsage != null) { - invocationsUsages.merge(invocationsUsage); - } + declarationsUsages[filePath] = _analyzeDeclarationsUsage(unit); } } } diff --git a/lib/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart b/lib/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart index 4710c733b3..0aef291e57 100644 --- a/lib/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart +++ b/lib/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart @@ -2,7 +2,6 @@ import 'dart:io'; import 'package:analyzer/dart/analysis/analysis_context.dart'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/element/element.dart'; // ignore: implementation_imports import 'package:analyzer/src/dart/element/element.dart'; @@ -77,19 +76,9 @@ class UnusedCodeAnalyzer { codeUsages.merge(codeUsage); } - publicCode[filePath] = _analyzeFilePublicCode(unit); - } - - final notAnalyzedFiles = filePaths.difference(analyzedFiles); - for (final filePath in notAnalyzedFiles) { - if (unusedCodeAnalysisConfig.analyzerExcludedPatterns + if (!unusedCodeAnalysisConfig.analyzerExcludedPatterns .any((pattern) => pattern.matches(filePath))) { - final unit = await resolveFile2(path: filePath); - - final codeUsage = _analyzeFileCodeUsages(unit); - if (codeUsage != null) { - codeUsages.merge(codeUsage); - } + publicCode[filePath] = _analyzeFilePublicCode(unit); } } } diff --git a/lib/src/analyzers/unused_files_analyzer/unused_files_analysis_config.dart b/lib/src/analyzers/unused_files_analyzer/unused_files_analysis_config.dart index 556eafeeec..fbab4e7224 100644 --- a/lib/src/analyzers/unused_files_analyzer/unused_files_analysis_config.dart +++ b/lib/src/analyzers/unused_files_analyzer/unused_files_analysis_config.dart @@ -3,10 +3,6 @@ import 'package:glob/glob.dart'; /// Represents converted unused files config which contains parsed entities. class UnusedFilesAnalysisConfig { final Iterable globalExcludes; - final Iterable analyzerExcludedPatterns; - const UnusedFilesAnalysisConfig( - this.globalExcludes, - this.analyzerExcludedPatterns, - ); + const UnusedFilesAnalysisConfig(this.globalExcludes); } diff --git a/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart b/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart index 4be60efb98..a0fdf1806e 100644 --- a/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart +++ b/lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart @@ -2,7 +2,6 @@ import 'dart:io'; import 'package:analyzer/dart/analysis/analysis_context.dart'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:path/path.dart'; import '../../config_builder/config_builder.dart'; @@ -67,16 +66,6 @@ class UnusedFilesAnalyzer { final unit = await context.currentSession.getResolvedUnit(filePath); unusedFiles.removeAll(_analyzeFile(filePath, unit, config.isMonorepo)); } - - final notAnalyzedFiles = filePaths.difference(analyzedFiles); - for (final filePath in notAnalyzedFiles) { - if (unusedFilesAnalysisConfig.analyzerExcludedPatterns - .any((pattern) => pattern.matches(filePath))) { - final unit = await resolveFile2(path: filePath); - unusedFiles - .removeAll(_analyzeFile(filePath, unit, config.isMonorepo)); - } - } } return unusedFiles.map((path) { diff --git a/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analysis_config.dart b/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analysis_config.dart index 485b8f2a4b..fd2503d307 100644 --- a/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analysis_config.dart +++ b/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analysis_config.dart @@ -4,12 +4,10 @@ import 'package:glob/glob.dart'; /// which contains parsed entities. class UnusedL10nAnalysisConfig { final Iterable globalExcludes; - final Iterable analyzerExcludedPatterns; final RegExp classPattern; UnusedL10nAnalysisConfig( this.globalExcludes, - this.analyzerExcludedPatterns, String? classPattern, ) : classPattern = RegExp(classPattern ?? r'I18n$'); } diff --git a/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart b/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart index cf8ec299f4..20f981180b 100644 --- a/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart +++ b/lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart @@ -4,7 +4,6 @@ import 'dart:io'; import 'package:analyzer/dart/analysis/analysis_context.dart'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; // ignore: implementation_imports @@ -79,24 +78,6 @@ class UnusedL10nAnalyzer { ); }); } - - final notAnalyzedFiles = filePaths.difference(analyzedFiles); - - for (final filePath in notAnalyzedFiles) { - if (unusedLocalizationAnalysisConfig.analyzerExcludedPatterns - .any((pattern) => pattern.matches(filePath))) { - final unit = await resolveFile2(path: filePath); - - _analyzeFile(unit, unusedLocalizationAnalysisConfig.classPattern) - .forEach((classElement, usages) { - localizationUsages.update( - classElement, - (value) => value..addAll(usages), - ifAbsent: () => usages, - ); - }); - } - } } return _checkUnusedL10n(localizationUsages, rootFolder); diff --git a/lib/src/config_builder/config_builder.dart b/lib/src/config_builder/config_builder.dart index 92466dcabe..f295bf206b 100644 --- a/lib/src/config_builder/config_builder.dart +++ b/lib/src/config_builder/config_builder.dart @@ -90,7 +90,6 @@ class ConfigBuilder { ) => UnusedFilesAnalysisConfig( prepareExcludes(config.excludePatterns, rootPath), - prepareExcludes(config.analyzerExcludePatterns, rootPath), ); /// Creates a raw unused code config from given [excludePatterns]. @@ -136,7 +135,6 @@ class ConfigBuilder { ) => UnusedL10nAnalysisConfig( prepareExcludes(config.excludePatterns, rootPath), - prepareExcludes(config.analyzerExcludePatterns, rootPath), config.classPattern, ); diff --git a/lib/src/utils/analyzer_utils.dart b/lib/src/utils/analyzer_utils.dart index c22ad7fa96..8b8ee85272 100644 --- a/lib/src/utils/analyzer_utils.dart +++ b/lib/src/utils/analyzer_utils.dart @@ -3,6 +3,9 @@ import 'dart:io'; import 'package:analyzer/dart/analysis/analysis_context.dart'; import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; +import 'package:analyzer/dart/analysis/context_locator.dart'; +import 'package:analyzer/file_system/file_system.dart' hide File; +import 'package:analyzer/file_system/overlay_file_system.dart'; import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart'; import 'package:analyzer/src/dart/analysis/byte_store.dart'; @@ -18,12 +21,13 @@ AnalysisContextCollection createAnalysisContextCollection( String rootFolder, String? sdkPath, ) { - final resourceProvider = PhysicalResourceProvider.INSTANCE; + final includedPaths = + folders.map((path) => normalize(join(rootFolder, path))).toList(); + final resourceProvider = _prepareAnalysisOptions(includedPaths); return AnalysisContextCollectionImpl( sdkPath: sdkPath, - includedPaths: - folders.map((path) => normalize(join(rootFolder, path))).toList(), + includedPaths: includedPaths, resourceProvider: resourceProvider, byteStore: createByteStore(resourceProvider), ); @@ -48,7 +52,7 @@ Set getFilePaths( /// If the state location can be accessed, return the file byte store, /// otherwise return the memory byte store. -ByteStore createByteStore(PhysicalResourceProvider resourceProvider) { +ByteStore createByteStore(ResourceProvider resourceProvider) { const miB = 1024 * 1024 /*1 MiB*/; const giB = 1024 * 1024 * 1024 /*1 GiB*/; @@ -86,3 +90,25 @@ Set _extractDartFilesFromFolders( )) .map((entity) => normalize(entity.path))) .toSet(); + +ResourceProvider _prepareAnalysisOptions(List includedPaths) { + final resourceProvider = + OverlayResourceProvider(PhysicalResourceProvider.INSTANCE); + + final contextLocator = ContextLocator(resourceProvider: resourceProvider); + final roots = contextLocator + .locateRoots(includedPaths: includedPaths, excludedPaths: []); + + for (final root in roots) { + final path = root.optionsFile?.path; + if (path != null) { + resourceProvider.setOverlay( + path, + content: '', + modificationStamp: DateTime.now().millisecondsSinceEpoch, + ); + } + } + + return resourceProvider; +} diff --git a/test/src/analyzers/unused_code_analyzer/unused_code_analyzer_test.dart b/test/src/analyzers/unused_code_analyzer/unused_code_analyzer_test.dart index b4552f16d3..bf1fb71765 100644 --- a/test/src/analyzers/unused_code_analyzer/unused_code_analyzer_test.dart +++ b/test/src/analyzers/unused_code_analyzer/unused_code_analyzer_test.dart @@ -35,7 +35,7 @@ void main() { ); }); - test('should report 3 files and not report excluded file', () { + test('should report 4 files and not report excluded file', () { expect(result, hasLength(4)); });