This repository has been archived by the owner on Mar 14, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 20
Haddock experiment (WIP) #166
Open
kostmo
wants to merge
2
commits into
atom-haskell-archive:master
Choose a base branch
from
kostmo:haddock-experiment
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
COMMENT_PREFIX = "-- "; | ||
DOCSTRING_PREFIX = COMMENT_PREFIX + "| "; | ||
|
||
|
||
function setdefault(dict, key, value) { | ||
if (!(key in dict)) | ||
dict[key] = value; | ||
return dict[key]; | ||
} | ||
|
||
|
||
function findDocsForSymbol(docs_by_module, symbol) { | ||
|
||
var module_qualification_chunks = symbol.split("."); | ||
var last_chunk = module_qualification_chunks[module_qualification_chunks.length - 1] | ||
|
||
for (var mkey in docs_by_module) { | ||
var module_dict = docs_by_module[mkey]; | ||
|
||
for (var skey in module_dict) { | ||
if (skey == last_chunk) { | ||
return module_dict[skey]; | ||
} | ||
} | ||
} | ||
return "-- <no documentation>"; | ||
} | ||
|
||
function parseHoogleTextDoc(file_contents) { | ||
lines = file_contents.trim().split('\n'); | ||
|
||
var current_module = null; | ||
var docstring_lines = []; | ||
|
||
// Nested dict; outer key is module name. | ||
// inner key is function/variable name. | ||
var entity_docs_map = {}; | ||
|
||
for (var i=0; i<lines.length; i++) { | ||
var line = lines[i]; | ||
|
||
if (line.startsWith(COMMENT_PREFIX)) { | ||
docstring_lines.push(line); | ||
} else { | ||
|
||
var tokens = line.split(/\s+/); | ||
|
||
if (tokens.length > 0) { | ||
if (tokens[0] == "module") { | ||
current_module = tokens[1]; | ||
} else { | ||
|
||
if (current_module != null) { | ||
if (tokens.length > 1) { | ||
if (tokens[1] == "::") { | ||
var entity_name = tokens[0]; | ||
if (docstring_lines.length > 0) { | ||
var sub_dict = setdefault(entity_docs_map, current_module, {}); | ||
sub_dict[entity_name] = docstring_lines.join("\n"); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
docstring_lines = []; | ||
} | ||
} | ||
|
||
return entity_docs_map; | ||
} | ||
|
||
exports.parseHoogleTextDoc = parseHoogleTextDoc; | ||
exports.findDocsForSymbol = findDocsForSymbol; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I'm piggybacking this experimental functionality on the Info+Type display, which is the default tooltip behavior in the package.
I've created a promise as
docP
which returns a value indoc
. For some reason the value ofdoc.text.text
displays asundefined
in the tooltip.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.
If you're trying to debug it, you might consider using
JSON.stringify(doc)
instead of this long-winded construction.That said, I have two thoughts on this whole thing. First, I would think that since this has virtually nothing to do with ghc-mod, this would be better-suited to be provided as a separate package, unless it eventually does (see below).
Second, there's some work wrt haddock happening on ghc-mod, which you might want to take a look at: DanielG/ghc-mod#810
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.
Wow, that
ghc-imported-from
merge is exciting. I feel like I should put my effort on hold until that is finished.Pardon the digression from Haddock, but it seems like that
ghc-imported-from
project could also improve the reliability of the "Go to Declaration" functionality. Would you agree? I saw your comment in atom-haskell/ide-haskell#137 that there are two ways to "Go to Declaration", provided by either theide-haskell-hasktags
package orhaskell-ghc-mod
package. However, for me neither seem to properly handle jumping to function definitions that are qualified imports. To me it's unfortunately ironic, as jumping to a declaration that is "far away" (i.e. in a differnt file) is the more valuable automation.I saw your other comment in atom-haskell/ide-haskell#110 that indicated some limitations:
haskell-ghc-mod
:ide-haskell-hasktags
:With regard to
haskell-ghc-mod
, were you referring to symbols that are not explicitly given in a module's export list? For me, symbols from a different module are rarely found regardless. Sometimes, when I mouseover a symbol, I see the following in the console:In that case, I of course cannot "Go to Declaration" with
haskell-ghc-mod
eitiher.In other cases, I am able to mouseover a qualified-imported symbol and see the "info" tooltip, and it even says
-- Defined in Foo.Bar.Blah
, but "Go to Declaration" will not take me there. I believe that this happens when the symbol is in a different local package (which happens to be one of two listed in mystack.yaml
file.Regarding
ide-haskell-hasktags
, it is much faster thanhaskell-ghc-mod
for jumping to declarations in the same module, but it also suffers from the inability to jump to symbols that are external to the current module when those symbols are qualified imports.Would it be valuable for me to submit some test cases to demonstrate these exact problems? I'd also try my hand at fixing the problems.
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.
It's not about qualified imports (if actual qualified imports fail, file a bug with a testcase -- those should work), but rather cross-package imports I believe? Horrible truth is, ghc is not aware of any cross-package source files -- packages are compiled. So jumping source files between packages is problematic.
Hasktags just parses all open Atom projects for Haskell sources and collects top-level declarations. So it stands to reason that it's faster. Besides, if you need to jump sources between two packages, you can just open both as Atom projects and that should work. There's a caveat with symbols sharing the same name: hasktags has no way to distinguish those, since it's not context-aware, unlike ghc-mod.
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.
Hi, I have created minimal test cases that demonstrate various failure modes of "Jump to Declaration" for both
haskell-ghc-mod
andide-haskell-hasktags
in this demo project.In summary:
haskell-ghc-mod
never works "across" packageside-haskell-hasktags
works both within the same package and "across" packages when:haskell-ghc-mod
does not work when a symbol is qualified by a renamed import, unless one manually highlights the symbol alone while excluding the leading namespace and period.Are the latter two items known limitations?
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.
@kostmo, thank you for your work, but please file new issues against relevant packages or at least ide-haskell in the future. It's hard enough to maintain this mess as it is.
So second point is an oversight on my part, should be fixed by ide-haskell-hasktags-0.0.6.
Third point seems to be a problem with ghc-mod -- it seems it doesn't resolve import aliases to files. Can't tell from the top of my head if it's easy to fix, or even fixable in principle -- it's very probable that it's a limitation of GHC API.