[dart2js] New RTI: Support redirection in ruleset.

Change-Id: I6b11dbd826f9b47febcb0cd2716d93ff5cd8b74c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118887
Commit-Queue: Mayank Patke <fishythefish@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
Mayank Patke 2019-09-26 22:24:52 +00:00 committed by commit-bot@chromium.org
parent 0c6249de26
commit 75eb947bc8
4 changed files with 53 additions and 13 deletions

View file

@ -493,12 +493,17 @@ class _RulesetEntry {
}
class Ruleset {
Map<ClassEntity, ClassEntity> _redirections;
Map<InterfaceType, _RulesetEntry> _entries;
Ruleset(this._entries);
Ruleset.empty() : this({});
Ruleset(this._redirections, this._entries);
Ruleset.empty() : this({}, {});
void add(InterfaceType targetType, Iterable<InterfaceType> supertypes,
void addRedirection(ClassEntity targetClass, ClassEntity redirection) {
_redirections[targetClass] = redirection;
}
void addEntry(InterfaceType targetType, Iterable<InterfaceType> supertypes,
Map<TypeVariableType, DartType> typeVariables) {
_RulesetEntry entry = _entries[targetType] ??= _RulesetEntry();
entry.addAll(supertypes, typeVariables);
@ -552,11 +557,22 @@ class RulesetEncoder {
js.concatenateStrings([
_quote,
_leftBrace,
...js.joinLiterals(ruleset._entries.entries.map(_encodeEntry), _comma),
...js.joinLiterals([
...ruleset._redirections.entries.map(_encodeRedirection),
...ruleset._entries.entries.map(_encodeEntry),
], _comma),
_rightBrace,
_quote,
]);
jsAst.StringConcatenation _encodeRedirection(
MapEntry<ClassEntity, ClassEntity> redirection) =>
js.concatenateStrings([
js.quoteName(_emitter.typeAccessNewRti(redirection.key)),
_colon,
js.quoteName(_emitter.typeAccessNewRti(redirection.value)),
]);
jsAst.StringConcatenation _encodeEntry(
MapEntry<InterfaceType, _RulesetEntry> entry) =>
js.concatenateStrings([

View file

@ -1945,6 +1945,10 @@ class FragmentEmitter {
js.Statement emitTypeRules(Fragment fragment) {
if (!_options.experimentNewRti) return js.EmptyStatement();
bool addJsObjectRedirections = false;
ClassEntity jsObjectClass = _commonElements.jsJavaScriptObjectClass;
InterfaceType jsObjectType = _elementEnvironment.getThisType(jsObjectClass);
Ruleset ruleset = Ruleset.empty();
Iterable<Class> classes =
fragment.libraries.expand((Library library) => library.classes);
@ -1971,17 +1975,21 @@ class FragmentEmitter {
}
if (isInterop) {
_classHierarchy
.subtypesOf(_commonElements.jsJavaScriptObjectClass)
.forEach((ClassEntity interceptor) {
ruleset.add(_elementEnvironment.getThisType(interceptor), supertypes,
typeVariables);
});
ruleset.addEntry(jsObjectType, supertypes, typeVariables);
addJsObjectRedirections = true;
} else {
ruleset.add(targetType, supertypes, typeVariables);
ruleset.addEntry(targetType, supertypes, typeVariables);
}
});
if (addJsObjectRedirections) {
_classHierarchy
.strictSubtypesOf(jsObjectClass)
.forEach((ClassEntity subtype) {
ruleset.addRedirection(subtype, jsObjectClass);
});
}
FunctionEntity method = _closedWorld.commonElements.rtiAddRulesMethod;
return js.js.statement('#(init.#,JSON.parse(#));', [
_emitter.staticFunctionAccess(method),

View file

@ -1207,9 +1207,17 @@ class _Universe {
static Object typeRules(universe) =>
JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
static Object findRule(universe, String targetType) =>
static Object _findRule(universe, String targetType) =>
JS('', '#.#', typeRules(universe), targetType);
static Object findRule(universe, String targetType) {
Object rule = _findRule(universe, targetType);
while (_Utils.isString(rule)) {
rule = _findRule(universe, _Utils.asString(rule));
}
return rule;
}
static void addRules(universe, rules) {
// TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated.
var keys = JS('JSArray', 'Object.keys(#)', rules);

View file

@ -1209,9 +1209,17 @@ class _Universe {
static Object typeRules(universe) =>
JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
static Object findRule(universe, String targetType) =>
static Object _findRule(universe, String targetType) =>
JS('', '#.#', typeRules(universe), targetType);
static Object findRule(universe, String targetType) {
Object rule = _findRule(universe, targetType);
while (_Utils.isString(rule)) {
rule = _findRule(universe, _Utils.asString(rule));
}
return rule;
}
static void addRules(universe, rules) {
// TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated.
var keys = JS('JSArray', 'Object.keys(#)', rules);