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

fix: use empty analysis options exclude to properly resolve units and speed up commands analysis #998

Merged
merged 2 commits into from Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions 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).
Expand Down
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
15 changes: 2 additions & 13 deletions lib/src/analyzers/unused_code_analyzer/unused_code_analyzer.dart
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
Expand Up @@ -3,10 +3,6 @@ import 'package:glob/glob.dart';
/// Represents converted unused files config which contains parsed entities.
class UnusedFilesAnalysisConfig {
final Iterable<Glob> globalExcludes;
final Iterable<Glob> analyzerExcludedPatterns;

const UnusedFilesAnalysisConfig(
this.globalExcludes,
this.analyzerExcludedPatterns,
);
const UnusedFilesAnalysisConfig(this.globalExcludes);
}
11 changes: 0 additions & 11 deletions lib/src/analyzers/unused_files_analyzer/unused_files_analyzer.dart
Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand Down
Expand Up @@ -4,12 +4,10 @@ import 'package:glob/glob.dart';
/// which contains parsed entities.
class UnusedL10nAnalysisConfig {
final Iterable<Glob> globalExcludes;
final Iterable<Glob> analyzerExcludedPatterns;
final RegExp classPattern;

UnusedL10nAnalysisConfig(
this.globalExcludes,
this.analyzerExcludedPatterns,
String? classPattern,
) : classPattern = RegExp(classPattern ?? r'I18n$');
}
19 changes: 0 additions & 19 deletions lib/src/analyzers/unused_l10n_analyzer/unused_l10n_analyzer.dart
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions lib/src/config_builder/config_builder.dart
Expand Up @@ -90,7 +90,6 @@ class ConfigBuilder {
) =>
UnusedFilesAnalysisConfig(
prepareExcludes(config.excludePatterns, rootPath),
prepareExcludes(config.analyzerExcludePatterns, rootPath),
);

/// Creates a raw unused code config from given [excludePatterns].
Expand Down Expand Up @@ -136,7 +135,6 @@ class ConfigBuilder {
) =>
UnusedL10nAnalysisConfig(
prepareExcludes(config.excludePatterns, rootPath),
prepareExcludes(config.analyzerExcludePatterns, rootPath),
config.classPattern,
);

Expand Down
34 changes: 30 additions & 4 deletions lib/src/utils/analyzer_utils.dart
Expand Up @@ -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';
Expand All @@ -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),
);
Expand All @@ -48,7 +52,7 @@ Set<String> 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*/;

Expand Down Expand Up @@ -86,3 +90,25 @@ Set<String> _extractDartFilesFromFolders(
))
.map((entity) => normalize(entity.path)))
.toSet();

ResourceProvider _prepareAnalysisOptions(List<String> 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;
}
Expand Up @@ -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));
});

Expand Down