material-motion / apidiff

Generate API diffs as markdown for Objective-C, Swift, and Android libraries.
Apache License 2.0
116 stars 11 forks source link

[javascript] Support javascript libraries? #4

Open pingpongboss opened 8 years ago

pingpongboss commented 8 years ago

Open question.

appsforartists commented 8 years ago

Here are some AST parsers for JS:

Here are some things that came up when I searched for JS AST diffing:

What's needed to build something like this? Writing a tool to diff ASTs and glean meaningful data out of the diffs sounds non-trivial.

pingpongboss commented 8 years ago

Extract Structured Form of Public API

This is the hard part.

You need an enumeration of the public API: public class signatures, their public method signatures, and their public field signatures. Maybe javascript's definition of a public API is different, you'll have to figure that out.

The enumeration can be in any structured form. For example:

It seems like you've found several tools that can parse javascript and generate an AST. Babylon looks promising with ClassDeclaration, ClassMethod, ObjectMethod, FunctionDeclaration, VariableDeclaration, etc. My gut says that most of the "AST diffing" tools may lead you in the wrong direction. They're mainly concerned with replacing line-by-line diff, but you're only interested in the public APIs not their implementations.

The next few steps are quite easy and can borrow heavily from the iOS and Android scripts.

Parse Public API into Intermediary Format

You'll parse that AST and extract only the information you need into an intermediary format for easy processing. This is done for both the old AST and new AST.

Example: iOS Android

Calculate Changes between Public APIs

Your intermediary format should make this easy.

Example: iOS Android

Print Changes in Markdown

Example: iOS Android

appsforartists commented 8 years ago

Thanks. That's helpful info.

It could be especially hard in JS because JS is a dynamic, untyped language. Therefore, you can write the same code in a handful of different ways, generating different ASTs for semantically equivalent code.

To attract internal clients, we're going to need to use a type system. Which one is still an open question, but internal teams are going to expect Closure annotations. Thus, even if we chose TypeScript or Flow, we'll still be generating Closure annotations from those formats to support most people in Piper.

Since we're going to need Closure annotations for all our public-facing APIs anyway, that's probably a reasonable boundary for diffing.

The Closure tool is written in Java. We could presumably create a CompilerPass that writes the AST as a JSON file that apidiff understands.

There's also a JavaScript tool that generates documentation from Closure annotations called JSDoc. I haven't dug into it deeply enough to see how it builds/stores its AST, but since Closure compatibility is essential, it might be better to use the Closure tool to generate our AST. If there are any deviations between Closure and JSDoc, we should stay on the Closure side.

I wonder if this is an area @MatrixFrog is interested in. Presumably, we're not the only team that would find an API diff tool for Closure-annotated code helpful.

MatrixFrog commented 8 years ago

I think @joeltine was looking at doing something similar.

appsforartists commented 8 years ago

+@jleyba

appsforartists commented 7 years ago

@tofuness You may find this interesting. Eventually, we'll want a tool that can spit out API changelogs comparing two releases. Click that link for example output from Objective-C, but effectively, we want to be able to compare two APIs:

write({ stream: MotionObservable, to: Property })
write({ from: MotionObservable, to: Property })

and see something like:

runtime.write

removed named parameter: stream added named parameter: from

TypeScript's API will probably be helpful in this.

Is this something you'd want to take astab at?