| // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analyzer/dart/analysis/features.dart'; |
| import 'package:analyzer/dart/analysis/results.dart'; |
| import 'package:analyzer/src/dart/analysis/experiments.dart' |
| show ExperimentStatus; |
| import 'package:analyzer_plugin/src/utilities/extensions/formatter_options.dart'; |
| import 'package:dart_style/dart_style.dart'; |
| |
| /// The default version to use for formatting code when there is no better |
| /// effective language version for the code. |
| /// |
| /// This is the minimum of the latest version supported by the formatter or |
| /// the current language version. |
| final defaultFormatterVersion = |
| DartFormatter.latestLanguageVersion < ExperimentStatus.currentVersion |
| ? DartFormatter.latestLanguageVersion |
| : ExperimentStatus.currentVersion; |
| |
| /// A list of all features that are currently enabled by an experiment flag. |
| final _allowedExperiments = ExperimentStatus.knownFeatures.values |
| .where((feature) => feature.status == FeatureStatus.future) |
| .toList(); |
| |
| /// Creates a formatter with the appropriate settings for [result]. |
| DartFormatter createFormatter( |
| ParsedUnitResult result, { |
| int? defaultPageWidth, |
| }) { |
| var featureSet = result.unit.featureSet; |
| var formatterOptions = result.analysisOptions.formatterOptions; |
| var effectivePageWidth = formatterOptions.pageWidth ?? defaultPageWidth; |
| var effectiveTrailingCommas = formatterOptions.dartStyleTrailingCommas; |
| var effectiveLanguageVersion = result.unit.languageVersion.effective; |
| return DartFormatter( |
| pageWidth: effectivePageWidth, |
| trailingCommas: effectiveTrailingCommas, |
| languageVersion: effectiveLanguageVersion, |
| experimentFlags: _getExperiments(featureSet), |
| ); |
| } |
| |
| /// Gets the list of experiment strings enabled by [featureSet] that are |
| /// required for future features. |
| List<String> _getExperiments(FeatureSet featureSet) { |
| return _allowedExperiments |
| .where(featureSet.isEnabled) |
| .map((feature) => feature.enableString) |
| .toList(); |
| } |
| |
| extension DartFormatterExtension on DartFormatter { |
| /// Formats the content, returning the original content if any error occurs |
| /// (for example a parse error) during formatting. |
| SourceCode formatSafely( |
| String content, { |
| int? selectionStart, |
| int? selectionLength, |
| }) { |
| var source = SourceCode( |
| content, |
| selectionStart: selectionStart, |
| selectionLength: selectionLength, |
| ); |
| try { |
| return formatSource(source); |
| } catch (_) { |
| // Return the original source if formatting failed for any reason. |
| return source; |
| } |
| } |
| } |