[m-rev.] for review: mmc --make, submodules and java

Peter Wang novalazy at gmail.com
Wed May 6 13:50:43 AEST 2009


2009/5/5 Julien Fischer <juliensf at csse.unimelb.edu.au>:
>
> parse_tree is fine; it's introducing import dependencies back the other way
> that concerns me, i.e. having the frontend packages import the code
> generators.

Here is an updated log message and interdiff.


Branches: main

Make `mmc --make' support submodules when compiling to Java.  Java files must
be placed in subdirectories named after the package that each class belongs to.

compiler/java_names.m
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
        Add a new module in the parse_tree package to contain code related to
        name mangling for Java.

compiler/mlds.m:
compiler/java_util.m:
        Move predicates to java_names.m.

compiler/mlds_to_java.m:
        Move predicates to java_names.m.

        Delete an unused predicate.

compiler/file_names.m:
        Rename `erlang_module_name' as it is now also used for Java.

        Make `module_name_to_file_name_general' return file names for `.java'
        and `.class' files that include package subdirectories.

compiler/make.program_target.m:
        Clean `.class' files on make clean.

compiler/mlds_to_il.m:
mdbcomp/prim_data.m:
        Move `sym_name_to_list' to mdbcomp.prim_data.

compiler/compile_target_code.m:
compiler/elds_to_erlang.m:
        Conform to changes.

library/Mmakefile:
        Delete hacks that work around Mercury not writing submodule .java files
        in subdirectories.

diff --git a/compiler/file_names.m b/compiler/file_names.m
index 514238a..17c5b16 100644
--- a/compiler/file_names.m
+++ b/compiler/file_names.m
@@ -130,8 +130,7 @@
 :- import_module libs.handle_options.
 :- import_module libs.options.
 :- import_module mdbcomp.prim_data.
-:- import_module ml_backend.                % XXX unwanted dependency
-:- import_module ml_backend.mlds_to_java.   % XXX unwanted dependency
+:- import_module parse_tree.java_names.
 :- import_module parse_tree.prog_util.
 :- import_module parse_tree.source_file_map.

@@ -269,7 +268,8 @@ choose_file_name(_ModuleName, BaseParentDirs,
BaseName, Ext, Search, MkDir,
             )
         )
     ->
-        FileName = BaseName
+        make_file_name(BaseParentDirs, do_not_search, do_create_dirs, BaseName,
+            Ext, FileName, !IO)
     ;
         % The source files, the final executables, library files (including
         % .init files) output files intended for use by the user, and phony
@@ -428,7 +428,7 @@ module_name_to_make_var_name(ModuleName, MakeVarName) :-
 make_file_name(SubDirNames, Search, MkDir, BaseName, Ext, FileName, !IO) :-
     globals.io_get_globals(Globals, !IO),
     globals.lookup_bool_option(Globals, use_grade_subdirs, UseGradeSubdirs),
-    globals.lookup_string_option(Globals, fullarch, FullArch),
+    globals.lookup_bool_option(Globals, use_subdirs, UseSubdirs),
     (
         UseGradeSubdirs = yes,
         file_is_arch_or_grade_dependent(Globals, Ext),
@@ -448,6 +448,7 @@ make_file_name(SubDirNames, Search, MkDir,
BaseName, Ext, FileName, !IO) :-
         )
     ->
         grade_directory_component(Globals, Grade),
+        globals.lookup_string_option(Globals, fullarch, FullArch),

         % The extra "Mercury" is needed so we can use `--intermod-directory
         % Mercury/<grade>/<fullarch>' and `--c-include
@@ -456,17 +457,27 @@ make_file_name(SubDirNames, Search, MkDir,
BaseName, Ext, FileName, !IO) :-
         % libraries.
         DirComponents = ["Mercury", Grade, FullArch, "Mercury" | SubDirNames]
     ;
+        UseSubdirs = yes
+    ->
         DirComponents = ["Mercury" | SubDirNames]
+    ;
+        DirComponents = SubDirNames
     ),
     (
-        MkDir = do_create_dirs,
-        DirName = dir.relative_path_name_from_components(DirComponents),
-        make_directory(DirName, _, !IO)
+        DirComponents = [],
+        FileName = BaseName
     ;
-        MkDir = do_not_create_dirs
-    ),
-    Components = DirComponents ++ [BaseName],
-    FileName = dir.relative_path_name_from_components(Components).
+        DirComponents = [_ | _],
+        (
+            MkDir = do_create_dirs,
+            DirName = dir.relative_path_name_from_components(DirComponents),
+            make_directory(DirName, _, !IO)
+        ;
+            MkDir = do_not_create_dirs
+        ),
+        Components = DirComponents ++ [BaseName],
+        FileName = dir.relative_path_name_from_components(Components)
+    ).

 :- pred file_is_arch_or_grade_dependent(globals::in, string::in) is semidet.

