Skip to content

Commit

Permalink
[web] Fix some regex issues in the sdk_rewriter (#25866)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdebbar committed May 3, 2021
1 parent 378e4db commit d61bbfa
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 41 deletions.
92 changes: 51 additions & 41 deletions web_sdk/sdk_rewriter.dart
Expand Up @@ -18,62 +18,62 @@ final ArgParser argParser = ArgParser()
..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'
''',
),
];

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', ''),
Expand All @@ -92,31 +92,41 @@ void main(List<String> arguments) {
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 {
Expand Down
119 changes: 119 additions & 0 deletions 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);
});
}

0 comments on commit d61bbfa

Please sign in to comment.