44
55import 'dart:convert' show jsonDecode, JsonEncoder;
66
7- import 'package:analyzer/dart/analysis/features.dart' ;
87import 'package:analyzer/dart/analysis/results.dart' ;
98import 'package:analyzer/dart/ast/ast.dart' ;
109import 'package:analyzer/file_system/file_system.dart' ;
@@ -30,11 +29,11 @@ class NonNullableFix {
3029 // TODO(srawlins): Refactor to use
3130 // `Feature.non_nullable.releaseVersion` when this becomes non-null (perhaps
3231 // after "Beta").
33- static final Version _intendedMinimumSdkVersion =
34- Feature .non_nullable.experimentalReleaseVersion;
32+ static final Version _intendedMinimumSdkVersion = Version .parse ('2.12.0-0' );
3533
3634 // In the package_config.json file, the patch number is omitted.
37- static const String _intendedLanguageVersion = '2.10' ;
35+ static final String _intendedLanguageVersion =
36+ '${_intendedMinimumSdkVersion .major }.${_intendedMinimumSdkVersion .minor }' ;
3837
3938 static final String _intendedSdkVersionConstraint =
4039 '>=$_intendedMinimumSdkVersion <2.12.0' ;
@@ -153,9 +152,6 @@ class NonNullableFix {
153152 if (updated) {
154153 _processConfigFile (pkgFolder, pubspec);
155154 }
156- // TODO(https://github.com/dart-lang/sdk/issues/43806): stop processing
157- // analysis options file when the experiment is no longer needed.
158- _processAnalysisOptionsFile (pkgFolder);
159155 }
160156
161157 Future <void > processUnit (ResolvedUnitResult result) async {
@@ -212,91 +208,6 @@ class NonNullableFix {
212208 }
213209 }
214210
215- void _processAnalysisOptionsException (
216- String action, String analysisOptionsPath, error) {
217- listener.addRecommendation ('''Failed to $action analysis options file
218- $analysisOptionsPath
219- $error
220-
221- Manually update this file to enable the Null Safety language feature in static
222- analysis by adding:
223-
224- analyzer:
225- enable-experiment:
226- - non-nullable
227- ''' );
228- }
229-
230- void _processAnalysisOptionsFile (Folder pkgFolder) {
231- var analysisOptionsFile =
232- pkgFolder.getChildAssumingFile ('analysis_options.yaml' );
233- if (! analysisOptionsFile.exists) {
234- // A source file edit cannot be made for a file which doesn't exist.
235- // Instead of using the fix listener, just write the file directly.
236- analysisOptionsFile.writeAsStringSync ('''
237- analyzer:
238- enable-experiment:
239- - non-nullable
240-
241- ''' );
242- return ;
243- }
244-
245- _YamlFile analysisOptions;
246- try {
247- analysisOptions = _YamlFile ._parseFrom (analysisOptionsFile);
248- } on FileSystemException catch (e) {
249- _processAnalysisOptionsException ('read' , analysisOptionsFile.path, e);
250- return ;
251- } on FormatException catch (e) {
252- _processAnalysisOptionsException ('parse' , analysisOptionsFile.path, e);
253- return ;
254- }
255-
256- var analysisOptionsMap = analysisOptions.content;
257- YamlNode analyzerOptions;
258- if (analysisOptionsMap is YamlMap ) {
259- analyzerOptions = analysisOptionsMap.nodes['analyzer' ];
260- }
261- if (analyzerOptions == null ) {
262- // There is no top-level "analyzer" section. We can write one in its
263- // entirety, and use a 2-space indentation. This is a valid indentation,
264- // even if the file contains another top-level section (perhaps "linter")
265- // which uses a different indentation.
266- var start = SourceLocation (0 , line: 0 , column: 0 );
267- var content = '''
268- analyzer:
269- enable-experiment:
270- - non-nullable
271-
272- ''' ;
273- analysisOptions._insertAfterParent (
274- SourceSpan (start, start, '' ), content, listener);
275- } else if (analyzerOptions is YamlMap ) {
276- var enableExperiment = analyzerOptions.nodes['enable-experiment' ];
277- if (enableExperiment == null ) {
278- var analyzerIndentation =
279- analysisOptions._getMapEntryIndentation (analyzerOptions);
280- var indent = ' ' * analyzerIndentation;
281- var content = '\n '
282- '${indent }enable-experiment:\n '
283- '$indent - non-nullable' ;
284- analysisOptions._insertAfterParent (
285- analyzerOptions.span, content, listener);
286- } else if (enableExperiment is YamlList ) {
287- var enableExperimentIndentation =
288- analysisOptions._getListIndentation (enableExperiment);
289- var indent = ' ' * enableExperimentIndentation;
290- var nonNullableIsEnabled = enableExperiment.value
291- .any ((experiment) => experiment == 'non-nullable' );
292- if (nonNullableIsEnabled) return ;
293- var content = '\n ' '$indent - non-nullable' ;
294- analysisOptions._insertAfterParent (
295- enableExperiment.span, content, listener);
296- }
297- }
298- }
299-
300211 /// Updates the Package Config file to specify a minimum Dart SDK version
301212 /// which supports null safety.
302213 void _processConfigFile (Folder pkgFolder, _YamlFile pubspec) {
@@ -516,48 +427,13 @@ $stackTrace''');
516427}
517428
518429class _YamlFile {
519- static final _newlineCharacter = RegExp ('[\r\n ]' );
520430 final String path;
521431 final String textContent;
522432
523433 final YamlNode content;
524434
525435 _YamlFile ._(this .path, this .textContent, this .content);
526436
527- /// Returns the indentation of the entries in [node] .
528- int _getListIndentation (YamlList node) {
529- return node.span.start.column;
530- }
531-
532- /// Returns the indentation of the first (and presumably all) entry of [node] .
533- int _getMapEntryIndentation (YamlMap node) {
534- if (node.isEmpty) return 2 ;
535-
536- var value = node.nodes.values.first;
537- if (value is YamlScalar ) {
538- // A YamlScalar value indicates that a "key: value" pair is on a single
539- // line. The span's start column is the start column of the value, not the
540- // key.
541- var offset = value.span.start.offset;
542- var firstSpaceIndex =
543- textContent.lastIndexOf (_newlineCharacter, offset) + 1 ;
544- var index = firstSpaceIndex;
545- while (textContent.codeUnitAt (index) == $space) {
546- index++ ;
547- }
548- return index - firstSpaceIndex;
549- } else if (value is YamlMap ) {
550- // If the first entry of [node] is a YamlMap, then the span for [node]
551- // indicates the start of the first entry.
552- return node.span.start.column;
553- } else {
554- assert (value is YamlList );
555- // If the first entry of [node] is a YamlList, then the span for [value]
556- // indicates the start of the first list entry.
557- return value.span.start.column;
558- }
559- }
560-
561437 String _getName () {
562438 YamlNode packageNameNode;
563439
0 commit comments