Skip to content
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

Reexport docs #1770

Merged
merged 8 commits into from Jan 12, 2016
Merged

Reexport docs #1770

merged 8 commits into from Jan 12, 2016

Conversation

hdgarrood
Copy link
Contributor

Addresses #1677.

Changes:

  • Env is now exported by Language.PureScript
  • Added a variant of desugarImports which also returns the Env.
  • Generalise parseAndDesugar to any MonadIO m, MonadError P.MultipleErrors m
  • Make parseAndDesugar also return the Env.
  • Remove the useless callback parameter to parseAndDesugar (what was I thinking??)
  • Add a re-exports field to the Module type in Language.PureScript.Docs
  • Print re-exported values in psc-docs.

For now, I just want to see if this passes CI (for some reason, tests aren't working on my machine). Before merging, this still needs:

  • History cleanup
  • Tests

@hdgarrood
Copy link
Contributor Author

This is what Neon from purescript-neon looks like with these changes: https://gist.github.com/hdgarrood/b55b7dd7e9e1ca43b7b2

/cc @tfausak

@hdgarrood
Copy link
Contributor Author

Oh also, fixes #1681

@tfausak
Copy link
Contributor

tfausak commented Dec 29, 2015

👍 Looks great!

@hdgarrood
Copy link
Contributor Author

Ok, this seems to work. I think it's ready for review. I cleaned the history up so that you can probably review them each individually.

@hdgarrood
Copy link
Contributor Author

Actually, this is not quite there yet.

m Module
expandReExports env ast@(P.Module _ _ mn' _ mexports) mdl = do
let exports = fromMaybe (err "exports were not elaborated") mexports
let reExportNames = mapMaybe takeReExport exports
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One problem with this code is that it can't handle re-exported virtual modules (see also: examples/docs/Virtual.purs: https://github.com/hdgarrood/purescript/blob/reexport-docs/examples/docs/src/Virtual.purs, which, with this code, would cause an internal compiler error).

I want to get a list of all the (real) modules from which values are being re-exported, but I don't want the modules they were originally exported from; I want the modules they were imported from the current module's point of view, that is, I don't want it to follow the whole path of re-exports of re-exports.

This seems to work but of course it chokes on virtual modules. I'm not particularly familiar with this part of the compiler, so I'd appreciate some guidance.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The information you're after isn't really accessible, as the renaming never takes the intermediate step, it always has multiply-re-exported values pointing at the original export locations.

What's actually the problem with that? You'll have to manually follow the chain of the links through the docs back to the original module if you want to get the definition's comments anyway, so this just takes those steps out of it...

Instead of grouping the re-exported values under a heading for each module, why don't we just lump them all under "Re-exported definitions" in general, and then show the original module info per re-exported member instead? That'd cut down on the number of headers at least, if that's one of the concerns.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not worried about the number of headings; I arrived at this design because I think it's the best way of presenting this information.

Suppose we have a ByteString type defined in Data.ByteString.Internal, re-exported by Data.ByteString, and then re-exported again by some module A. In that case, I think we would want to write in A's docs that ByteString is re-exported from Data.ByteString. More generally, I think the documentation should present things the same way as they are in the source, because I think that's more likely to make sense to readers of the docs.

The reason for the call to sortModules in this code is to make sure dependencies have already been rendered; this way, we can include the whole declaration for re-exports, including comments, so you wouldn't have to follow the chain back to the source.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okidoke. I'm not sure what to suggest for now; the information you need is never constructed. I guess we'll have to change the way the imports/exports are handled to accumulate it somehow, either by reworking the data structures generally or maybe we can tack something in there that allows us to capture the info just for docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, maybe this is going to be a little harder then. Save this for after 0.8 perhaps?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, yeah. I'll have a quick look at the "tack on extra info" approach before giving up totally though, as I did that recently to fix the bug where it was warning about some module not existing when it's the value that was actually missing. I added a set of virtual modules to the Env, so perhaps we can change that into a Map and track the imported values there instead or something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I'm referring to if you want to take a look yourself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that does sound promising - I'll take a look :)

@hdgarrood
Copy link
Contributor Author

@garyb Your suggestion worked wonderfully! I fixed all the failing tests and cleaned up the history again. I think this is good to go now.

@garyb
Copy link
Member

garyb commented Jan 3, 2016

Nice 😄

Although I'm not too sure about the fixed part, seems the build is failing still.

@hdgarrood
Copy link
Contributor Author

Looks like it's the psc-publish tests which are failing. They pass on my machine, so I think they can be disabled for now. They aren't running in master at all at the moment anyway, because of a call to exitSuccess before we even reach those tests:

then exitSuccess

I can look at them again after this is merged.

@hdgarrood
Copy link
Contributor Author

Ah, no, the docs tests are actually faililng. cabal test seems to be swallowing stderr, too >:( https://travis-ci.org/purescript/purescript/jobs/99953632#L3171

@hdgarrood
Copy link
Contributor Author

Oh, no, it's just printing stdout and stderr out of order: https://travis-ci.org/purescript/purescript/jobs/99953632#L3090-L3097

How do we feel about running dist/build/tests/tests and dist/build/psci-tests/psci-tests explicitly, instead of cabal test?

@hdgarrood
Copy link
Contributor Author

Fixed now, I think. On second thoughts, I'd rather just leave the CI scripts alone.

@garyb
Copy link
Member

garyb commented Jan 4, 2016

Looks like it's still failing unfortunately, for the build with disttests enabled. The log is so massive I'm having a hard time seeing what's going wrong though... any ideas?

@hdgarrood
Copy link
Contributor Author

I think I just worked it out - the new examples, used in the new tests, weren't listed in extra-source-files in purescript.cabal, meaning the tests couldn't run out of an sdist. I just amended the commit and force pushed so hopefully it will work now.

--
, importedVirtualModules :: S.Set ModuleName
, importedVirtualModules :: M.Map ModuleName ModuleName
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is quite right actually, shouldn't it be M.Map ModuleName [ModuleName]? As you can have things like:

import A as X
import B as X

That makes the problem of figuring out where re-exports came from a little awkward again though, so maybe we actually need even more information in the RHS value (something like Imports again with qualified X.foo names pointing to the imported A.foo/B.foo names)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes, of course. Although maybe a [ModuleName] would be sufficient? I think we can look in the other fields of the Imports value for that information?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, all this code in Docs.Convert is worryingly similar to what's already in Sugar.Names, I think. How would you feel about instead adding a little extra information to the Exports data type, mentioning the first "real" module that declarations come from? Then, in Docs.Convert, we could just walk over the Exports value. We then wouldn't have to look at any DeclarationRef values, or Imports values, or anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's totally fine by me, it shouldn't complicate the names stuff much, right?

We're already on the second revision of the names stuff and I don't think it's any clearer what is going on than my first attempt at it (although it works much better this time) - I'd like to try yet again to make it a little easier to comprehend and extract this kind of info out of, but that's not something I want to get into right now 😉

@hdgarrood
Copy link
Contributor Author

Half a note to myself, half for the benefit of anyone reading this later:

I just had a closer look and I'm pretty sure all the information I need is already in the Env. The Imports value has the module things were imported from on the RHS; in the case of re-exports, it lists the module things were re-exported from. So I can iterate over the Exports, looking in the Imports for each exported thing to find which module I should display it as having come from. I'll also update the comments in Sugar.Names.Env to reflect this. :D

@hdgarrood
Copy link
Contributor Author

Ok now that I've looked a bit more, we don't quite have enough information as it is now. Take this example:

module Docs (module Clash1) where

import Clash1 as Clash1
import Clash2 as Clash2

And suppose both Clash1 and Clash2 re-export values called x from two different other modules.

Then, the Exports value for Docs tells me that a value called x is exported, and that x is originally defined in one of those two other modules, but the Imports values only lists them as having come from Clash1 or Clash2. So I can't work out which one is exported without also looking at the exports list. I'd rather add this information to the Env, I think, as the code in Sugar.Names.Env is probably best equipped to handle collecting this information.

@hdgarrood
Copy link
Contributor Author

Wait, we do! I was wrong, the Imports values lists both the module things are originally defined in as well as the module they were imported from (via the Qualified)! Just give me another day or two.

Add a variant of Language.PureScript.Sugar.Names.desugarImports which
also returns the Env, built up during desugaring imports.

We also export Env and related types (Imports, Exports), so that people
can get useful information out of the the Env value in this new variant.
* Generalised to work with any Monad which has both MonadIO and
  MonadError MultipleErrors instances
* Remove the useless callback parameter; now, just return the modules
  and bookmarks instead.
This new information will be necessary for documenting re-exports.
Clearly demarcate each section of the test suite.
This is what cabal seems to expect us to do.
In particular, tests for documentation for re-exports.
* Add a new field in Language.PureScript.Docs.Types.Module for
  re-exported declarations
* Split two child modules out of Language.PureScript.Docs.Convert:
  Single, which is essentially what Convert previously was, and
  ReExports, which handles re-exports.
* Handle re-exports while converting declarations for documentation
  (which were previously just ignored). Notably, converting docs can now
  throw MultipleErrors as a result (although if the code compiles
  normally, it should always succeed here too).
* Update Language.PureScript.Docs.AsMarkdown to include re-exports in
  the generated documentation.
* Export more values from Language.PureScript.Docs.AsMarkdown (because
  psc-docs needs them now)

As an incidental consequence of the above changes, this commit also
fixes #1681.
@hdgarrood
Copy link
Contributor Author

Ok, I think this is good to go now.

@garyb
Copy link
Member

garyb commented Jan 10, 2016

I'll review this sometime this evening. It'll be great to have it solved at last!

@garyb
Copy link
Member

garyb commented Jan 11, 2016

Looks good to me 👍

It's crazy how complicated selective re-exports make things unfortunately (I spent quite a few hours working stuff out related to them for the warnings today), but they are really rather useful.

@garyb
Copy link
Member

garyb commented Jan 12, 2016

@paf31 shall I merge this or do you want to review too / have any comments?

@paf31
Copy link
Contributor

paf31 commented Jan 12, 2016

@garyb If you're happy with everything, go ahead and merge. Thanks @hdgarrood!

@garyb
Copy link
Member

garyb commented Jan 12, 2016

Yeah, thanks @hdgarrood!

garyb added a commit that referenced this pull request Jan 12, 2016
@garyb garyb merged commit 604f69d into purescript:master Jan 12, 2016
@hdgarrood
Copy link
Contributor Author

🎆 you're welcome. :)

@hdgarrood hdgarrood deleted the reexport-docs branch January 12, 2016 19:34
@coveralls
Copy link

Coverage Status

Coverage increased (+0.7%) to 69.845% when pulling 95d7eb2 on hdgarrood:reexport-docs into 342c17f on purescript:master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants