Skip to content

Generate per-file top-level Java class names instead of hardcoded Main - #25

Open
hiroshi-cl wants to merge 2 commits into
java_extractionfrom
java-classname-per-file
Open

Generate per-file top-level Java class names instead of hardcoded Main #25
hiroshi-cl wants to merge 2 commits into
java_extractionfrom
java-classname-per-file

Conversation

@hiroshi-cl

@hiroshi-cl hiroshi-cl commented Aug 5, 2026

Copy link
Copy Markdown

extractのファイル名をhaskellと同様クラス名に反映するようにします

hiroshi-cl and others added 2 commits August 4, 2026 01:51
Every generated .java file declared `class Main`, so compiling multiple
extracted files together with `javac *.java` always failed with a
duplicate-class error. The class name is now derived from the module id
(the same one file_naming already computes), threaded from preamble into
pp_struct via a ref, mirroring the existing fix_arities side channel.

mono_filename's Java branch now derives its id from the target filename
the same way Haskell already does, since previously it always forced the
literal "Main" id for Java regardless of the requested filename.

Updates all Java extraction test fixtures accordingly and adds a
run-case.sh step that compiles a case's generated files together, which
would have caught this bug.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Java's top-level class name needed the module id, but the shared
pp_struct signature carried none, so it was smuggled in via a
top_class_name ref written by preamble and read by pp_struct
(mirroring fix_arities). Add Id.t as an explicit pp_struct argument
instead: OCaml/Haskell/JSON/Scheme just ignore it, and Java derives
the class name directly from it, removing the ordering dependency on
preamble running first.

Pure refactor: all java-extraction test fixtures still match byte
for byte.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@hiroshi-cl hiroshi-cl changed the title Thread module Id.t through pp_struct instead of a ref side channel Generate per-file top-level Java class names instead of hardcoded Main Aug 5, 2026
@hiroshi-cl
hiroshi-cl requested a review from cedretaber August 5, 2026 16:13
Comment on lines +537 to +544
match lang () with
| Haskell | Java ->
(* These backends name a top-level container (module / class)
after the file, so the file name must be a valid identifier. *)
(try Id.of_string (Filename.basename f)
with UserError _ ->
user_err Pp.(str "Extraction: provided filename is not a valid identifier"))
| Ocaml | Scheme | JSON -> default_id

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

HaskellだけでなくJavaもdefault_idじゃなくてfilenameを使うようにする

's -> Id.t -> Pp.t option -> DirPath.Set.t -> unsafe_needs ->
Pp.t;
pp_struct : 's -> ml_structure -> Pp.t;
pp_struct : 's -> Id.t -> ml_structure -> Pp.t;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

pp_stuctを拡張してId.tを渡すようにする
haskellではpreambleとして処理しているがjavaではpp_structで出力する
これにより他の言語への抽出コードも変更が出ている

@hiroshi-cl
hiroshi-cl marked this pull request as ready for review August 5, 2026 16:19
Comment on lines +47 to +48
if not valid then
user_err Pp.(str "Extraction: " ++ Id.print id ++

@cedretaber cedretaber Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝
invalid な名前の場合、名前を変えるのではなくエラーにする。

not (String.is_empty s)
&& is_java_ident_start s.[0]
&& String.for_all is_java_ident_part s
&& not (Id.Set.mem id keywords)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nits な指摘

  • Rocq コード内にファイル名と同じ型が定義されていると、同じ名前のクラスが2つ出てきてコンパイルが落ちそう
  • true / false / null は Java のキーワードではなくリテラルなので valid な扱いとなり、しかし class true は javac がエラーを出す。 var なども同様

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Java keyword じゃないやつも必要に応じて keywords の中に突っ込んでるから( let とか error とか)、このへんの語も全部入れてしまっても良いかも?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

確かに JLS §3.8 で reserved 以外にもBooleanLiteral (true, false), NullLiteral (null) も識別子として使えないことになってるので入れても良さそう

一方以下5つは TypeIdentifier から除外されてるけど変数とかには使えることになってそうなのでここで除外はするけどkeywordsには入れないほうが良さそう 🤔

permits
record
sealed
var
yield

@cedretaber cedretaber left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2点指摘しましたが、概ね良さそうです 🙏
( Java のキーワードとそれ以外のリテラルとか、 var みたいな後から入ったのがどういう扱いなのかとか、よく分っていないのですが……。)

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.

7. 出力ファイルごとに固有のトップレベルクラス名を生成する

2 participants