はじめに
Emacsでeglot-jlを使って関数等の補完をしていた時に, 自作のモジュールを読み込んだ時に不意にLanguageServerが落ちることが頻発した。 というか,100%落ちてしまいどうにもならなくなった。
丸二日調べてようやく原因が分かった。
で,結構他の人でもはまるかもしれないと思い,ここに情報を公開することとした。
どんな時に発生するか?
パッケージの構成としては,次の図のようなフォルダ構造になるのだが,この構造の
MyPackage/srcの中に.で始まるファイルやディレクトリが存在するとLanguageServerの
エラーが発生するようだ。

エラー発生原因の箇所
個人的に問題と思っているのはSymbolServer/src/utils.jlのところで,ソースは次のような感じ。
function sha2_256_dir(path, sha=zeros(UInt8, 32)) (uperm(path) & 0x04) != 0x04 && return startswith(path, ".") && return if isfile(path) && endswith(path, ".jl") s1 = open(path) do f sha2_256(f) end sha .+= s1 elseif isdir(path) for f in readdir(path) sha = sha2_256_dir(joinpath(path, f), sha) end end return sha end
ここで,startswidth(path, ".") && return のreturnが問題で,
本来shaに準ずるものが返らないといけないのが,値無しで返っている。
上の関数の呼び出し元はsha_pkg
という関数で,ソースは次の通り。
function sha_pkg(manifest_dir::AbstractString, pe::PackageEntry) relpath = path(pe) isa(relpath, String) || return nothing src_path = normpath(joinpath(manifest_dir, relpath, "src")) return isdir(src_path) ? sha2_256_dir(src_path) : nothing end
つまり,パッケージのsrc以下の.jlファイルのsha2サム値の合計をpkgのshaサム値として返そうというものらしい。
しかし,何からの原因でsrcフォルダ内に.で始まるファイル等があるとLanguageServerでエラーが発生することになる。
影響
srcフォルダの中にEmacs等で一時的に.で始まるファイルを作成したり,現実的には.gitignoreファイルを作成した時に
必ずエラーが発生する等の影響があると思われる。
対策
srcフォルダの中には.で始まるファイル・フォルダを作成しないようにする必要がある。
悪用方法
srcフォルダの中に.gitignoreを作成して,他人にLanguageServerの補完をさせないようにする等の
活用方法が考えられる。
さいごに
なお,本来の対策としては
startwith(path, ".") && return
のところを
startwith(path, ".") && return sha
とすると,.で始まるファイルだった時はshaをそのまま返すので
簡易的な対策になると思います。というかそうすべき。
ですが,私は性格が悪いので,黙ってこのまま放置しようと思います。 誰か正義のミカタがissueを上げることを期待してこの記事を終わりにしようと思います。