Store original names in the minified name map

Change-Id: I411125aebe08fee10f1eeee4e6f30623cb0d7854
Reviewed-on: https://dart-review.googlesource.com/65795
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Sigmund Cherem 2018-07-20 23:50:45 +00:00 committed by commit-bot@chromium.org
parent ac73b8e198
commit e3b5bfd854
6 changed files with 82 additions and 17 deletions

View file

@ -542,6 +542,8 @@ class Namer {
final NamingScope instanceScope = new NamingScope();
final Map<String, jsAst.Name> userInstanceMembers =
new HashMap<String, jsAst.Name>();
final Map<String, String> userInstanceMembersOriginalName =
new HashMap<String, String>();
final Map<MemberEntity, jsAst.Name> internalInstanceMembers =
new HashMap<MemberEntity, jsAst.Name>();
final Map<String, jsAst.Name> userInstanceOperators =
@ -557,7 +559,8 @@ class Namer {
userInstanceMembers.forEach((name, jsName) {
// Non-finalized names are not present in the output program
if (jsName is TokenName && !jsName.isFinalized) return;
map[jsName.name] = name;
var originalName = userInstanceMembersOriginalName[name];
map[jsName.name] = originalName ?? name;
});
// TODO(sigmund): reverse the operator names back to the original Dart
@ -1199,6 +1202,7 @@ class Namer {
newName = getFreshName(instanceScope, proposedName,
sanitizeForAnnotations: true);
userInstanceMembers[key] = newName;
userInstanceMembersOriginalName[key] = '$originalName';
}
return _newReference(newName);
}
@ -1221,6 +1225,8 @@ class Namer {
String name = proposeName();
newName = getFreshName(instanceScope, name, sanitizeForAnnotations: true);
userInstanceMembers[key] = newName;
// TODO(sigmund): consider plumbing the original name instead.
userInstanceMembersOriginalName[key] = name;
}
return _newReference(newName);
}
@ -1241,6 +1247,7 @@ class Namer {
assert(!userInstanceMembers.containsKey(key));
assert(!instanceScope.isUsed(disambiguatedName));
userInstanceMembers[key] = new StringBackedName(disambiguatedName);
userInstanceMembersOriginalName[key] = originalName;
instanceScope.registerUse(disambiguatedName);
}

View file

