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

C# 対応 #115

Open
kmyk opened this issue Jan 29, 2020 · 15 comments · May be fixed by #401
Open

C# 対応 #115

kmyk opened this issue Jan 29, 2020 · 15 comments · May be fixed by #401

Comments

@kmyk
Copy link
Member

kmyk commented Jan 29, 2020

親 issue: #116

考えてなかったけどやってくれそうな人がいるので
同時に F# 対応も入るとうれしい

@kmyk
Copy link
Member Author

kmyk commented Jan 29, 2020

@riantkb @key-moon @cannorin

@cannorin
Copy link
Member

C#/F# には #include に相当するものがないですが,csprojfsproj から単一ファイルの生成をするという感じですか

@key-moon
Copy link
Contributor

key-moon commented Jan 29, 2020

仕様についてなのですが、C#の特性上関数やコード片を外に出すことができません。
ライブラリ的にはやはり関数なども置けたほうが嬉しいため、対応をするのであればC# scripting形式のファイルとしてライブラリを扱うのが良いのかな、とおもったりしています。
そうすると#load "[filepath]"で別のライブラリをincludeのように参照できます。()

@cannorin
Copy link
Member

F# script (fsx) にも #load プリミティヴがありそのように使うことができます (cf. https://docs.microsoft.com/ja-jp/dotnet/fsharp/tutorials/fsharp-interactive/)

@kmyk
Copy link
Member Author

kmyk commented Jan 29, 2020

Roslyn って言ってたのを昨日見たのでとりあえず名前だけ挙げておきます (私は何なのかよく分かってません)
https://twitter.com/kymn_/status/1222084445970132992

@key-moon
Copy link
Contributor

key-moon commented Jan 29, 2020

Roslynは.NET Coreで使われているコンパイラで、Compiler as a Serviceを掲げて構文解析等のAPIを提供しているものです。
C#のプロジェクトをライブラリにする場合はこれが方法となると思いますので、検討したいです。
パッと思いつくメリット・デメリットとしては、

メリット

  • C#プロジェクトでライブラリが書ける
  • 依存関係等をあまり意識しなくてよくなる(プロジェクトについてコンパイラがよしなにしてくれるので)
  • 名前空間をつけられる(追記)
  • テストについて、NUnit等のテスト用フレームワークを用いたテストの記述ができる(?)(かなりめんどくさそうではある)
  • 別用途への適用ができるかも(提出ファイル自動生成等)

デメリット

  • 関数をライブラリ化する際に、Classで包まなければいけない(ボイラープレートが増える)
  • 同じClass名のライブラリを作るのが煩雑になりそう(同一名前空間に同名Classが存在できないため)
  • 実装が多分つらい

くらいでしょうか

@riantkb
Copy link

riantkb commented Jan 29, 2020

https://github.com/riantkb/csharp/blob/83deb5ebbb7ecf65ab9a5987aab2feb461453ae8/test/BITTest.csx
こんなふうに書いて
dotnet script test/BITTest.csx
とすると動いたので,テストコードを c# script 形式で書くのはありかもしれないです.

ただ,c# script だと名前空間が定義できないので,ライブラリがちゃんと名前空間で分けられていたりすると動かないので少し微妙…

@key-moon
Copy link
Contributor

名前空間をつけている人がVerifyできなくなるのはあまり宜しくないので、生C#への対応は必須そうですね。それとは別にscriptでの手軽さは残したいので、簡単にできそうなscriptへの対応をまずは生やそうと思います。

@key-moon key-moon mentioned this issue Jan 29, 2020
4 tasks
@key-moon
Copy link
Contributor

