[web] Fix some regex issues in the sdk_rewriter (#25866)
diff --git a/web_sdk/sdk_rewriter.dart b/web_sdk/sdk_rewriter.dart
index dfa63e2..ceab562 100644
--- a/web_sdk/sdk_rewriter.dart
+++ b/web_sdk/sdk_rewriter.dart
@@ -18,17 +18,17 @@
..addOption('stamp');
final List<Replacer> uiPatterns = <Replacer>[
- AllReplacer('library ui;', 'library dart.ui;'),
- AllReplacer('part of ui;', 'part of dart.ui;'),
- AllReplacer(r'''
-import 'src/engine.dart' as engine;
-''', r'''
+ AllReplacer(RegExp(r'library\s+ui;'), 'library dart.ui;'),
+ AllReplacer(RegExp(r'part\s+of\s+ui;'), 'part of dart.ui;'),
+ AllReplacer(RegExp(r'''
+import\s*'src/engine.dart'\s*as\s+engine;
+'''), r'''
import 'dart:_engine' as engine;
'''),
- AllReplacer(
+ AllReplacer(RegExp(
r'''
-export 'src/engine.dart'
-''',
+export\s*'src/engine.dart'
+'''),
r'''
export 'dart:_engine'
''',
@@ -36,44 +36,44 @@
];
final List<Replacer> engineLibraryPatterns = <Replacer>[
- AllReplacer('library engine;', 'library dart._engine;'),
- AllReplacer(r'''
-import '../ui.dart' as ui;
-''', r'''
+ AllReplacer(RegExp(r'library\s+engine;'), 'library dart._engine;'),
+ AllReplacer(RegExp(r'''
+import\s*'../ui.dart' as ui;
+'''), r'''
import 'dart:ui' as ui;
'''),
- AllReplacer(r'''
-import 'package:ui/ui.dart' as ui;
-''', r'''
+ AllReplacer(RegExp(r'''
+import\s*'package:ui/ui.dart' as ui;
+'''), r'''
import 'dart:ui' as ui;
'''),
// Remove imports of engine part files.
- AllReplacer(RegExp(r"import 'engine/.*';"), ''),
+ AllReplacer(RegExp(r"import\s*'engine/.*';"), ''),
// Replace exports of engine files with "part" directives.
MappedReplacer(RegExp(r'''
-export 'engine/(.*)';
+export\s*'engine/(.*)';
'''), (Match match) => '''
part 'engine/${match.group(1)}';
'''),
AllReplacer(
- 'import \'package:js/js.dart\'',
- 'import \'dart:_js_annotations\'',
+ RegExp(r"import\s*'package:js/js.dart'"),
+ r"import 'dart:_js_annotations'",
),
];
final List<Replacer> enginePartsPatterns = <Replacer>[
- AllReplacer('part of engine;', 'part of dart._engine;'),
+ AllReplacer(RegExp(r'part\s+of\s+engine;'), 'part of dart._engine;'),
// Remove library-level JS annotations.
AllReplacer(RegExp(r'\n@JS(.*)\nlibrary .+;'), ''),
// Remove library directives.
AllReplacer(RegExp(r'\nlibrary .+;'), ''),
// Remove imports/exports from all engine parts.
- AllReplacer(RegExp(r'import .*'), ''),
- AllReplacer(RegExp(r'export .*'), ''),
+ AllReplacer(RegExp(r'\nimport\s*.*'), ''),
+ AllReplacer(RegExp(r'\nexport\s*.*'), ''),
];
final List<Replacer> sharedPatterns = <Replacer>[
- AllReplacer("import 'package:meta/meta.dart';", ''),
+ AllReplacer(RegExp(r"import\s*'package:meta/meta.dart';"), ''),
AllReplacer('@required', ''),
AllReplacer('@protected', ''),
AllReplacer('@mustCallSuper', ''),
@@ -92,31 +92,41 @@
final File outputFile = File(path.join(
directory.path, inputFile.path.substring(inputDirectoryPath.length)))
..createSync(recursive: true);
- String source = inputFile.readAsStringSync();
- final List<Replacer> replacementPatterns = <Replacer>[];
- replacementPatterns.addAll(sharedPatterns);
- if (results['ui'] as bool) {
- replacementPatterns.addAll(uiPatterns);
- } else if (results['engine'] as bool) {
- if (inputFilePath.endsWith('lib/src/engine.dart')) {
- replacementPatterns.addAll(engineLibraryPatterns);
- } else {
- source = _preprocessEnginePartFile(source);
- replacementPatterns.addAll(enginePartsPatterns);
- }
- }
- for (final Replacer replacer in replacementPatterns) {
- source = replacer.perform(source);
- }
- outputFile.writeAsStringSync(source);
+ final String source = inputFile.readAsStringSync();
+ final String rewrittenContent = rewriteFile(
+ source,
+ filePath: inputFilePath,
+ isUi: results['ui'] as bool,
+ isEngine: results['engine'] as bool,
+ );
+ outputFile.writeAsStringSync(rewrittenContent);
if (results['stamp'] != null) {
File(results['stamp'] as String).writeAsStringSync('stamp');
}
}
}
+String rewriteFile(String source, {String filePath, bool isUi, bool isEngine}) {
+ final List<Replacer> replacementPatterns = <Replacer>[];
+ replacementPatterns.addAll(sharedPatterns);
+ if (isUi) {
+ replacementPatterns.addAll(uiPatterns);
+ } else if (isEngine) {
+ if (filePath.endsWith('lib/src/engine.dart')) {
+ replacementPatterns.addAll(engineLibraryPatterns);
+ } else {
+ source = _preprocessEnginePartFile(source);
+ replacementPatterns.addAll(enginePartsPatterns);
+ }
+ }
+ for (final Replacer replacer in replacementPatterns) {
+ source = replacer.perform(source);
+ }
+ return source;
+}
+
String _preprocessEnginePartFile(String source) {
- if (source.contains('\npart of engine;')) {
+ if (source.startsWith('part of engine;') || source.contains('\npart of engine;')) {
// The file hasn't been migrated yet.
// Do nothing.
} else {
diff --git a/web_sdk/test/sdk_rewriter_test.dart b/web_sdk/test/sdk_rewriter_test.dart
new file mode 100644
index 0000000..559e530
--- /dev/null
+++ b/web_sdk/test/sdk_rewriter_test.dart
@@ -0,0 +1,119 @@
+// Copyright 2013 The Flutter Authors. 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:test/test.dart';
+
+import '../sdk_rewriter.dart';
+
+void main() {
+ test('handles imports/exports correctly in the engine library file', () {
+ const String source = '''
+library engine;
+
+import '../ui.dart' as ui;
+import 'package:ui/ui.dart' as ui;
+
+import 'package:some_package/some_package.dart';
+
+import 'engine/file1.dart';
+export 'engine/file1.dart';
+
+import'engine/file2.dart';
+export'engine/file2.dart';
+
+import 'engine/file3.dart';
+export 'engine/file3.dart';
+''';
+
+ const String expected = '''
+library dart._engine;
+
+import 'dart:ui' as ui;
+import 'dart:ui' as ui;
+
+import 'package:some_package/some_package.dart';
+
+
+part 'engine/file1.dart';
+
+
+part 'engine/file2.dart';
+
+
+part 'engine/file3.dart';
+''';
+
+ final String result = rewriteFile(
+ source,
+ filePath: '/path/to/lib/web_ui/lib/src/engine.dart',
+ isUi: false,
+ isEngine: true,
+ );
+ expect(result, expected);
+ });
+
+ test('removes imports/exports from engine files', () {
+ const String source = '''
+import 'package:some_package/some_package.dart';
+import 'package:some_package/some_package/foo.dart';
+import 'package:some_package/some_package' as some_package;
+
+import 'file1.dart';
+import'file2.dart';
+import 'file3.dart';
+
+export 'file4.dart';
+export'file5.dart';
+export 'file6.dart';
+
+void printSomething() {
+ print('something');
+}
+''';
+
+ const String expected = '''
+part of dart._engine;
+
+
+
+void printSomething() {
+ print('something');
+}
+''';
+
+ final String result = rewriteFile(
+ source,
+ filePath: '/path/to/lib/web_ui/lib/src/engine/my_file.dart',
+ isUi: false,
+ isEngine: true,
+ );
+ expect(result, expected);
+ });
+
+ test('does not insert an extra part directive', () {
+ const String source = '''
+part of engine;
+
+void printSomething() {
+ print('something');
+}
+''';
+
+ const String expected = '''
+part of dart._engine;
+
+void printSomething() {
+ print('something');
+}
+''';
+
+ final String result = rewriteFile(
+ source,
+ filePath: '/path/to/lib/web_ui/lib/src/engine/my_file.dart',
+ isUi: false,
+ isEngine: true,
+ );
+ expect(result, expected);
+ });
+}