w3c / webidl2.js

WebIDL parser
https://w3c.github.io/webidl2.js/checker/
MIT License
249 stars 63 forks source link

Example usage? #647

Open greggman opened 2 years ago

greggman commented 2 years ago

Is there docs or an example of using this to look at the AST externally?

What I mean is, looking in the code, write ends up calling each object's private write function. Effectively parse(idl).map(t => t.write()); but let's say I wanted to generate HTML. How would I go about doing this? All the types are private and so I end up looking at random fields to try to guess the type. Even if I could branch on the type (as in if (x instanceof Typedef) etc that seems very hacky (lots of ifs)

Is there some helper to help me walk the AST to visit each node or an example of doing so?

saschanaz commented 2 years ago

Not sure what specific purpose you have, but there is a work to prettify IDL using this library: https://github.com/w3c/respec/blob/e6d12149e82106fb3c034c1f7bd0735ae9075aff/src/core/webidl.js#L27-L131

All the types are private and

It's not that the types are private, it's just that the type library is not up to date 🥲 (#255)

greggman commented 2 years ago

It's not about the types being private, it's about not having to manually check types as in

   // anti-pattern?
   if (node instanceof Enum) {
      ...
   } else if (node instanceof Typedef) {
     ...
   } else if (node instanceof Namespace) {
     ...
   } else if (node instance of Interface) {
      ...
   } ... repeat for every type ....

Whether I use node instanceof SomeType or node.type === "someType" it seems more common to expect some other way to walk an AST than having to manually check each type?

As for what I'm trying to do. I'm trying to generate a nested display. So for example if I have

enum Color {
  "red",
  "green",
  "blue",
}
dictionary Baz {
    Color background;
    double opacity;
};

dictionary Moo {
   double width;
   double heigh;
};

dictionary Foo : Bar {
    required Baz baz;
    Moo moo;
};

Then I want to generate something like

{  // Foo
   baz: { // Baz
       background: "red" | "green" | "blue",
       opacity: Number
   },
   moo: { // Moo (optional)
       width: Number,
       height: Number,
   },
};

Maybe a large set of ifs handling each different AST type is what I need but it seemed like maybe there was a better way I'm missing

saschanaz commented 2 years ago

Hmm, could you provide a pseudo-code that you expect to work? I can see what others do (babel etc.) and follow them, but understanding your specific requirement will probably be more helpful.

greggman commented 2 years ago

Sorry, I'm not sure what I'm looking for 😅 I was just asking of there was more I was overlooking.

AFAIK, as it is, if I want to do what I wrote above I have to dig into the internals of the classes if Enum walk values, if Typedef walk members, etc... where as often AST libraries have some kind of utilities that let the library deal with the internals. For example, Babel has traversers/visitors

https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-traversal

Anyway, I don't want to ask for any work on your part. I'll try to figure out a solution with what's there and then maybe I can suggest a solution and a PR if one comes up.

dontcallmedom commented 1 year ago

WebIDL2.js exposing a traversal API would sure be nice

saschanaz commented 1 year ago

WebIDL2.js exposing a traversal API would sure be nice

This is kinda done in the writer API, you can theoretically use the writer API and then ignore the return value.