diff --git a/compiler/java_names.m b/compiler/java_names.m
new file mode 100644
index 0000000..485b87f
--- /dev/null
+++ b/compiler/java_names.m
@@ -0,0 +1,288 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2002-2009 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: java_names.m.
+% Main authors: juliensf, mjwybrow, wangp.
+%
+% This module contains utility routines related to naming things in Java,
+% which are also required in the frontend.
+%
+%-----------------------------------------------------------------------------%
+
+:- module parse_tree.java_names.
+:- interface.
+
+:- import_module mdbcomp.prim_data.
+
+:- import_module bool.
+
+%-----------------------------------------------------------------------------%
+
+    % For the Java back-end, we need to distinguish between module qualifiers
+    % and type qualifiers, because type names get the case of their initial
+    % letter inverted (i.e. lowercase => uppercase).
+    %
+    % This duplicates mlds_qual_kind so as not to introduce unwanted
+    % dependencies in either direction.
+    %
+:- type java_qual_kind
+    --->    module_qual
+    ;       type_qual.
+
+    % Java doesn't allow a fully-qualified class to have the same name as a
+    % package.  Our workaround is to name package components with trailing
+    % underscores, e.g. `mammal_.primate_.chimp' where `chimp' is a class.
+    % This is enabled with `package_name_mangling'.
+    %
+    % The packages `mercury' and `mercury.runtime' are named without
+    % underscores simply because there is existing handwritten code already
+    % using those names.
+    %
+:- type package_name_mangling
+    --->    package_name_mangling
+    ;       no_package_name_mangling.
+
+    % Mangle a name so that it is suitable for Java.
+    %
+:- pred mangle_sym_name_for_java(sym_name::in, java_qual_kind::in,
+    string::in, package_name_mangling::in, string::out) is det.
+
+    % Returns yes iff the given package is one provided by the Mercury
+    % implementation, `mercury' or `mercury.runtime'.
+    %
+:- func is_mercury_provided_java_package(sym_name) = bool.
+
+    % Used in module_name_to_file_name to derive file names for Java files.
+    % Returns a module name which each component mangled.
+    %
+:- func java_module_name(module_name) = module_name.
+
+    % If the given name conficts with a reserved Java word we must add a
+    % prefix to it to avoid compilation errors.
+    %
+:- func valid_java_symbol_name(string) = string.
+
+    % Succeeds iff the given string matches a reserved word in Java.
+    %
+:- pred java_is_keyword(string::in) is semidet.
+
+    % Invert the case of the first letter of the string.
+    %
+:- func flip_initial_case(string) = string.
+
+    % Invert the case of the first letter of the last component of
+    % a (possibly) qualified name.
+    %
+:- func flip_initial_case_of_final_part(sym_name) = sym_name.
+
+    % The package containing the Mercury standard library.
+    %
+:- func mercury_std_library_package_name = sym_name.
+
+    % The package containing the Mercury Java runtime classes.
+    %
+:- func mercury_runtime_package_name = sym_name.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module parse_tree.file_names.
+:- import_module parse_tree.prog_foreign.   % for name_mangle
+
+:- import_module char.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+mangle_sym_name_for_java(SymName, QualKind, QualifierOp,
+        PackageNameMangling, JavaSafeName) :-
+    mangle_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
+        MangledSymName),
+    JavaSafeName = sym_name_to_string_sep(MangledSymName, QualifierOp).
+
+:- pred mangle_sym_name_for_java_2(sym_name::in, java_qual_kind::in,
+    package_name_mangling::in, sym_name::out) is det.
+
+mangle_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
+        MangledSymName) :-
+    (
+        SymName = unqualified(Name),
+        JavaSafeName = java_safe_name_component(QualKind, Name),
+        MangledSymName = unqualified(JavaSafeName)
+    ;
+        SymName = qualified(ModuleName0, PlainName),
+        mangle_sym_name_for_java_2(ModuleName0, module_qual,
+            PackageNameMangling, MangledModuleName0),
+        (
+            PackageNameMangling = package_name_mangling,
+            MercuryProvided = is_mercury_provided_java_package(ModuleName0),
+            (
+                MercuryProvided = yes,
+                MangledModuleName = MangledModuleName0
+            ;
+                MercuryProvided = no,
+                MangledModuleName = append_underscore_sym_name(
+                    MangledModuleName0)
+            )
+        ;
+            PackageNameMangling = no_package_name_mangling,
+            MangledModuleName = MangledModuleName0
+        ),
+        JavaSafePlainName = java_safe_name_component(QualKind, PlainName),
+        MangledSymName = qualified(MangledModuleName, JavaSafePlainName)
+    ).
+
+:- func java_safe_name_component(java_qual_kind, string) = string.
+
+java_safe_name_component(QualKind, Name) = JavaSafeName :-
+    (
+        QualKind = module_qual,
+        FlippedName = Name
+    ;
+        QualKind = type_qual,
+        FlippedName = flip_initial_case(Name)
+    ),
+    MangledName = name_mangle(FlippedName),
+    JavaSafeName = valid_java_symbol_name(MangledName).
+
+is_mercury_provided_java_package(ModuleName) = MercuryProvided :-
+    ( ModuleName = mercury_std_library_package_name ->
+        MercuryProvided = yes
+    ; ModuleName = mercury_runtime_package_name ->
+        MercuryProvided = yes
+    ;
+        MercuryProvided = no
+    ).
+
+:- func append_underscore_sym_name(sym_name) = sym_name.
+
+append_underscore_sym_name(SymName0) = SymName :-
+    (
+        SymName0 = unqualified(Name),
+        SymName = unqualified(Name ++ "_")
+    ;
+        SymName0 = qualified(ModuleSymName, Name),
+        SymName = qualified(ModuleSymName, Name ++ "_")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+java_module_name(ModuleName) = JavaModuleName :-
+    QualModuleName = qualify_mercury_std_library_module_name(ModuleName),
+    mangle_sym_name_for_java_2(QualModuleName, module_qual,
+        package_name_mangling, JavaModuleName).
+
+%-----------------------------------------------------------------------------%
+
+valid_java_symbol_name(SymName) = ValidSymName :-
+    Prefix = "mr_",
+    ( java_is_keyword(SymName) ->
+        % This is a reserved Java word, add the above prefix.
+        ValidSymName = Prefix ++ SymName
+    ; string.append(Prefix, Suffix, SymName) ->
+        % This name already contains the prefix we are adding to
+        % variables to avoid conficts, so add an additional '_'.
+        ValidSymName = Prefix ++ "_" ++ Suffix
+    ;
+        % Normal name; do nothing.
+        ValidSymName = SymName
+    ).
+
+%-----------------------------------------------------------------------------%
+
+java_is_keyword("abstract").
+java_is_keyword("boolean").
+java_is_keyword("break").
+java_is_keyword("byte").
+java_is_keyword("case").
+java_is_keyword("catch").
+java_is_keyword("char").
+java_is_keyword("class").
+java_is_keyword("const").
+java_is_keyword("continue").
+java_is_keyword("default").
+java_is_keyword("do").
+java_is_keyword("double").
+java_is_keyword("else").
+java_is_keyword("enum").
+java_is_keyword("extends").
+java_is_keyword("false").
+java_is_keyword("final").
+java_is_keyword("finally").
+java_is_keyword("float").
+java_is_keyword("for").
+java_is_keyword("goto").
+java_is_keyword("if").
+java_is_keyword("implements").
+java_is_keyword("import").
+java_is_keyword("instanceof").
+java_is_keyword("int").
+java_is_keyword("interface").
+java_is_keyword("long").
+java_is_keyword("native").
+java_is_keyword("new").
+java_is_keyword("null").
+java_is_keyword("package").
+java_is_keyword("private").
+java_is_keyword("protected").
+java_is_keyword("public").
+java_is_keyword("return").
+java_is_keyword("short").
+java_is_keyword("static").
+java_is_keyword("strictfp").
+java_is_keyword("super").
+java_is_keyword("switch").
+java_is_keyword("synchronized").
+java_is_keyword("this").
+java_is_keyword("throw").
+java_is_keyword("throws").
+java_is_keyword("transient").
+java_is_keyword("true").
+java_is_keyword("try").
+java_is_keyword("void").
+java_is_keyword("volatile").
+java_is_keyword("while").
+
+%-----------------------------------------------------------------------------%
+
+flip_initial_case(S0) = S :-
+    ( string.first_char(S0, First0, Rest) ->
+        ( char.is_upper(First0) ->
+            First = char.to_lower(First0)
+        ; char.is_lower(First0) ->
+            First = char.to_upper(First0)
+        ;
+            First = First0
+        ),
+        string.first_char(S, First, Rest)
+    ;
+        S = S0
+    ).
+
+flip_initial_case_of_final_part(unqualified(Name)) =
+    unqualified(flip_initial_case(Name)).
+flip_initial_case_of_final_part(qualified(Qual, Name)) =
+    qualified(Qual, flip_initial_case(Name)).
+
+%-----------------------------------------------------------------------------%
+
+mercury_std_library_package_name = unqualified("mercury").
+
+mercury_runtime_package_name = qualified(unqualified("mercury"), "runtime").
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "java_names.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module java_names.
+%-----------------------------------------------------------------------------%
diff --git a/compiler/java_util.m b/compiler/java_util.m
index 1436f44..b3c5523 100644
--- a/compiler/java_util.m
+++ b/compiler/java_util.m
@@ -19,13 +19,6 @@
 :- interface.

 :- import_module backend_libs.builtin_ops.
-:- import_module mdbcomp.prim_data.
-
-%-----------------------------------------------------------------------------%
-
-    % Succeeds iff the given string matches a reserved word in Java.
-    %
-:- pred java_is_keyword(string::in) is semidet.

 %-----------------------------------------------------------------------------%
 %
@@ -61,16 +54,6 @@
 :- pred java_binary_infix_op(binary_op::in, string::out) is semidet.

 %-----------------------------------------------------------------------------%
-
-    % The package containing the Mercury standard library.
-    %
-:- func mercury_std_library_package_name = sym_name.
-
-    % The package containing the Mercury Java runtime classes.
-    %
-:- func mercury_runtime_package_name = sym_name.
-
-%-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

 :- implementation.
@@ -131,67 +114,6 @@ java_binary_infix_op(int_ge, ">=").

 %-----------------------------------------------------------------------------%

-java_is_keyword("abstract").
-java_is_keyword("boolean").
-java_is_keyword("break").
-java_is_keyword("byte").
-java_is_keyword("case").
-java_is_keyword("catch").
-java_is_keyword("char").
-java_is_keyword("class").
-java_is_keyword("const").
-java_is_keyword("continue").
-java_is_keyword("default").
-java_is_keyword("do").
-java_is_keyword("double").
-java_is_keyword("else").
-java_is_keyword("enum").
-java_is_keyword("extends").
-java_is_keyword("false").
-java_is_keyword("final").
-java_is_keyword("finally").
-java_is_keyword("float").
-java_is_keyword("for").
-java_is_keyword("goto").
-java_is_keyword("if").
-java_is_keyword("implements").
-java_is_keyword("import").
-java_is_keyword("instanceof").
-java_is_keyword("int").
-java_is_keyword("interface").
-java_is_keyword("long").
-java_is_keyword("native").
-java_is_keyword("new").
-java_is_keyword("null").
-java_is_keyword("package").
-java_is_keyword("private").
-java_is_keyword("protected").
-java_is_keyword("public").
-java_is_keyword("return").
-java_is_keyword("short").
-java_is_keyword("static").
-java_is_keyword("strictfp").
-java_is_keyword("super").
-java_is_keyword("switch").
-java_is_keyword("synchronized").
-java_is_keyword("this").
-java_is_keyword("throw").
-java_is_keyword("throws").
-java_is_keyword("transient").
-java_is_keyword("true").
-java_is_keyword("try").
-java_is_keyword("void").
-java_is_keyword("volatile").
-java_is_keyword("while").
-
-%-----------------------------------------------------------------------------%
-
-mercury_std_library_package_name = unqualified("mercury").
-
-mercury_runtime_package_name = qualified(unqualified("mercury"), "runtime").
-
-%-----------------------------------------------------------------------------%
-
 :- func this_file = string.

 this_file = "java_util.m".
diff --git a/compiler/mlds.m b/compiler/mlds.m
index d723892..de58e48 100644
--- a/compiler/mlds.m
+++ b/compiler/mlds.m
@@ -1744,18 +1744,6 @@

 %-----------------------------------------------------------------------------%

-    % Invert the case of the first letter of the string.
-    % This is used for the Java back-end.
-    %
-:- func flip_initial_case(string) = string.
-
-    % Invert the case of the first letter of the last component of
-    % a (possibly) qualified name.  This is used for the Java back-end.
-    %
-:- func flip_initial_case_of_final_part(sym_name) = sym_name.
-
-%-----------------------------------------------------------------------------%
-
 :- type mlds_exported_enums == list(mlds_exported_enum).

 :- type mlds_exported_enum
@@ -1784,6 +1772,7 @@
 :- import_module parse_tree.file_names.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_util.
+:- import_module parse_tree.java_names.

 :- import_module char.
 :- import_module int.
@@ -1993,26 +1982,6 @@ mlds_std_tabling_proc_label(ProcLabel0) = ProcLabel :-
     ),
     ProcLabel = mlds_proc_label(PredLabel, ProcId).

