ソースコードの定義へジャンプ
導入
こんにちは!久しぶりにクールな機能をしてきました.最近仕事をしてきたんですけどね.
この機能は定義にジャンプします(私はポストの残りの部分でJTDを省略します)、そしてソースコードをよりナビゲート可能にすることができます.
TLドクター
この機能の例を見るには、次のリンクを参照できます.
Prelude.JSON.renderAs
https://hydra.dhall-lang.org/build/70743/download/1/docs/JSON/renderAs.dhall.html JumpTo
このリストのプレフィックスhttps://hydra.dhall-lang.org/build/70746/download/1/docs/ 定義へジャンプ
あなたのプロジェクト(どんなプログラミング言語でも)のためにドキュメンテーションジェネレータを使用する主な目的は、あなたのユーザーがあなたのライブラリ/フレームワーク/パッケージ/何を使うかを学ぶことを簡単にすることです.ソースコードコメントの解析などの簡単なこと
dhall-docs
すでに十分ですが、我々は常にコードを発見しやすく読みやすくする機能を追加することができます.定義へのジャンプは、ほとんどのドキュメントジェネレータツールが持っている機能です.使いましょう
haddock
例としてhaddock
Haskellパッケージのドキュメントを生成します.dhall
例えばパッケージです.Dhall.Core
再エクスポートDhall.Syntax
) https://hackage.haskell.org/package/dhall-1.34.0/docs/Dhall-Core.html ; haddock
ソースコードをレンダリングしますDhall.Syntax
モジュールhttps://hackage.haskell.org/package/dhall-1.34.0/docs/src/Dhall.Syntax.html Dhall.Syntax
, 次のようになります.Expr
データタイプ:dhallのAST.dhall-docs
: ファイルを取ると、各名前が定義されている場所を参照するには静的な分析を行うと、ユーザーがそれをホバリングし、ユーザーがクリックしたときにその名前の定義にジャンプするときに正しくそれを強調表示します.実装
ダムオールスターズ
The
Expr
からのデータ型dhall
パッケージはパースされた式のソーススパンを取得するのに便利なコンストラクタです.data Expr s a =
...
| Note s (Expr s a)
...
あなたはそのハドックを見ることができますhere )…の目的
Note
問題のある表現を強調することで有用な構文解析と型エラーを作成することです.dhallパーサが出力するExpr Src Import
解説Src
and Import
が見つかるExpr
haddock ) それぞれの有意義な表現がNote
コンストラクタ.Src
sは、解析された式(例えばソーステキストと線とコラム番号)に関するメタデータ情報を含みます.たとえば、次の式があります.1 + 2
それは何か(このように)解析されます.Note (source code info of the "1 + 2" expression)
(NaturalPlus -- for the `+` operator
(Note (source code info for the "1") (NaturalLit 1))
(Note (source code info for the "1") (NaturalLit 2))
)
その他Note
, ソースコードについての余分な情報を保持する他のコンストラクターがあります.それは主にdhall format
and dhall lint
コマンド.コードレンダラ
今の質問は、どのように操作することができます/トラバース
Expr
次のHTMLを生成する方法では?-- we will come to the ??? later
data NameDecl = NameDecl Src Text ???
data SourceCodeType
= ImportExpr Dhall.Import
| NameUse NameDecl
| NameDeclaration NameDecl
data SourceCodeFragment = SourceCodeFragment Src SourceCodeType
あなたはそれぞれを考えることができますSourceCodeFragment
ソースコードの次のセクションとして.トークンに似ています(しかし、厳密にはそうではありません).一人一人が差別されるSourceCodeType
, これはHTMLでコードをどのようにレンダリングするかの情報を持っています.今、私たちは
Expr Src Import
に[SourceCodeFragment]
そしてそれはfragments
機能が来るfragments :: Expr Src Import -> [SourceCodeFragment]
の実装fragments
関数は、このポスト(正確にするために、110行)に収まるのに非常に大きいです、しかし、それがすることは、生成するためにASTで単純な文脈分析を走らせることですSourceCodeFragment
名前が宣言され使用されるたびに.名前が宣言されていないとき、名前が未使用で、そのHTMLにハイライトが表示されていない場合SourceCodeFragment
)すべての仕事は
infer
関数、内部宣言fragments
:-- explanation for ??? will come up later
infer :: Dhall.Context NameDecl -> Expr Src Import -> Writer [SourceCodeFragment] ???
Dhall.Context
ASTを横断するとき、名前を挿入して、問い合わせることができる文脈テーブルです.それが意味をなすとき、我々は名前を挿入します(すなわち、結合、記録フィールドとラムダパラメタをさせてください).この作品はすべて許される
dhall-docs
次の定義にジャンプします.について
???
コードで?LET結合とラムダ引数名は同じJTD論理を共有します:
Let
and Lam
それに応じてコンテキストに名前を追加する.foo
ユーザーがfoo
セレクタ式a.foo
:let a = { foo = 2 }
in a.foo
プッシュfoo
文脈へのラベルは正しい解決ではありませんfoo
ラベルは複雑です.代わりに、別のデータ型を使用することです.
data JtdInfo
= RecordFields (Set.Set NameDecl)
| NoInfo
???
対応JtdInfo
. あなたは考えることができますJtdInfo
余分な情報としてより正確に生成されたJTDを支援する静的解析から回復した.置換???
上のスニペットでは、data NameDecl = NameDecl Src Text JtdInfo
infer :: Dhall.Context NameDecl -> Expr Src Import -> Writer [SourceCodeFragment] JtdInfo
現在NameDecl
関連付けがあるJtdInfo
, を返しますJtdInfo
からinfer
. 今、我々はパターンにマッチすることができますField
JTDを正しく設定するコンストラクタField e (FieldSelection (Just Src{srcEnd=posStart}) label (Just Src{srcStart=posEnd})) -> do
fields <- do
dhallType <- infer context e
case dhallType of
NoInfo -> return mempty
RecordFields s -> return $ Set.toList s
let src = makeSrcForLabel posStart posEnd label
let match (NameDecl _ l _) = l == label
case filter match fields of
x@(NameDecl _ _ t) : _ -> do
Writer.tell [SourceCodeFragment src (NameUse x)]
return t
_ -> return NoInfo
それが意味するならば、我々はJTDをセットアップします.感謝のパターンマッチングは、エレガントなすべてのケースを扱うことができます.終わる
これは私がGSoCプロジェクトの一環として開発した最後の機能です.すべてのプロジェクトと私のすべての経験についての話の概要についての私の最後のレポートを読むために調整してください.
読書ありがとう!
Reference
この問題について(ソースコードの定義へジャンプ), 我々は、より多くの情報をここで見つけました https://dev.to/german1608/jump-to-definition-on-source-code-4fioテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol