6abae965db
Make mirrors no longer able to create new instances of enum classes. (If that breaks anyone, they had it coming! It would invalidate exhaustiveness of switches and thereby soundness in general.) Also fix a number of failing tests, delete some no longer relevant tests (e.g. testing reflection of programs that won't compile, there are no runtime compilation errors any more.) Fix some more tests that were failing. Not all. Tested: Refactoring of existing tests. Change-Id: I558fe0ed45d23cac9eddbfdfa3d560d09195955d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403587 Commit-Queue: Lasse Nielsen <lrn@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
202 lines
6.4 KiB
Dart
202 lines
6.4 KiB
Dart
// Copyright (c) 2013, 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.
|
|
|
|
/// Helper methods for converting a [Mirror] to a [String].
|
|
library test.stringify;
|
|
|
|
import 'dart:mirrors';
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
String name(DeclarationMirror? mirror) {
|
|
return (mirror == null) ? '<null>' : stringifySymbol(mirror.simpleName);
|
|
}
|
|
|
|
String stringifyMap(Map map) {
|
|
var buffer = StringBuffer('{');
|
|
bool first = true;
|
|
var names = map.keys.map((s) => MirrorSystem.getName(s)).toList()..sort();
|
|
for (String key in names) {
|
|
if (!first) buffer.write(', ');
|
|
first = false;
|
|
buffer.write(key);
|
|
buffer.write(': ');
|
|
buffer.write(stringify(map[Symbol(key)]));
|
|
}
|
|
buffer.write('}');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyIterable(Iterable list) {
|
|
var buffer = StringBuffer('[');
|
|
bool first = true;
|
|
for (String value in list.map(stringify)) {
|
|
if (!first) buffer.write(', ');
|
|
first = false;
|
|
buffer.write(value);
|
|
}
|
|
buffer.write(']');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyInstance(InstanceMirror instance) {
|
|
var buffer = StringBuffer('Instance(');
|
|
if (instance.hasReflectee) {
|
|
buffer.write('value = ${stringify(instance.reflectee)}');
|
|
}
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifySymbol(Symbol symbol) => 's(${MirrorSystem.getName(symbol)})';
|
|
|
|
void writeDeclarationOn(DeclarationMirror mirror, StringBuffer buffer) {
|
|
buffer.write(stringify(mirror.simpleName));
|
|
if (mirror.owner != null) {
|
|
buffer.write(' in ');
|
|
buffer.write(name(mirror.owner));
|
|
}
|
|
if (mirror.isPrivate) buffer.write(', private');
|
|
if (mirror.isTopLevel) buffer.write(', top-level');
|
|
}
|
|
|
|
void writeVariableOn(VariableMirror variable, StringBuffer buffer) {
|
|
writeDeclarationOn(variable, buffer);
|
|
if (variable.isStatic) buffer.write(', static');
|
|
if (variable.isFinal) buffer.write(', final');
|
|
if (variable.isConst) buffer.write(', const');
|
|
}
|
|
|
|
String stringifyVariable(VariableMirror variable) {
|
|
var buffer = StringBuffer('Variable(');
|
|
writeVariableOn(variable, buffer);
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyParameter(ParameterMirror parameter) {
|
|
var buffer = StringBuffer('Parameter(');
|
|
writeVariableOn(parameter, buffer);
|
|
if (parameter.isOptional) buffer.write(', optional');
|
|
if (parameter.isNamed) buffer.write(', named');
|
|
// TODO(6490): dart2js always returns false for hasDefaultValue.
|
|
if (parameter.hasDefaultValue) {
|
|
buffer.write(', value = ${stringify(parameter.defaultValue)}');
|
|
}
|
|
// TODO(ahe): Move to writeVariableOn.
|
|
buffer.write(', type = ${stringify(parameter.type)}');
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyTypeVariable(TypeVariableMirror typeVariable) {
|
|
var buffer = StringBuffer('TypeVariable(');
|
|
writeDeclarationOn(typeVariable, buffer);
|
|
buffer.write(', upperBound = ${stringify(typeVariable.upperBound)}');
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyType(TypeMirror type) {
|
|
var buffer = StringBuffer('Type(');
|
|
writeDeclarationOn(type, buffer);
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyClass(ClassMirror cls) {
|
|
var buffer = StringBuffer('Class(');
|
|
writeDeclarationOn(cls, buffer);
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyMethod(MethodMirror method) {
|
|
var buffer = StringBuffer('Method(');
|
|
writeDeclarationOn(method, buffer);
|
|
if (method.isAbstract) buffer.write(', abstract');
|
|
if (method.isSynthetic) buffer.write(', synthetic');
|
|
if (method.isStatic) buffer.write(', static');
|
|
if (method.isGetter) buffer.write(', getter');
|
|
if (method.isSetter) buffer.write(', setter');
|
|
if (method.isConstructor) buffer.write(', constructor');
|
|
buffer.write(')');
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringifyDependencies(LibraryMirror l) {
|
|
n(s) => s is Symbol ? MirrorSystem.getName(s) : s;
|
|
int compareDep(a, b) {
|
|
if (a.targetLibrary == b.targetLibrary) {
|
|
if ((a.prefix != null) && (b.prefix != null)) {
|
|
return n(a.prefix).compareTo(n(b.prefix));
|
|
}
|
|
return a.prefix == null ? 1 : -1;
|
|
}
|
|
return n(
|
|
a.targetLibrary.simpleName,
|
|
).compareTo(n(b.targetLibrary.simpleName));
|
|
}
|
|
|
|
int compareCom(a, b) => n(a.identifier).compareTo(n(b.identifier));
|
|
int compareFirst(a, b) => a[0].compareTo(b[0]);
|
|
sortBy(c, p) => List.from(c)..sort(p);
|
|
|
|
var buffer = StringBuffer();
|
|
sortBy(l.libraryDependencies, compareDep).forEach((dep) {
|
|
if (dep.isImport) buffer.write('import ');
|
|
if (dep.isExport) buffer.write('export ');
|
|
buffer.write(n(dep.targetLibrary.simpleName));
|
|
if (dep.isDeferred) buffer.write(' deferred');
|
|
if (dep.prefix != null) buffer.write(' as ${n(dep.prefix)}');
|
|
buffer.write('\n');
|
|
|
|
var flattenedCombinators = <dynamic>[];
|
|
dep.combinators.forEach((com) {
|
|
com.identifiers.forEach((ident) {
|
|
flattenedCombinators.add([n(ident), com.isShow, com.isHide]);
|
|
});
|
|
});
|
|
sortBy(flattenedCombinators, compareFirst).forEach((triple) {
|
|
buffer.write(' ');
|
|
if (triple[1]) buffer.write('show ');
|
|
if (triple[2]) buffer.write('hide ');
|
|
buffer.write(triple[0]);
|
|
buffer.write('\n');
|
|
});
|
|
});
|
|
return buffer.toString();
|
|
}
|
|
|
|
String stringify(value) {
|
|
if (value == null) return '<null>';
|
|
if (value is Map) return stringifyMap(value);
|
|
if (value is Iterable) return stringifyIterable(value);
|
|
if (value is InstanceMirror) return stringifyInstance(value);
|
|
if (value is ParameterMirror) return stringifyParameter(value);
|
|
if (value is VariableMirror) return stringifyVariable(value);
|
|
if (value is MethodMirror) return stringifyMethod(value);
|
|
if (value is num) return value.toString();
|
|
if (value is String) return value;
|
|
if (value is Symbol) return stringifySymbol(value);
|
|
if (value is ClassMirror) return stringifyClass(value);
|
|
if (value is TypeVariableMirror) return stringifyTypeVariable(value);
|
|
if (value is TypeMirror) return stringifyType(value);
|
|
throw 'Unexpected value: $value';
|
|
}
|
|
|
|
void expect(expected, actual, [String reason = ""]) {
|
|
Expect.stringEquals(expected, stringify(actual), reason);
|
|
}
|
|
|
|
int compareSymbols(Symbol a, Symbol b) {
|
|
return MirrorSystem.getName(a).compareTo(MirrorSystem.getName(b));
|
|
}
|
|
|
|
Iterable<Symbol> simpleNames(Iterable<Mirror> i) =>
|
|
i.map((e) => (e as DeclarationMirror).simpleName);
|
|
|
|
List<Symbol> sort(Iterable<Symbol> symbols) =>
|
|
symbols.toList()..sort(compareSymbols);
|