-flip_initial_case_of_final_part(unqualified(Name)) =
-    unqualified(flip_initial_case(Name)).
-flip_initial_case_of_final_part(qualified(Qual, Name)) =
-    qualified(Qual, flip_initial_case(Name)).
-
-    % Invert the case of the first letter of the string.
-flip_initial_case(S0) = S :-
-    ( string.first_char(S0, First0, Rest) ->
-        ( char.is_upper(First0) ->
-            First = char.to_lower(First0)
-        ; char.is_lower(First0) ->
-            First = char.to_upper(First0)
-        ;
-            First = First0
-        ),
-        string.first_char(S, First, Rest)
-    ;
-        S = S0
-    ).
-
 %-----------------------------------------------------------------------------%

     % We represent the set of declaration flags as a bunch of bit-fields packed
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 338014d..2a4b0e9 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -72,7 +72,6 @@
 :- interface.

 :- import_module hlds.hlds_module.
-:- import_module mdbcomp.prim_data.
 :- import_module ml_backend.mlds.

 :- import_module io.
@@ -81,10 +80,6 @@

 :- pred output_mlds(module_info::in, mlds::in, io::di, io::uo) is det.

-    % Used in module_name_to_file_name to derive file names for Java files.
-    %
-:- func java_module_name(module_name) = module_name.
-
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

