mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 15:21:31 +00:00
33e174084a
Use `hasScheme` in place of comparing against the empty string, and `isScheme` to compare against all other schemes. TEST=No behavior changes. Change-Id: Ifc9fd13c6cf37933ebd4a754c4b500dedbcb291b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231185 Reviewed-by: Kevin Moore <kevmoo@google.com> Commit-Queue: Nate Bosch <nbosch@google.com>
196 lines
6.5 KiB
Dart
196 lines
6.5 KiB
Dart
// Copyright (c) 2020, 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.md file.
|
|
|
|
import 'dart:io' show File, Platform, stdin, exitCode;
|
|
|
|
import 'package:front_end/src/api_prototype/compiler_options.dart';
|
|
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
|
|
import 'package:kernel/ast.dart';
|
|
import 'package:kernel/class_hierarchy.dart';
|
|
|
|
import 'incremental_suite.dart' as helper;
|
|
|
|
Future<void> main(List<String> args) async {
|
|
exitCode = 1;
|
|
Map<Uri, List<Class>> classMap = {};
|
|
Map<Uri, List<Class>> classMapWithOne = {};
|
|
Component c;
|
|
int toGo = 0;
|
|
ClassHierarchy classHierarchy;
|
|
Class memberClass;
|
|
Class primitiveConstantClass;
|
|
|
|
{
|
|
Uri input = Platform.script.resolve("../tool/_fasta/compile.dart");
|
|
CompilerOptions options = helper.getOptions();
|
|
helper.TestIncrementalCompiler compiler =
|
|
new helper.TestIncrementalCompiler(options, input,
|
|
/*Uri initializeFrom*/ null, /*bool outlineOnly*/ true);
|
|
IncrementalCompilerResult compilerResult = await compiler.computeDelta();
|
|
c = compilerResult.component;
|
|
classHierarchy = compilerResult.classHierarchy!;
|
|
List<Library> libraries = c.libraries
|
|
.where((Library lib) =>
|
|
(lib.importUri.toString() == "package:kernel/ast.dart"))
|
|
.toList();
|
|
Library astLibrary = libraries.single;
|
|
List<Class> classes =
|
|
astLibrary.classes.where((Class c) => c.name == "Node").toList();
|
|
Class nodeClass = classes.single;
|
|
classes =
|
|
astLibrary.classes.where((Class c) => c.name == "Member").toList();
|
|
memberClass = classes.single;
|
|
classes = astLibrary.classes
|
|
.where((Class c) => c.name == "PrimitiveConstant")
|
|
.toList();
|
|
primitiveConstantClass = classes.single;
|
|
|
|
for (Library library in c.libraries) {
|
|
for (Class c in library.classes) {
|
|
if (c.isAbstract) continue;
|
|
if (classHierarchy.isSubtypeOf(c, nodeClass)) {
|
|
List<Member> toStringList = classHierarchy
|
|
.getInterfaceMembers(c)
|
|
.where((Member m) =>
|
|
!m.isAbstract &&
|
|
m.name.text == "toString" &&
|
|
!m.enclosingLibrary.importUri.isScheme("dart"))
|
|
.toList();
|
|
if (toStringList.length > 1) throw "What?";
|
|
if (toStringList.length == 1) {
|
|
classMapWithOne[c.fileUri] ??= <Class>[];
|
|
classMapWithOne[c.fileUri]!.add(c);
|
|
continue;
|
|
}
|
|
toGo++;
|
|
|
|
classMap[c.fileUri] ??= <Class>[];
|
|
classMap[c.fileUri]!.add(c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (toGo == 0) {
|
|
print("OK");
|
|
exitCode = 0;
|
|
} else {
|
|
String classes = classMap.values
|
|
.map((list) => list.map((cls) => cls.name).join(', '))
|
|
.join(', ');
|
|
print("Missing toString() on $toGo class(es): ${classes}");
|
|
|
|
if (args.length == 1 && args.single == "--interactive") {
|
|
for (Uri uri in classMap.keys) {
|
|
List<Class> classes = classMap[uri]!;
|
|
print("Would you like to update ${classes.length} classes in ${uri}?"
|
|
" (y/n)");
|
|
if (stdin.readLineSync() != "y") {
|
|
print("Skipping $uri");
|
|
continue;
|
|
}
|
|
print("Continuing on $uri");
|
|
classes.sort((Class a, Class b) {
|
|
return a.fileEndOffset - b.fileEndOffset;
|
|
});
|
|
File f = new File.fromUri(uri);
|
|
String src = f.readAsStringSync();
|
|
StringBuffer newSrc = new StringBuffer();
|
|
int from = 0;
|
|
for (Class c in classes) {
|
|
String innerContent = "";
|
|
if (classHierarchy.isSubtypeOf(c, memberClass)) {
|
|
innerContent = "\$name";
|
|
} else if (classHierarchy.isSubtypeOf(c, primitiveConstantClass)) {
|
|
innerContent = "\$value";
|
|
}
|
|
int to = c.fileEndOffset;
|
|
newSrc.write(src.substring(from, to));
|
|
// We're just before the final "}".
|
|
newSrc.write("""
|
|
|
|
@override
|
|
String toString() {
|
|
return "${c.name}(\${toStringInternal()})";
|
|
}
|
|
|
|
@override
|
|
String toStringInternal() {
|
|
return "${innerContent}";
|
|
}
|
|
""");
|
|
from = to;
|
|
}
|
|
newSrc.write(src.substring(from));
|
|
f.writeAsStringSync(newSrc.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (args.length == 1 && args.single == "--interactive") {
|
|
for (Uri uri in classMapWithOne.keys) {
|
|
List<Class> classes = classMapWithOne[uri]!;
|
|
print("Would you like to update toString for ${classes.length} "
|
|
"classes in ${uri}? (y/n)");
|
|
if (stdin.readLineSync() != "y") {
|
|
print("Skipping $uri");
|
|
continue;
|
|
}
|
|
print("Continuing on $uri");
|
|
classes.sort((Class a, Class b) {
|
|
return a.fileEndOffset - b.fileEndOffset;
|
|
});
|
|
File f = new File.fromUri(uri);
|
|
String src = f.readAsStringSync();
|
|
StringBuffer newSrc = new StringBuffer();
|
|
int from = 0;
|
|
for (Class c in classes) {
|
|
String innerContent = "()";
|
|
if (classHierarchy.isSubtypeOf(c, memberClass)) {
|
|
innerContent = r"($name)";
|
|
} else if (classHierarchy.isSubtypeOf(c, primitiveConstantClass)) {
|
|
innerContent = r"($value)";
|
|
}
|
|
|
|
List<Member> toStringList = classHierarchy
|
|
.getInterfaceMembers(c)
|
|
.where((Member m) =>
|
|
!m.isAbstract &&
|
|
m.name.text == "toString" &&
|
|
!m.enclosingLibrary.importUri.isScheme("dart"))
|
|
.toList();
|
|
Member toString = toStringList.single;
|
|
if (toString.fileUri != uri) continue;
|
|
int end = toString.fileEndOffset + 1;
|
|
String existing = src.substring(toString.fileOffset, end).trim();
|
|
if (!existing.contains('return "${c.name}${innerContent}";')) {
|
|
continue;
|
|
}
|
|
|
|
innerContent = "";
|
|
if (classHierarchy.isSubtypeOf(c, memberClass)) {
|
|
innerContent = "\$name";
|
|
} else if (classHierarchy.isSubtypeOf(c, primitiveConstantClass)) {
|
|
innerContent = "\$value";
|
|
}
|
|
|
|
int to = toString.fileOffset;
|
|
newSrc.write(src.substring(from, to));
|
|
// We're just before the final "}".
|
|
newSrc.write("""
|
|
toString() {
|
|
return "${c.name}(\${toStringInternal()})";
|
|
}
|
|
|
|
@override
|
|
String toStringInternal() {
|
|
return "${innerContent}";
|
|
}""");
|
|
from = toString.fileEndOffset + 1;
|
|
}
|
|
newSrc.write(src.substring(from));
|
|
f.writeAsStringSync(newSrc.toString());
|
|
}
|
|
}
|
|
}
|