list_attributesが表すものについて、C#ではどのようにして対応するかを検討したいです。
list_attributesはVerifyファイルの指定などに使われています。詳しくは以下の引用と、C++での実装を参考にしてください。(C++では#defineマクロの値をkey-value辞書として返すようにしています)

list_attributes (設定情報の辞書を返す) だけは設計が自明でないんですが、うまくやってください。
実用的には「コンパイラが clang++ でかつ ulimit に失敗している場合のみ実行をスキップしたい」などの単純な条件分岐を含む設定が可能な仕様にする必要があります。

Originally posted by @kmyk in #116 (comment)

C#の#defineはシンボルの定義のみしか行えないので、他の方法を考える必要があります。
私は#pragmaディレクティブを使うのが最適かな、と思っているのですが、他に良い方法があれば教えて下さい。

@kmyk
Copy link
Member Author

kmyk commented May 6, 2020

.csx の依存関係解析について、現在は #load しか認識してくれないけど using 句も認識してくれるとうれしそう。

例:

https://github.com/camypaper/complib/blob/3805a404c327922398484caa8c2c1f79a059e7e9/Tests/Graph/HLtree.test.csx#L5

cc: @camypaper

@camypaper
Copy link

現状の判定条件が行頭に #load がある程度のゆるさなので

matchobj = re.search(r'^\s*#load\s*"\s*(.+)\s*"', content, flags=re.MULTILINE)

https://github.com/camypaper/complib/blob/b1ba376a64964d1b6522b53b3ce26f763a4b4239/Tests/Graph/HLtree.test.csx#L2-L4

みたいにコメントで補足、というのでもなんとかなりそうです。
namespace の解析を真面目にするのはしんどい割に労力に見合わなさそうという気もしています。

@kmyk
Copy link
Member Author

kmyk commented May 6, 2020

なるほど、#r "./../../bin/complib.dll" の時点ですでに全部が import されていて、using は名前空間を省略できるようにするだけなのか。つらそう
申し訳ないがひとまずはコメントで補足する方式でお願いします 🙇

@camypaper
Copy link

現状 3 つぐらい手は考えていて、今後やるにしても 2 程度が無難な落とし所な気が個人的にはしています

  1. roslyn などで頑張って解析
    • pros: ちゃんとできるのがうれしい、ユーザ側が気にせず使える
    • cons: 実装も保守も多分めちゃくちゃしんどい。
  2. [using static ディレクティブ] https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/using-static で使うライブラリのクラス名を明示させる(そういう用途のものではないが…)
    • pros: コード中に使うライブラリのクラスを明示できる(し、コード書く時の静的解析にもかかる)
    • cons: クラス名からファイル名は追跡できないのでそこのお世話をしないといけない。あとコードスニペットには対処不能(それは csx でやればいいけど)
  3. #load filepath をごまかして使う
    • pros: ほぼ何もしないのでコストが低い
    • cons:ファイル名や依存関係に対するユーザ側の管理コストがかかる

@key-moon
Copy link
Contributor

key-moon commented May 8, 2020

現状の判定条件が行頭に #load がある程度のゆるさなので

これ、実はdotnet scriptでの実装をほぼそのまま取ってきてます(loadディレクティブとかはifディレクティブの影響を受けないので、実はこれでもロードされる)

//hoge.csx
#if HOGE
/*
#load "fuga.csx"
*/
#endif
//fuga.csx
System.Console.WriteLine("fuga");

C# scriptの理想的な使い方/依存関係の解決法は(たぶん)#load filepathでのロードなので、usingでの解決やroslynに突っ込むといったことは(scriptでない)C#プロジェクトに対応する方で行うべきなので、いい加減やります。(テストもテストプロジェクトを作ってテストを書くことでいい感じになって欲しいと思っていますが、少し煩雑なのでたしかに共存可能だと嬉しいかもしれない)

それとは別に、RoslynでのC# scriptのパースは1ファイルしか受け付けられない仕様になっているので、同一の解析器に突っ込むことはできなさそうです。なので、共存させる実装はかなり煩雑になりそうだなあという予測があります。

@kzrnm
Copy link
Contributor

kzrnm commented Mar 13, 2022

拙作のライブラリ https://github.com/kzrnm/SourceExpander で Roslyn による依存関係の解決を実現しているので、これを使用して実装できるかと思います。

私の方で実装してみようと思うので、完成したら Pull request を送ってみます。

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 a pull request may close this issue.

6 participants