@@ -102,11 +97,13 @@
 :- import_module libs.file_util.
 :- import_module libs.globals.
 :- import_module libs.options.
+:- import_module mdbcomp.prim_data.
 :- import_module ml_backend.java_util.
 :- import_module ml_backend.ml_code_util.  % for ml_gen_local_var_decl_flags.
 :- import_module ml_backend.ml_type_gen.   % for ml_gen_type_name
 :- import_module ml_backend.ml_util.
 :- import_module parse_tree.file_names.    % for mercury_std_library_name.
+:- import_module parse_tree.java_names.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_foreign.
 :- import_module parse_tree.prog_out.
@@ -143,19 +140,6 @@ output_mlds(ModuleInfo, MLDS, !IO) :-
 % Utility predicates for various purposes.
 %

-    % Succeeds iff the given qualified name is part of the standard
-    % library (as listed in compiler/modules.m).
-    %
-:- pred qualified_name_is_stdlib(mercury_module_name::in) is semidet.
-
-qualified_name_is_stdlib(unqualified(_)) :- fail.
-qualified_name_is_stdlib(qualified(Module, Name)) :-
-    (
-        mercury_std_library_module_name(qualified(Module, Name))
-    ;
-        qualified_name_is_stdlib(Module)
-    ).
-
     % Succeeds iff this definition is a data definition which
     % defines RTTI.
     %