@ -36,17 +36,18 @@ Future<D8Result> runWithD8(
Map<String, String> memorySourceFiles: const <String, String>{},
List<String> options: const <String>[],
String expectedOutput,
bool printJs: false}) async {
bool printJs: false,
bool printSteps: false}) async {
entryPoint ??= Uri.parse('memory:main.dart');
Uri mainFile =
await createTemp(entryPoint, memorySourceFiles, printSteps: true);
await createTemp(entryPoint, memorySourceFiles, printSteps: printSteps);
String output = uriPathToNative(mainFile.resolve('out.js').path);
List<String> dart2jsArgs = [
mainFile.toString(),
'-o$output',
'--packages=${Platform.packageConfig}',
]..addAll(options);
print('Running: dart2js ${dart2jsArgs.join(' ')}');
if (printSteps) print('Running: dart2js ${dart2jsArgs.join(' ')}');
CompilationResult result = await dart2js.internalMain(dart2jsArgs);
Expect.isTrue(result.isSuccess);
@ -59,11 +60,11 @@ Future<D8Result> runWithD8(
'sdk/lib/_internal/js_runtime/lib/preambles/d8.js',
output
];
print('Running: d8 ${d8Args.join(' ')}');
if (printSteps) print('Running: d8 ${d8Args.join(' ')}');
ProcessResult runResult = Process.runSync(d8executable, d8Args);
String out = '${runResult.stderr}\n${runResult.stdout}';
print('d8 output:');
print(out);
if (printSteps) print('d8 output:');
if (printSteps) print(out);
if (expectedOutput != null) {
Expect.equals(0, runResult.exitCode);
Expect.stringEquals(expectedOutput.trim(),

View file

@ -0,0 +1,15 @@
// Copyright (c) 2018, 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.
// Error pattern: Cannot read property '([^']*)' of null
// Kind of minified name: instance
// Expected deobfuscated name: method
main() {
new MyClass().f.method();
}
class MyClass {
var f;
}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2018, 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.
// Error pattern: Cannot read property '([^']*)' of null
// Kind of minified name: instance
// Expected deobfuscated name: method
main() {
new MyClass().f.method(1, 2);
}
class MyClass {
var f;
}

View file

@ -0,0 +1,25 @@
// Copyright (c) 2018, 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.
// TODO(sigmund): should this be handled as "other"? (the identifier appears
// direclty in the line producing the error).
//
// Error pattern: \.([^\.]*) is not a function
// Kind of minified name: instance
// Expected deobfuscated name: m1
import 'package:expect/expect.dart';
main() {
dynamic x = confuse(new B());
x.m1();
}
@AssumeDynamic()
@NoInline()
confuse(x) => x;
class B {
m2() {}
}

View file

@ -19,6 +19,7 @@ void main(List<String> args) {
ArgResults argResults = argParser.parse(args);
Directory dataDir =
new Directory.fromUri(Platform.script.resolve('minified'));
print('Input folder: ${dataDir.uri}');
asyncTest(() async {
bool continuing = false;
await for (FileSystemEntity entity in dataDir.list()) {
@ -29,9 +30,7 @@ void main(List<String> args) {
!continuing) {
continue;
}
print('----------------------------------------------------------------');
print('Checking ${entity.uri}');
print('----------------------------------------------------------------');
print('\ninput $name');
await runTest(await new File.fromUri(entity.uri).readAsString());
if (argResults['continued']) continuing = true;
}
@ -85,19 +84,19 @@ Future runTest(String code) async {
Expect.isNotNull(nameMatch, "Could not find the expected deobfuscated name.");
var expectedName = nameMatch.group(1);
var test = new MinifiedNameTest(pattern, kind, expectedName, code);
print(test.code);
print('expectations: ${pattern.pattern} $kind $expectedName');
await checkExpectation(test, false);
await checkExpectation(test, true);
}
checkExpectation(MinifiedNameTest test, bool minified) async {
print('-- ${minified ? 'minified' : 'not-minified'} '
'-----------------------------------------------');
print('-- ${minified ? 'minified' : 'not-minified'}:');
D8Result result = await runWithD8(
memorySourceFiles: {'main.dart': test.code},
options: minified ? [Flags.minify] : []);
String stdout = result.runResult.stdout;
String error = _extractError(stdout);
print(' error: $error');
Expect.isNotNull(error, 'Couldn\'t find the error message in $stdout');
var match = test.pattern.firstMatch(error);
@ -106,6 +105,7 @@ checkExpectation(MinifiedNameTest test, bool minified) async {
'Error didn\'t match the test pattern'
'\nerror: $error\npattern:${test.pattern}');
var name = match.group(1);
print(' obfuscated-name: $name');
Expect.isNotNull(name, 'Error didn\'t contain a name\nerror: $error');
var sourceMap = '${result.outputPath}.map';
@ -116,15 +116,17 @@ checkExpectation(MinifiedNameTest test, bool minified) async {
var minifiedNames = extensions['minified_names'];
Expect.isNotNull(minifiedNames, "Source-map doesn't contain minified-names");
var actualName;
if (test.isGlobal) {
var actualName = json['names'][minifiedNames['global'][name]];
Expect.equals(test.expectedName, actualName);
actualName = json['names'][minifiedNames['global'][name]];
} else if (test.isInstance) {
var actualName = json['names'][minifiedNames['instance'][name]];
Expect.equals(test.expectedName, actualName);
actualName = json['names'][minifiedNames['instance'][name]];
} else {
Expect.fail('unexpected');
}
print(' actual-name: $actualName');
Expect.equals(test.expectedName, actualName);
print(' PASS!!');
}
String _extractError(String stdout) {