mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:07:49 +00:00
[dart2js] Avoid adding empty type rules.
The fragment emitter already tries to skip the call to `addRules` if the ruleset is empty, but this occurs too early. The ruleset encoder strips tautologies like `T <: T` and `InterfaceType <: Object`, but this occurs after the empty check. This CL removes the preprocessing from the encoder and instead performs checks when entries are added to the ruleset, fixing the issue. Change-Id: I62f937e0ff6abac12973f82b2c89d8ea6f3162b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258040 Reviewed-by: Joshua Litt <joshualitt@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
This commit is contained in:
parent
3584073fbc
commit
581db69c7a
|
@ -460,15 +460,22 @@ class _RulesetEntry {
|
|||
}
|
||||
|
||||
class Ruleset {
|
||||
Map<ClassEntity, ClassEntity> _redirections;
|
||||
Map<InterfaceType, _RulesetEntry> _entries;
|
||||
final DartTypes _dartTypes;
|
||||
final Map<ClassEntity, ClassEntity> _redirections = {};
|
||||
final Map<InterfaceType, _RulesetEntry> _entries = {};
|
||||
|
||||
Ruleset(this._redirections, this._entries);
|
||||
Ruleset.empty() : this({}, {});
|
||||
Ruleset.empty(this._dartTypes);
|
||||
|
||||
CommonElements get _commonElements => _dartTypes.commonElements;
|
||||
ClassEntity get _objectClass => _commonElements.objectClass;
|
||||
|
||||
bool get isEmpty => _redirections.isEmpty && _entries.isEmpty;
|
||||
bool get isNotEmpty => _redirections.isNotEmpty || _entries.isNotEmpty;
|
||||
|
||||
bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
|
||||
|
||||
bool _isSyntheticClosure(InterfaceType type) => type.element.isClosure;
|
||||
|
||||
void addRedirection(ClassEntity redirectee, ClassEntity target) {
|
||||
assert(redirectee != target);
|
||||
_redirections[redirectee] = target;
|
||||
|
@ -476,20 +483,21 @@ class Ruleset {
|
|||
|
||||
void addEntry(InterfaceType targetType, Iterable<InterfaceType> supertypes,
|
||||
Map<TypeVariableType, DartType> typeVariables) {
|
||||
if (_isObject(targetType) || _isSyntheticClosure(targetType)) return;
|
||||
supertypes = supertypes.where((supertype) =>
|
||||
!_isObject(supertype) &&
|
||||
!identical(targetType.element, supertype.element));
|
||||
if (supertypes.isEmpty && typeVariables.isEmpty) return;
|
||||
_RulesetEntry entry = _entries[targetType] ??= _RulesetEntry();
|
||||
entry.addAll(supertypes, typeVariables);
|
||||
}
|
||||
}
|
||||
|
||||
class RulesetEncoder {
|
||||
final DartTypes _dartTypes;
|
||||
final ModularEmitter _emitter;
|
||||
final RecipeEncoder _recipeEncoder;
|
||||
|
||||
RulesetEncoder(this._dartTypes, this._emitter, this._recipeEncoder);
|
||||
|
||||
CommonElements get _commonElements => _dartTypes.commonElements;
|
||||
ClassEntity get _objectClass => _commonElements.objectClass;
|
||||
RulesetEncoder(this._emitter, this._recipeEncoder);
|
||||
|
||||
final _leftBrace = js.string('{');
|
||||
final _rightBrace = js.string('}');
|
||||
|
@ -499,32 +507,10 @@ class RulesetEncoder {
|
|||
final _comma = js.string(',');
|
||||
final _doubleQuote = js.string('"');
|
||||
|
||||
bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
|
||||
|
||||
bool _isSyntheticClosure(InterfaceType type) => type.element.isClosure;
|
||||
|
||||
void _preprocessEntry(InterfaceType targetType, _RulesetEntry entry) {
|
||||
entry._supertypes.removeWhere((InterfaceType supertype) =>
|
||||
_isObject(supertype) ||
|
||||
identical(targetType.element, supertype.element));
|
||||
}
|
||||
|
||||
void _preprocessRuleset(Ruleset ruleset) {
|
||||
ruleset._entries.removeWhere((InterfaceType targetType, _) =>
|
||||
_isObject(targetType) || _isSyntheticClosure(targetType));
|
||||
ruleset._entries.forEach(_preprocessEntry);
|
||||
ruleset._entries.removeWhere((_, _RulesetEntry entry) => entry.isEmpty);
|
||||
}
|
||||
|
||||
// TODO(fishythefish): Common substring elimination.
|
||||
|
||||
/// Produces a string readable by `JSON.parse()`.
|
||||
jsAst.StringConcatenation encodeRuleset(Ruleset ruleset) {
|
||||
_preprocessRuleset(ruleset);
|
||||
return _encodeRuleset(ruleset);
|
||||
}
|
||||
|
||||
jsAst.StringConcatenation _encodeRuleset(Ruleset ruleset) =>
|
||||
jsAst.StringConcatenation encodeRuleset(Ruleset ruleset) =>
|
||||
js.concatenateStrings([
|
||||
_leftBrace,
|
||||
...js.joinLiterals([
|
||||
|
|
|
@ -628,8 +628,7 @@ class FragmentEmitter {
|
|||
: RuntimeTypesImpl(_closedWorld),
|
||||
_closedWorld.nativeData,
|
||||
_closedWorld.commonElements);
|
||||
_rulesetEncoder =
|
||||
RulesetEncoder(_closedWorld.dartTypes, _emitter, _recipeEncoder);
|
||||
_rulesetEncoder = RulesetEncoder(_emitter, _recipeEncoder);
|
||||
}
|
||||
|
||||
js.Expression generateEmbeddedGlobalAccess(String global) =>
|
||||
|
@ -1912,7 +1911,7 @@ class FragmentEmitter {
|
|||
Map<ClassTypeData, List<ClassTypeData>> nativeRedirections =
|
||||
_nativeEmitter.typeRedirections;
|
||||
|
||||
Ruleset ruleset = Ruleset.empty();
|
||||
Ruleset ruleset = Ruleset.empty(_dartTypes);
|
||||
Map<ClassEntity, int> erasedTypes = {};
|
||||
Iterable<ClassTypeData> classTypeData =
|
||||
fragment.libraries.expand((Library library) => library.classTypeData);
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
|
||||
/*two-frag.library:
|
||||
a_pre_fragments=[
|
||||
p1: {units: [4{libB}, 1{libA}], usedBy: [p2, p3], needs: []},
|
||||
p2: {units: [3{libA, libC}, 6{libC}], usedBy: [p3], needs: [p1]},
|
||||
p3: {units: [2{libA, libB, libC}, 5{libB, libC}], usedBy: [], needs: [p2, p1]}],
|
||||
p1: {units: [4{libB}, 1{libA}], usedBy: [p3], needs: []},
|
||||
p2: {units: [6{libC}], usedBy: [p3], needs: []},
|
||||
p3: {units: [2{libA, libB, libC}, 5{libB, libC}, 3{libA, libC}], usedBy: [], needs: [p2, p1]}],
|
||||
b_finalized_fragments=[
|
||||
f1: [4{libB}, 1{libA}],
|
||||
f2: [6{libC}],
|
||||
|
|
|
@ -80,30 +80,28 @@
|
|||
/*three-frag.library:
|
||||
a_pre_fragments=[
|
||||
p1: {units: [26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}], usedBy: [p2], needs: []},
|
||||
p2: {units: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [p4, p3], needs: [p1]},
|
||||
p3: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [p4], needs: [p2]},
|
||||
p4: {units: [2{b1, b2, b3, b4, b5}], usedBy: [], needs: [p2, p3]}],
|
||||
p2: {units: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}], usedBy: [p3], needs: [p1]},
|
||||
p3: {units: [2{b1, b2, b3, b4, b5}, 24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}], usedBy: [], needs: [p2]}],
|
||||
b_finalized_fragments=[
|
||||
f1: [26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}],
|
||||
f2: [9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}],
|
||||
f3: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}],
|
||||
f4: [2{b1, b2, b3, b4, b5}]],
|
||||
f3: [2{b1, b2, b3, b4, b5}, 24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}]],
|
||||
c_steps=[
|
||||
b1=(f4, f3, f2, f1),
|
||||
b2=(f4, f3, f2, f1),
|
||||
b3=(f4, f3, f2, f1),
|
||||
b4=(f4, f3, f2, f1),
|
||||
b5=(f4, f3, f2, f1)]
|
||||
b1=(f3, f2, f1),
|
||||
b2=(f3, f2, f1),
|
||||
b3=(f3, f2, f1),
|
||||
b4=(f3, f2, f1),
|
||||
b5=(f3, f2, f1)]
|
||||
*/
|
||||
|
||||
/*two-frag.library:
|
||||
a_pre_fragments=[
|
||||
p1: {units: [12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}], usedBy: [p2], needs: []},
|
||||
p2: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}], usedBy: [p3], needs: [p1]},
|
||||
p1: {units: [8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}], usedBy: [p2], needs: []},
|
||||
p2: {units: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}], usedBy: [p3], needs: [p1]},
|
||||
p3: {units: [2{b1, b2, b3, b4, b5}], usedBy: [], needs: [p2]}],
|
||||
b_finalized_fragments=[
|
||||
f1: [12{b1, b3, b5}, 8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}],
|
||||
f2: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}],
|
||||
f1: [8{b1, b3, b4}, 11{b1, b2, b5}, 7{b1, b2, b4}, 5{b1, b2, b3}, 30{b4, b5}, 27{b3, b5}, 26{b3, b4}, 21{b2, b5}, 19{b2, b4}, 18{b2, b3}, 10{b1, b5}, 6{b1, b4}, 4{b1, b3}, 3{b1, b2}, 31{b5}, 29{b4}, 25{b3}, 17{b2}, 1{b1}],
|
||||
f2: [24{b2, b3, b4, b5}, 16{b1, b3, b4, b5}, 15{b1, b2, b4, b5}, 13{b1, b2, b3, b5}, 9{b1, b2, b3, b4}, 28{b3, b4, b5}, 23{b2, b4, b5}, 22{b2, b3, b5}, 20{b2, b3, b4}, 14{b1, b4, b5}, 12{b1, b3, b5}],
|
||||
f3: [2{b1, b2, b3, b4, b5}]],
|
||||
c_steps=[
|
||||
b1=(f3, f2, f1),
|
||||
|
|
|
@ -15,7 +15,19 @@
|
|||
lib3=(f2)]
|
||||
*/
|
||||
|
||||
/*two-frag|three-frag.library:
|
||||
/*two-frag.library:
|
||||
a_pre_fragments=[
|
||||
p1: {units: [1{lib1}], usedBy: [p2], needs: []},
|
||||
p2: {units: [2{lib1, lib3}, 3{lib3}], usedBy: [], needs: [p1]}],
|
||||
b_finalized_fragments=[
|
||||
f1: [1{lib1}],
|
||||
f2: [3{lib3}]],
|
||||
c_steps=[
|
||||
lib1=(f1),
|
||||
lib3=(f2)]
|
||||
*/
|
||||
|
||||
/*three-frag.library:
|
||||
a_pre_fragments=[
|
||||
p1: {units: [1{lib1}], usedBy: [p3], needs: []},
|
||||
p2: {units: [3{lib3}], usedBy: [p3], needs: []},
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
"id": "outputUnit/1",
|
||||
"kind": "outputUnit",
|
||||
"name": "1",
|
||||
"size": 895,
|
||||
"size": 834,
|
||||
"filename": "out_1.part.js",
|
||||
"imports": [
|
||||
"lib1"
|
||||
|
|
Loading…
Reference in a new issue