@@ -290,136 +274,6 @@ reverse_string(String0, String) :-
     string.to_char_list(String0, String1),
     string.from_rev_char_list(String1, String).

-    % Java doesn't allow a fully-qualified class to have the same name as a
-    % package.  Our workaround is to name package components with trailing
-    % underscores, e.g. `mammal_.primate_.chimp' where `chimp' is a class.
-    % This is enabled with `package_name_mangling'.
-    %
-    % The packages `mercury' and `mercury.runtime' are named without
-    % underscores simply because there is existing handwritten code already
-    % using those names.
-    %
-:- type package_name_mangling
-    --->    package_name_mangling
-    ;       no_package_name_mangling.
-
-:- pred mangle_mlds_sym_name_for_java(sym_name::in, mlds_qual_kind::in,
-    string::in, package_name_mangling::in, string::out) is det.
-
-mangle_mlds_sym_name_for_java(SymName, QualKind, QualifierOp,
-        PackageNameMangling, JavaSafeName) :-
-    mangle_mlds_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
-        MangledSymName),
-    JavaSafeName = sym_name_to_string_sep(MangledSymName, QualifierOp).
-
-:- pred mangle_mlds_sym_name_for_java_2(sym_name::in, mlds_qual_kind::in,
-    package_name_mangling::in, sym_name::out) is det.
-
-mangle_mlds_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
-        MangledSymName) :-
-    (
-        SymName = unqualified(Name),
-        JavaSafeName = java_safe_name_component(QualKind, Name),
-        MangledSymName = unqualified(JavaSafeName)
-    ;
-        SymName = qualified(ModuleName0, PlainName),
-        mangle_mlds_sym_name_for_java_2(ModuleName0, module_qual,
-            PackageNameMangling, MangledModuleName0),
-        (
-            PackageNameMangling = package_name_mangling,
-            MaybeUnderscore =
should_append_underscore_for_package(ModuleName0),
-            (
-                MaybeUnderscore = yes,
-                MangledModuleName = append_underscore_sym_name(
-                    MangledModuleName0)
-            ;
-                MaybeUnderscore = no,
-                MangledModuleName = MangledModuleName0
-            )
-        ;
-            PackageNameMangling = no_package_name_mangling,
-            MangledModuleName = MangledModuleName0
-        ),
-        JavaSafePlainName = java_safe_name_component(QualKind, PlainName),
-        MangledSymName = qualified(MangledModuleName, JavaSafePlainName)
-    ).
-
-:- func java_safe_name_component(mlds_qual_kind, string) = string.
-
-java_safe_name_component(QualKind, Name) = JavaSafeName :-
-    (
-        QualKind = module_qual,
-        FlippedName = Name
-    ;
-        QualKind = type_qual,
-        FlippedName = flip_initial_case(Name)
-    ),
-    MangledName = name_mangle(FlippedName),
-    JavaSafeName = valid_symbol_name(MangledName).
-
-:- func should_append_underscore_for_package(sym_name) = bool.
-
-should_append_underscore_for_package(ModuleName) = Append :-
-    ( ModuleName = mercury_std_library_package_name ->
-        Append = no
-    ; ModuleName = mercury_runtime_package_name ->
-        Append = no
-    ;
-        Append = yes
-    ).
-
-:- func append_underscore_sym_name(sym_name) = sym_name.
-
-append_underscore_sym_name(SymName0) = SymName :-
-    (
-        SymName0 = unqualified(Name),
-        SymName = unqualified(Name ++ "_")
-    ;
-        SymName0 = qualified(ModuleSymName, Name),
-        SymName = qualified(ModuleSymName, Name ++ "_")
-    ).
-
-java_module_name(ModuleName) = JavaModuleName :-
-    QualModuleName = qualify_mercury_std_library_module_name(ModuleName),
-    mangle_mlds_sym_name_for_java_2(QualModuleName, module_qual,
-        package_name_mangling, JavaModuleName).
-
-%-----------------------------------------------------------------------------%
-%
-% Name mangling code to fix problem of mercury modules having the same name
-% as reserved Java words such as `char' and `int'.
-%
-
-    % If the given name conficts with a reserved Java word we must add a
-    % prefix to it to avoid compilation errors.
-:- func valid_symbol_name(string) = string.
-
-valid_symbol_name(SymName) = ValidSymName :-
-    Prefix = "mr_",
-    ( java_is_keyword(SymName) ->
-        % This is a reserved Java word, add the above prefix.
-        ValidSymName = Prefix ++ SymName
-    ; string.append(Prefix, Suffix, SymName) ->
-        % This name already contains the prefix we are adding to
-        % variables to avoid conficts, so add an additional '_'.
-        ValidSymName = Prefix ++ "_" ++ Suffix
-    ;
-        % Normal name; do nothing.
-        ValidSymName = SymName
-    ).
-
-:- type java_module_name == sym_name.
-
-:- func valid_module_name(java_module_name) = java_module_name.
-
-valid_module_name(unqualified(String)) =  ValidModuleName :-
-    ValidString = valid_symbol_name(String),
-    ValidModuleName = unqualified(ValidString).
-valid_module_name(qualified(ModuleSpecifier, String)) =  ValidModuleName :-
-    ValidModuleSpecifier = valid_module_name(ModuleSpecifier),
-    ValidString = valid_symbol_name(String),
-    ValidModuleName = qualified(ValidModuleSpecifier, ValidString).
-
 %-----------------------------------------------------------------------------%
 %
 % Code to output imports.
