Skip to content

[ddc] Duplicated member signature information on some classes #52867

@nshahan

Description

@nshahan

In the compiled output, some classes have duplicated member signature information attached to them. For example, see the Iterable class in the compiled output:

class Iterable extends core.Object {
  ...
}
...
dart.setMethodSignature(Iterable, () => dart.global.Object.setPrototypeOf({
  cast: dart.gFnType(R => [core.Iterable$(R), []], R => [dart.nullable(core.Object)]),
  [$cast]: dart.gFnType(R => [core.Iterable$(R), []], R => [dart.nullable(core.Object)]),
  followedBy: dart.fnType(core.Iterable$(E), [dart.nullable(core.Object)]),
  [$followedBy]: dart.fnType(core.Iterable$(E), [dart.nullable(core.Object)]),
  map: dart.gFnType(T => [core.Iterable$(T), [dart.fnType(T, [E])]], T => [dart.nullable(core.Object)]),
  [$map]: dart.gFnType(T => [core.Iterable$(T), [dart.fnType(T, [E])]], T => [dart.nullable(core.Object)]),
  where: dart.fnType(core.Iterable$(E), [dart.fnType(core.bool, [E])]),
  [$where]: dart.fnType(core.Iterable$(E), [dart.fnType(core.bool, [E])]),
  whereType: dart.gFnType(T => [core.Iterable$(T), []], T => [dart.nullable(core.Object)]),
  [$whereType]: dart.gFnType(T => [core.Iterable$(T), []], T => [dart.nullable(core.Object)]),
  expand: dart.gFnType(T => [core.Iterable$(T), [dart.fnType(core.Iterable$(T), [E])]], T => [dart.nullable(core.Object)]),
  [$expand]: dart.gFnType(T => [core.Iterable$(T), [dart.fnType(core.Iterable$(T), [E])]], T => [dart.nullable(core.Object)]),
  contains: dart.fnType(core.bool, [dart.nullable(core.Object)]),
  [$contains]: dart.fnType(core.bool, [dart.nullable(core.Object)]),
  forEach: dart.fnType(dart.void, [dart.fnType(dart.void, [E])]),
  [$forEach]: dart.fnType(dart.void, [dart.fnType(dart.void, [E])]),
  reduce: dart.fnType(E, [dart.nullable(core.Object)]),
  [$reduce]: dart.fnType(E, [dart.nullable(core.Object)]),
  fold: dart.gFnType(T => [T, [T, dart.fnType(T, [T, E])]], T => [dart.nullable(core.Object)]),
  [$fold]: dart.gFnType(T => [T, [T, dart.fnType(T, [T, E])]], T => [dart.nullable(core.Object)]),
  every: dart.fnType(core.bool, [dart.fnType(core.bool, [E])]),
  [$every]: dart.fnType(core.bool, [dart.fnType(core.bool, [E])]),
  join: dart.fnType(core.String, [], [core.String]),
  [$join]: dart.fnType(core.String, [], [core.String]),
  any: dart.fnType(core.bool, [dart.fnType(core.bool, [E])]),
  [$any]: dart.fnType(core.bool, [dart.fnType(core.bool, [E])]),
  toList: dart.fnType(core.List$(E), [], {growable: core.bool}, {}),
  [$toList]: dart.fnType(core.List$(E), [], {growable: core.bool}, {}),
  toSet: dart.fnType(core.Set$(E), []),
  [$toSet]: dart.fnType(core.Set$(E), []),
  take: dart.fnType(core.Iterable$(E), [core.int]),
  [$take]: dart.fnType(core.Iterable$(E), [core.int]),
  takeWhile: dart.fnType(core.Iterable$(E), [dart.fnType(core.bool, [E])]),
  [$takeWhile]: dart.fnType(core.Iterable$(E), [dart.fnType(core.bool, [E])]),
  skip: dart.fnType(core.Iterable$(E), [core.int]),
  [$skip]: dart.fnType(core.Iterable$(E), [core.int]),
  skipWhile: dart.fnType(core.Iterable$(E), [dart.fnType(core.bool, [E])]),
  [$skipWhile]: dart.fnType(core.Iterable$(E), [dart.fnType(core.bool, [E])]),
  firstWhere: dart.fnType(E, [dart.fnType(core.bool, [E])], {orElse: dart.nullable(core.Object)}, {}),
  [$firstWhere]: dart.fnType(E, [dart.fnType(core.bool, [E])], {orElse: dart.nullable(core.Object)}, {}),
  lastWhere: dart.fnType(E, [dart.fnType(core.bool, [E])], {orElse: dart.nullable(core.Object)}, {}),
  [$lastWhere]: dart.fnType(E, [dart.fnType(core.bool, [E])], {orElse: dart.nullable(core.Object)}, {}),
  singleWhere: dart.fnType(E, [dart.fnType(core.bool, [E])], {orElse: dart.nullable(core.Object)}, {}),
  [$singleWhere]: dart.fnType(E, [dart.fnType(core.bool, [E])], {orElse: dart.nullable(core.Object)}, {}),
  elementAt: dart.fnType(E, [core.int]),
  [$elementAt]: dart.fnType(E, [core.int])
}, dart.getMethods(dart.global.Object.getPrototypeOf(Iterable))));

Each method has the same signature added twice, once with just a name and once with a "symbolized" name. I couldn't remove either of them without some tests failing so there must be some inconsistency in how we access the signatures at runtime.

Not all classes exhibit this pattern. Most have either just a name or just a symbol. It looks like the duplication was added long ago in the analyzer based version and it persisted when ported to kernel 749d298.

With the new runtime type system this issue also appears with the default type arguments for the instance methods that have type parameters. In order to be consistent with the method signature I had to duplicate them in the same way to get all of the lookups to work at runtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-web-jsIssues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop.web-dev-compiler

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions