-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
flow shadow-file
#2184
flow shadow-file
#2184
Conversation
@facebook-github-bot import |
Thanks for importing. |
@facebook-github-bot update |
might I suggest the name |
@@ -0,0 +1,66 @@ | |||
open CommandUtils |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing copyright header
So I'd like us to get away from using Specifically: There's a lot of confusion right now around the differences between I wrote up some sample documentation here that I'd like to move into docs soon (maybe in this diff): #1996 (comment) I'm not necessarily tied to |
I should be able to circle back and update the "libdef" and "shadow files" docs either this weekend or Monday. |
12a5932
to
78678f2
Compare
|
7788a38
to
e6dad12
Compare
|
Thanks for the updates. I'm still not convinced on the name "shadow-file". You've previously suggested that users should write |
I've sort of gone back and forth on this, too. At the moment I'm stuck on the "it's not perfect, but not that unclear" side (you write a flow file that shadows the real, compiled, JS file).
That's right. Depending on how you interpret "shadow", this still seems to make sense to me -- but maybe I've just gotten used to it after thinking about it for a little while now. I'm still pretty open to names other than "shadow" if you have any suggestions, though? "shadow" is just the best I was able to come up with so far. The only things I want to avoid are the terms "lib"/"def" (too confusingly similar to "[libdefs]"), and "decl"/"declare" (doesn't adequately distinguish libdefs, which have I suppose we could name the command |
declared_classes: string IMap.t; | ||
mutable next_declared_class_name: int; | ||
flow_cx: Context.t; | ||
indent: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused right now
When I initially saw the PR with Usually when I explain libdefs / js.flow files to others, I usually called them |
I don't think we're discussing what to call all kinds of .js.flow files here, only what to call .js.flow files which happen to contain only I think we should call these declaration files, because they only contain declarations. "libdefs" from the builtins or I'd call all forms of |
This is great. I am especially happy that this encoding will prevent issues where config differences between lib and consumer cause errors, as you pointed out in your description. Does this work for files that import types/values from other modules? Can you include some tests for generating shadow files for modules with dependencies? Since you're generating the declarations from types, I assume suppression types just come out as any, correct? Type aliases/annots are substituted by their definition as well, yes? What about generating shadow files for many modules at once? I think that could be a common use case, for example fbjs's build step copies over all files. Is there any perf gain to be had with a batch mode? |
let id = env.next_declared_class_name in | ||
env.next_declared_class_name <- id + 1; | ||
id | ||
let resolve_type t env = Flow_js.resolve_type env.flow_cx t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On mobile so forgive an unresearched comment: I think Flow_js.resolve_type will return any
for open tvars, so ideally this should happen after merge. Does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, the expectation is that the cx
passed into Codegen.mk_env
is fully merged.
This is a level of nuance that we want to avoid. The mental model needs to be simple, and currently it is: People seem to understand this model once described in this way, so I want to avoid breaking things down into any further categories of files. TS's story around interface/decl/typings files is all over the place with terminology and I've always found it confusing in conversations about them -- so this has motivated a strong need to keep things simple and minimal as we build out our story here. |
Good call, I'll add some tests. In the beginning I expect these imported types to simply be flattened into the declared types, but once we work out our story around imports between libdefs we can take that approach.
That's right, but I should add tests to prove it
Right now this only takes a single file on the command line and prints the results to stdout (first-version simplicity). The server command is intentionally set up to accept multiple files and return multiple results to support multi-file generation though. It might be a little better to do this in a follow-up. |
These files can include imports though, right? They're JS files including declarations, not lib defs iiuc. In fact, you probably need that in order to use class types (nominal) from other modules. |
Oh, good point -- they can include imports, you're right. I'll need to work that in then |
So I agree with that mental model, but this command doesn't generate all types of shadow files, it generates a very specific subset: the declarations/interface of some real JS file. Why does a command called All I'm suggesting is that the name should reflect what the command does. |
The purpose of the command is to generate a Truthfully though, I don't think it's necessary to be completely precise in the name as long as it's not incorrect. In this case, generating a shadow/ If it's any consolation: If we ever do discover a good reason to generate non- |
4748862
Summary: This adds a new command, `flow gen-flow-files path/to/file.js`, which generates the minimal `.js.flow` interface file that can be used for publishing compiled Flow source. Specifically: It generates only `import`, `declare`, and `declare export` statements in order to omit all the implementation text. Background: Currently the best practice for publishing Flow source is (roughly): 1. `cp src/foo.js dist/foo.js.flow` 2. `babel src/foo.js > dist/foo.js` This mostly works, but has a few downsides: 1. The published contents of `dist/*` are much larger than they need to be -- they contain a pre-compiled copy of all the original source. This is basically just crufty bytes that need to be downloaded every time the package is `npm install`-ed. 2. The published `.js.flow` files contain implementation details -- which are much more susceptible to breaking changes across Flow versions. While breaking changes across Flow version are still possible even in `declare` statements, this happens *far* less often. 3. We also want to re-use this type -> code codegen infrastructure to generate libdefs for flow-typed at some point. This particular diff is only about `.js.flow` files (i.e. no `declare module ...` statements) -- but that can be added on in a follow up diff. This diff includes a new `codegen.ml` file which exposes an API intended for generating code from various things (types for now, possibly ASTs at some point if that's useful/performant/worth the effort). It's minimal in terms of feature-set right now but we can expand/improve it later. I didn't use `type_printer.ml` because it only handles some types and many of the types it will print aren't actual code or easily composable with other bits of code. It's also used by lots of stuff that I didn't really want to investigate breaking changes for while building out this feature. At some point it probably makes sense to either improve `Type_printer` enough to subsume `Codegen` or the other way around. I suspect the `Codegen` is going to be easier to generalize, but we'll leave that for a later time to look into. Closes facebook/flow#2184 Reviewed By: gabelevi Differential Revision: D3663107 Pulled By: jeffmo fbshipit-source-id: a791f85235f978fc9e5e46639e0dec37b71fad60
Summary: This adds a new command, `flow gen-flow-files path/to/file.js`, which generates the minimal `.js.flow` interface file that can be used for publishing compiled Flow source. Specifically: It generates only `import`, `declare`, and `declare export` statements in order to omit all the implementation text. Background: Currently the best practice for publishing Flow source is (roughly): 1. `cp src/foo.js dist/foo.js.flow` 2. `babel src/foo.js > dist/foo.js` This mostly works, but has a few downsides: 1. The published contents of `dist/*` are much larger than they need to be -- they contain a pre-compiled copy of all the original source. This is basically just crufty bytes that need to be downloaded every time the package is `npm install`-ed. 2. The published `.js.flow` files contain implementation details -- which are much more susceptible to breaking changes across Flow versions. While breaking changes across Flow version are still possible even in `declare` statements, this happens *far* less often. 3. We also want to re-use this type -> code codegen infrastructure to generate libdefs for flow-typed at some point. This particular diff is only about `.js.flow` files (i.e. no `declare module ...` statements) -- but that can be added on in a follow up diff. This diff includes a new `codegen.ml` file which exposes an API intended for generating code from various things (types for now, possibly ASTs at some point if that's useful/performant/worth the effort). It's minimal in terms of feature-set right now but we can expand/improve it later. I didn't use `type_printer.ml` because it only handles some types and many of the types it will print aren't actual code or easily composable with other bits of code. It's also used by lots of stuff that I didn't really want to investigate breaking changes for while building out this feature. At some point it probably makes sense to either improve `Type_printer` enough to subsume `Codegen` or the other way around. I suspect the `Codegen` is going to be easier to generalize, but we'll leave that for a later time to look into. Closes #2184 Reviewed By: gabelevi Differential Revision: D3663107 Pulled By: jeffmo fbshipit-source-id: 8f1147590e8bf48ebedb7b6ea5d1b720669c7518
This adds a new command,
flow shadow-file path/to/file.js
, which generates the minimal.js.flow
interface file that can be used for publishing compiled Flow source. Specifically: It generates onlydeclare
anddeclare export
statements in order to omit all the implementation text.Background: Currently the best practice for publishing Flow source is (roughly):
cp src/foo.js dist/foo.js.flow
babel src/foo.js > dist/foo.js
This mostly works, but has a few downsides:
dist/*
are much larger than they need to be -- they contain a pre-compiled copy of all the original source. This is basically just crufty bytes that need to be downloaded every time the package isnpm install
-ed..js.flow
files contain implementation details -- which are much more susceptible to breaking changes across Flow versions. While breaking changes across Flow version are still possible even indeclare
statements, this happens far less often..js.flow
files (i.e. nodeclare module ...
statements) -- but that can be added on in a follow up diff.This diff includes a new
codegen.ml
file which exposes an API intended for generating code from various things (types for now, possibly ASTs at some point if that's useful/performant/worth the effort). It's minimal in terms of feature-set right now but we can expand/improve it later. I didn't usetype_printer.ml
because it only handles some types and many of the types it will print aren't actual code or easily composable with other bits of code. It's also used by lots of stuff that I didn't really want to investigate breaking changes for while building out this feature.At some point it probably makes sense to either improve
Type_printer
enough to subsumeCodegen
or the other way around. I suspect theCodegen
is going to be easier to generalize, but we'll leave that for a later time to look into.