@@ -449,11 +303,8 @@ output_import(Import, !IO) :-
         unexpected(this_file, "foreign import in Java backend")
     ),
     SymName = mlds_module_name_to_sym_name(ImportName),
-    JavaSafeSymName = valid_module_name(SymName),
-    File = sym_name_to_string(JavaSafeSymName),
-    % XXX Name mangling code should be put here when we start enforcing
-    % Java's naming conventions.
-    ClassFile = File,
+    mangle_sym_name_for_java(SymName, module_qual, ".", package_name_mangling,
+        ClassFile),
     % There are issues related to using import statements and Java's naming
     % conventions. To avoid these problems, we output dependencies as comments
     % only. This is ok, since we always use fully qualified names anyway.
@@ -925,8 +776,8 @@ create_addr_wrapper_name(CodeAddr,
MangledClassEntityName) :-
     % Create a name for this wrapper class based on the fully qualified method
     % (predicate) name.
     ModuleQualifierSym = mlds_module_name_to_sym_name(ModuleQualifier),
-    mangle_mlds_sym_name_for_java(ModuleQualifierSym, QualKind, "__",
-        no_package_name_mangling, ModuleNameStr),
+    mangle_sym_name_for_java(ModuleQualifierSym, convert_qual_kind(QualKind),
+        "__", no_package_name_mangling, ModuleNameStr),
     ClassEntityName = "addrOf__" ++ ModuleNameStr ++ "__" ++ PredName,
     MangledClassEntityName = name_mangle_maybe_shorten(ClassEntityName).

@@ -1039,21 +890,6 @@ generate_call_method_args([Type | Types],
Variable, Counter, Args0, Args) :-
     Args1 = Args0 ++ [UnBoxedRval],
     generate_call_method_args(Types, Variable, Counter + 1, Args1, Args).

-:- func mlds_module_name_to_string(mlds_module_name) = string.
-
-mlds_module_name_to_string(MldsModuleName) = ModuleNameStr :-
-    ModuleName = mlds_module_name_to_sym_name(MldsModuleName),
-    ModuleNameStr = symbol_name_to_string(ModuleName, "").
-
-:- func symbol_name_to_string(sym_name, string) = string.
-
-symbol_name_to_string(unqualified(SymName), SymNameStr0) = SymNameStr :-
-    SymNameStr = SymNameStr0 ++ SymName.
-symbol_name_to_string(qualified(Qualifier, SymName), SymNameStr0)
-        = SymNameStr :-
-    SymNameStr1 = symbol_name_to_string(Qualifier, SymNameStr0),
-    SymNameStr = SymNameStr1 ++ "__" ++ SymName.
-
 :- func make_pred_name_string(mlds_pred_label, proc_id,
     maybe(mlds_func_sequence_num)) = string.

@@ -1149,9 +985,7 @@ output_init_2(Indent, InitPred, !IO) :-

 output_src_start(Indent, MercuryModuleName, Imports, ForeignDecls, Defns,
         !IO) :-
-    MLDSModuleName = mercury_module_name_to_mlds(MercuryModuleName),
-    ModuleSymName = mlds_module_name_to_sym_name(MLDSModuleName),
-    JavaSafeModuleName = valid_module_name(ModuleSymName),
+    JavaSafeModuleName = java_module_name(MercuryModuleName),
     output_auto_gen_comment(MercuryModuleName, !IO),
     indent_line(Indent, !IO),
     io.write_string("/* :- module ", !IO),
@@ -1172,26 +1006,18 @@ output_src_start(Indent, MercuryModuleName,
Imports, ForeignDecls, Defns,
 :- pred output_package_info(sym_name::in, io::di, io::uo) is det.

 output_package_info(unqualified(_), !IO).
-output_package_info(qualified(Module, _), !IO) :-
+output_package_info(qualified(JavaSafeModule, _), !IO) :-
     io.write_string("package ", !IO),
-    mangle_mlds_sym_name_for_java(Module, module_qual, ".",
-        package_name_mangling, PackageName),
+    PackageName = sym_name_to_string(JavaSafeModule),
     io.write_string(PackageName, !IO),
-    MaybeUnderscore = should_append_underscore_for_package(Module),
-    (
-        MaybeUnderscore = yes,
-        io.write_string("_;\n", !IO)
-    ;
-        MaybeUnderscore = no,
-        io.write_string(";\n", !IO)
-    ).
+    io.write_string(";\n", !IO).

     % Check if this module contains a `main' predicate and if it does insert
     % a `main' method in the resulting Java class that calls the
     % `main' predicate. Save the command line arguments in the class
     % variable `args' in the class `mercury.runtime.JavaInternal'.
     %
-:- pred maybe_write_main_driver(indent::in, java_module_name::in,
+:- pred maybe_write_main_driver(indent::in, sym_name::in,
     list(mlds_defn)::in, io::di, io::uo) is det.

 maybe_write_main_driver(Indent, JavaSafeModuleName, Defns, !IO) :-
@@ -1420,7 +1246,7 @@ output_interface(Interface, !IO) :-
             Arity, _)
     ->
         SymName = mlds_module_name_to_sym_name(ModuleQualifier),
-        mangle_mlds_sym_name_for_java(SymName, QualKind, ".",
+        mangle_sym_name_for_java(SymName, convert_qual_kind(QualKind), ".",
             package_name_mangling, ModuleName),
         io.format("%s.%s", [s(ModuleName), s(Name)], !IO),
         %
@@ -1982,7 +1808,7 @@ output_fully_qualified_thing(qual(ModuleName,
QualKind, Name), OutputFunc,
     mlds_module_name_to_sym_name(ModuleName) = WholeModuleName,

     % Write the package name components.
-    mangle_mlds_sym_name_for_java(PackageName, module_qual, Qualifier,
+    mangle_sym_name_for_java(PackageName, module_qual, Qualifier,
         package_name_mangling, MangledPackageName),
     io.write_string(MangledPackageName, !IO),

@@ -1992,8 +1818,8 @@ output_fully_qualified_thing(qual(ModuleName,
QualKind, Name), OutputFunc,
         true
     ;
         remove_sym_name_prefixes(WholeModuleName, PackageName, NonPackageName),
-        mangle_mlds_sym_name_for_java(NonPackageName, QualKind, Qualifier,
-            no_package_name_mangling, MangledNonPackageName),
+        mangle_sym_name_for_java(NonPackageName, convert_qual_kind(QualKind),
+            Qualifier, no_package_name_mangling, MangledNonPackageName),
         io.write_string(Qualifier, !IO),
         io.write_string(MangledNonPackageName, !IO)
     ),
@@ -2018,6 +1844,11 @@ remove_sym_name_prefixes(SymName0, Prefix, SymName) :-
         unexpected(this_file, "remove_sym_name_prefixes: prefix not found")
     ).

+:- func convert_qual_kind(mlds_qual_kind) = java_qual_kind.
+
+convert_qual_kind(module_qual) = module_qual.
+convert_qual_kind(type_qual) = type_qual.
+
 :- pred output_module_name(mercury_module_name::in, io::di, io::uo) is det.

 output_module_name(ModuleName, !IO) :-
@@ -3372,7 +3203,7 @@ output_mangled_name(Name, !IO) :-

 output_valid_mangled_name(Name, !IO) :-
     MangledName = name_mangle(Name),
-    JavaSafeName = valid_symbol_name(MangledName),
+    JavaSafeName = valid_java_symbol_name(MangledName),
     io.write_string(JavaSafeName, !IO).

 :- pred output_call_rval(module_info::in, mlds_rval::in, mlds_module_name::in,
@@ -3734,7 +3565,7 @@
mlds_output_proc_label(mlds_proc_label(PredLabel, ProcId), !IO) :-

 mlds_output_data_addr(data_addr(ModuleQualifier, DataName), !IO) :-
     SymName = mlds_module_name_to_sym_name(ModuleQualifier),
-    mangle_mlds_sym_name_for_java(SymName, module_qual, ".",
+    mangle_sym_name_for_java(SymName, module_qual, ".",
         package_name_mangling, ModuleName),
     io.write_string(ModuleName, !IO),
     io.write_string(".", !IO),
diff --git a/compiler/notes/compiler_design.html
b/compiler/notes/compiler_design.html
index d16a6c1..47d6fd3 100644
--- a/compiler/notes/compiler_design.html
+++ b/compiler/notes/compiler_design.html
@@ -309,6 +309,8 @@ such as pretty-printing.

 	<p>
 	file_names.m does conversions between module names and file names.
+	It uses java_names.m, which contains predicates for dealing with names
+	of things in Java.

 	<p>
 	module_cmds.m handles the commands for manipulating interface files of
diff --git a/compiler/parse_tree.m b/compiler/parse_tree.m
index 203f901..d0f0960 100644
--- a/compiler/parse_tree.m
+++ b/compiler/parse_tree.m
@@ -68,6 +68,9 @@
 :- include_module source_file_map.
 :- include_module write_deps_file.

+% Java-related utilities.
+:- include_module java_names.
+
 % (Note that intermod and trans_opt also contain routines that
 % act on the parse tree, but those modules are considered part
 % of the HLDS transformations package.)
diff --git a/library/Mmakefile b/library/Mmakefile
index cd54653..5bcc831 100644
--- a/library/Mmakefile
+++ b/library/Mmakefile
@@ -266,7 +266,7 @@ JAVAS = ` echo $($(STD_LIB_NAME).javas) | sed \
 # rather than compiling them separately.  This is needed because
 # otherwise javac doesn't handle cyclic dependencies between different
 # modules.
-classes: javas java_symlinks java_subdir_copies
+classes: javas java_symlinks
 	$(JAVAC) $(ALL_JAVACFLAGS) $(JAVAS)

 # javac expects to find the sources for symbols named mercury.* in
@@ -280,22 +280,6 @@ java_symlinks:
 	[ -d mercury ] || ln -s . mercury
 	[ -d runtime ] || ln -s $(MERCURY_DIR)/java/runtime .

-# Mercury doesn't yet put .java files in the directory hierarchies that Java
-# expects.  For now we copy a few files manually.
-.PHONY: java_subdir_copies
-java_subdir_copies:
-	[ -d bit_buffer_ ] || mkdir bit_buffer_
-	[ -d stream_ ] || mkdir stream_
-	[ -d string_ ] || mkdir string_
-	[ -d thread_ ] || mkdir thread_
-	cp bit_buffer.read.java bit_buffer_/read.java
-	cp bit_buffer.write.java bit_buffer_/write.java
-	cp stream.string_writer.java stream_/string_writer.java
-	cp string.builder.java string_/builder.java
-	cp thread.channel.java thread_/channel.java
-	cp thread.mvar.java thread_/mvar.java
-	cp thread.semaphore.java thread_/semaphore.java
-
 # Once all of the library classes have been compiled, we put them in a single
 # jar file.  At this point we also add the runtime classes to a jar file.
 # Note that this stage makes use of the symbolic links created earlier to
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list