[m-rev.] for review: java packaging
Peter Wang
novalazy at gmail.com
Wed May 20 16:36:01 AEST 2009
Branches: main
Previously, unqualified Mercury modules would result in Java classes which
were placed in the default (unnamed) package. This is a problem as Java
doesn't allow packaged classes to import types from the unpackaged classes.
This patch gives all Java classes generated from Mercury files the "mercury."
package prefix.
mmake support for Java files is even more broken than before. It expects
Java files to be placed in the same directory but, due to the "mercury."
prefix, even classes for non-nested modules are placed in a subdirectory
called `mercury'. (The standard library can still be built with mmake using
custom rules.)
Fix creation of `.jar' files. It is not enough to package the `.class' files
that we know will be produced for each module. Nested classes generate
separate `.class' files which also need to be included.
Fix creation of the shell script that launches Java programs.
compiler/java_names.m:
Add an outermost "mercury" qualifier on all module names.
compiler/compile_target_code.m:
Fix creation of `.jar' files, as described.
Use a temporary file and @-syntax to pass the list of class files to
`jar'.
Pass `jar -C <dir> <class> -C <dir> <class> ...' as -C only affects
the argument immediately following it.
Run `jar i' to add an index to jar files.
compiler/file_names.m:
Add `get_class_dir_name' to return the directory that contains class
files.
Make `choose_file_name' work for Java files again (with package
directories) when `--use-subdirs' is disabled.
compiler/module_cmds.m:
Make `create_java_shell_script' work correctly when
`--use-grade-subdirs' is enabled, and when the main module is
packaged (as it will be).
Make `list_class_files_for_jar' scan the directory containing class
files, to include nested classes. Return a list of class files.
Make `list_class_files_for_jar_mmake' use `get_class_dir_name'.
library/Mmakefile:
Update hacks to build the standard library in the java grade.
mdbcomp/prim_data.m:
Delete `insert_module_qualifier' as `add_outermost_qualifier'
is equivalent.
compiler/module_qual.m:
compiler/prog_type.m:
compiler/write_deps_file.m:
Conform to changes.
diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index 74e354e..07e3cab 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -1598,8 +1598,8 @@ link(ErrorStream, LinkTargetType, ModuleName,
ObjectsList, Succeeded, !IO) :-
LinkSucceeded, !IO)
;
LinkTargetType = java_archive,
- create_java_archive(ErrorStream, ModuleName, OutputFileName,
- ObjectsList, LinkSucceeded, !IO)
+ create_java_archive(ErrorStream, OutputFileName, ObjectsList,
+ LinkSucceeded, !IO)
;
LinkTargetType = erlang_archive,
create_erlang_archive(ErrorStream, ModuleName, OutputFileName,
@@ -2326,21 +2326,71 @@ create_archive(ErrorStream, LibFileName,
Quote, ObjectList, Succeeded, !IO) :-
Succeeded, !IO)
).
-:- pred create_java_archive(io.output_stream::in, module_name::in,
- file_name::in, list(file_name)::in, bool::out, io::di, io::uo) is det.
+:- pred create_java_archive(io.output_stream::in, file_name::in,
+ list(file_name)::in, bool::out, io::di, io::uo) is det.
-create_java_archive(ErrorStream, ModuleName, JarFileName, ObjectList,
- Succeeded, !IO) :-
+create_java_archive(ErrorStream, JarFileName, ObjectList, Succeeded, !IO) :-
% XXX Maybe these should be set up as options:
Jar = "jar",
- JarCreateFlags = "cf",
- list_class_files_for_jar(ModuleName, ObjectList, ListClassFiles, !IO),
- Cmd = string.append_list([
- Jar, " ", JarCreateFlags, " ", JarFileName, " ", ListClassFiles ]),
+ list_class_files_for_jar(ObjectList, ClassSubDir, ListClassFiles, !IO),
+ (
+ ListClassFiles = [],
+ unexpected(this_file, "empty list of .class files")
+ ;
+ ListClassFiles = [_ | _]
+ ),
+
+ % Write the list of class files to a temporary file and pass the name of
+ % the temporary file to jar using @syntax. The list of class files can be
+ % extremely long.
+ io.make_temp(TempFileName, !IO),
+ io.open_output(TempFileName, OpenResult, !IO),
+ (
+ OpenResult = ok(Stream),
+ list.foldl(write_jar_class_argument(Stream, ClassSubDir),
+ ListClassFiles, !IO),
+ io.close_output(Stream, !IO),
+
+ Cmd = string.append_list(
+ [Jar, " cf ", JarFileName, " @", TempFileName]),
+ invoke_system_command(ErrorStream, cmd_verbose_commands, Cmd,
+ Succeeded, !IO),
+ io.remove_file(TempFileName, _, !IO),
+
+ (
+ Succeeded = yes,
+ % Add an index, which is supposed to speed up class loading.
+ IndexCmd = string.append_list([Jar, " i ", JarFileName]),
+ invoke_system_command(ErrorStream, cmd_verbose_commands, IndexCmd,
+ _, !IO)
+ ;
+ Succeeded = no,
+ io.remove_file(JarFileName, _, !IO)
+ )
+ ;
+ OpenResult = error(Error),
+ io.write_string(ErrorStream, "Error creating `", !IO),
+ io.write_string(ErrorStream, TempFileName, !IO),
+ io.write_string(ErrorStream, "': ", !IO),
+ io.write_string(ErrorStream, io.error_message(Error), !IO),
+ io.nl(ErrorStream, !IO),
+ Succeeded = no
+ ).
+
+:- pred write_jar_class_argument(io.output_stream::in, string::in, string::in,
+ io::di, io::uo) is det.
- invoke_system_command(ErrorStream, cmd_verbose_commands, Cmd, Succeeded,
- !IO).
+write_jar_class_argument(Stream, ClassSubDir, ClassFileName, !IO) :-
+ ( dir.path_name_is_absolute(ClassFileName) ->
+ true
+ ;
+ io.write_string(Stream, "-C ", !IO),
+ io.write_string(Stream, ClassSubDir, !IO),
+ io.write_string(Stream, " ", !IO)
+ ),
+ io.write_string(Stream, ClassFileName, !IO),
+ io.nl(Stream, !IO).
%-----------------------------------------------------------------------------%
diff --git a/compiler/file_names.m b/compiler/file_names.m
index c0ef87b..6fbaa3f 100644
--- a/compiler/file_names.m
+++ b/compiler/file_names.m
@@ -120,6 +120,10 @@
%
:- pred module_name_to_make_var_name(module_name::in, string::out) is det.
+ % Return the name of the directory containing Java `.class' files.
+ %
+:- pred get_class_dir_name(string::out, io::di, io::uo) is det.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -249,31 +253,31 @@ choose_file_name(_ModuleName, BaseParentDirs,
BaseName, Ext, Search, MkDir,
globals.lookup_string_option(Globals, shared_library_extension,
SharedLibExt),
(
- (
- UseSubdirs = no
- ;
- % If we're searching for (rather than writing) a `.mih' file,
- % use the plain file name. This is so that searches for files
- % in installed libraries will work. `--c-include-directory' is
- % set so that searches for files in the current directory will
- % work.
- % Similarly for `.hrl' files. We set `--erlang-include-directory'
- % for those.
-
- Search = do_search,
- ( Ext = ".mih"
- ; Ext = ".mih.tmp"
- ; Ext = ".hrl"
- ; Ext = ".hrl.tmp"
- )
+ % If we're searching for (rather than writing) a `.mih' file,
+ % use the plain file name. This is so that searches for files
+ % in installed libraries will work. `--c-include-directory' is
+ % set so that searches for files in the current directory will
+ % work.
+ % Similarly for `.hrl' files. We set `--erlang-include-directory'
+ % for those.
+
+ Search = do_search,
+ ( Ext = ".mih"
+ ; Ext = ".mih.tmp"
+ ; Ext = ".hrl"
+ ; Ext = ".hrl.tmp"
)
->
- % XXX this was part of a change to support submodules in Java
- % but broke the high level C backend
- % make_file_name(BaseParentDirs, do_not_search, do_create_dirs,
- % BaseName, Ext, FileName, !IO)
FileName = BaseName
;
+ UseSubdirs = no
+ ->
+ % Even if not putting files in a `Mercury' directory, Java files will
+ % have non-empty BaseParentDirs (the package) which may need to be
+ % created.
+ make_file_name(BaseParentDirs, Search, MkDir, 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
% Mmake targets names go in the current directory
@@ -482,6 +486,24 @@ make_file_name(SubDirNames, Search, MkDir,
BaseName, Ext, FileName, !IO) :-
FileName = dir.relative_path_name_from_components(Components)
).
+get_class_dir_name(ClassDirName, !IO) :-
+ globals.io_get_globals(Globals, !IO),
+ globals.lookup_bool_option(Globals, use_grade_subdirs, UseGradeSubdirs),
+ globals.lookup_bool_option(Globals, use_subdirs, UseSubdirs),
+ (
+ UseGradeSubdirs = yes
+ ->
+ grade_directory_component(Globals, Grade),
+ globals.lookup_string_option(Globals, fullarch, FullArch),
+ ClassDirName = "Mercury" / Grade / FullArch / "Mercury" / "classs"
+ ;
+ UseSubdirs = yes
+ ->
+ ClassDirName = "Mercury" / "classs"
+ ;
+ ClassDirName = "."
+ ).
+
:- pred file_is_arch_or_grade_dependent(globals::in, string::in) is semidet.
file_is_arch_or_grade_dependent(_, Ext) :-
diff --git a/compiler/java_names.m b/compiler/java_names.m
index 485b87f..ab30f76 100644
--- a/compiler/java_names.m
+++ b/compiler/java_names.m
@@ -175,7 +175,16 @@ append_underscore_sym_name(SymName0) = SymName :-
%-----------------------------------------------------------------------------%
java_module_name(ModuleName) = JavaModuleName :-
- QualModuleName = qualify_mercury_std_library_module_name(ModuleName),
+ % Put a "mercury" prefix on the module name if it doesn't already have one,
+ % so that even unqualified module names to end up in a Java package.
+ % Java doesn't allow packaged classes to import types from the default
+ % unnamed package. We don't do this earlier so as not to disturb other
+ % MLDS backends.
+ ( outermost_qualifier(ModuleName) = "mercury" ->
+ QualModuleName = ModuleName
+ ;
+ QualModuleName = add_outermost_qualifier("mercury", ModuleName)
+ ),
mangle_sym_name_for_java_2(QualModuleName, module_qual,
package_name_mangling, JavaModuleName).
diff --git a/compiler/module_cmds.m b/compiler/module_cmds.m
index be586c0..41bc297 100644
--- a/compiler/module_cmds.m
+++ b/compiler/module_cmds.m
@@ -139,18 +139,20 @@
:- pred create_java_shell_script(module_name::in, bool::out,
io::di, io::uo) is det.
- % Given a list .class files, return the string that should be passed
- % to `jar' to reference those class files.
+ % Given a list .class files, return the list of .class files that should be
+ % passed to `jar'. This is required because nested classes are in separate
+ % files which we don't know about, so we have to scan the directory to
+ % figure out which files were produced by `javac'.
%
-:- pred list_class_files_for_jar(module_name::in, list(string)::in,
- string::out, io::di, io::uo) is det.
+:- pred list_class_files_for_jar(list(string)::in, string::out,
+ list(string)::out, io::di, io::uo) is det.
% Given a `mmake' variable reference to a list of .class files, return an
% expression that generates the list of arguments for `jar' to reference
% those class files.
%
-:- pred list_class_files_for_jar_mmake(module_name::in, string::in,
- string::out, io::di, io::uo) is det.
+:- pred list_class_files_for_jar_mmake(string::in, string::out, io::di, io::uo)
+ is det.
% Get the value of the Java class path from the environment. (Normally
% it will be obtained from the CLASSPATH environment variable, but if
@@ -184,9 +186,13 @@
:- import_module libs.options.
:- import_module parse_tree.error_util.
:- import_module parse_tree.file_names.
+:- import_module parse_tree.java_names.
+:- import_module char.
:- import_module dir.
:- import_module getopt_io.
+:- import_module int.
+:- import_module set.
:- import_module string.
%-----------------------------------------------------------------------------%
@@ -666,31 +672,31 @@ create_java_shell_script(MainModuleName,
Succeeded, !IO) :-
maybe_write_string(Verbose, "% Generating shell script `" ++
FileName ++ "'...\n", !IO),
- module_name_to_file_name(MainModuleName, ".class", do_not_create_dirs,
- ClassFileName, !IO),
- DirName = dir.dirname(ClassFileName),
+ get_class_dir_name(ClassDirName, !IO),
% XXX PathSeparator should be ";" on Windows
PathSeparator = ":",
globals.io_lookup_accumulating_option(java_classpath, Java_Incl_Dirs0,
!IO),
% We prepend the .class files' directory and the current CLASSPATH.
- Java_Incl_Dirs = [DirName, "$CLASSPATH" | Java_Incl_Dirs0],
+ Java_Incl_Dirs = [ClassDirName, "$CLASSPATH" | Java_Incl_Dirs0],
ClassPath = string.join_list(PathSeparator, Java_Incl_Dirs),
globals.io_lookup_string_option(java_interpreter, Java, !IO),
- module_name_to_file_name(MainModuleName, "", do_not_create_dirs,
- Name_No_Extn, !IO),
+ ClassName = sym_name_to_string(java_module_name(MainModuleName)),
+ % Remove symlink in the way, if any.
+ io.remove_file(FileName, _, !IO),
io.open_output(FileName, OpenResult, !IO),
(
OpenResult = ok(ShellScript),
% XXX On Windows we should output a .bat file instead
- io.write_string(ShellScript, "#!/bin/sh\n", !IO),
- io.write_string(ShellScript, "CLASSPATH=" ++ ClassPath ++ "\n", !IO),
- io.write_string(ShellScript, "export CLASSPATH\n", !IO),
- io.write_string(ShellScript, "exec " ++ Java ++ " ", !IO),
- io.write_string(ShellScript, Name_No_Extn ++ " \"$@\"\n", !IO),
+ list.foldl(io.write_string(ShellScript), [
+ "#!/bin/sh\n",
+ "CLASSPATH=", ClassPath, "\n",
+ "export CLASSPATH\n",
+ "exec ", Java, " ", ClassName, " \"$@\"\n"
+ ], !IO),
io.close_output(ShellScript, !IO),
io.call_system("chmod a+x " ++ FileName, ChmodResult, !IO),
(
@@ -713,39 +719,75 @@ create_java_shell_script(MainModuleName,
Succeeded, !IO) :-
Succeeded = no
).
-list_class_files_for_jar(ModuleName, ClassFiles, ListClassFiles, !IO) :-
+list_class_files_for_jar(MainClassFiles, ClassSubDir, ListClassFiles, !IO) :-
globals.io_lookup_bool_option(use_subdirs, UseSubdirs, !IO),
globals.io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs, !IO),
AnySubdirs = UseSubdirs `or` UseGradeSubdirs,
(
AnySubdirs = yes,
- module_name_to_file_name(ModuleName, ".class", do_not_create_dirs,
- ClassFile, !IO),
- ClassSubdir = dir.dirname(ClassFile),
- % Here we use the `-C' option of jar to change directory during
- % execution and strip away the Mercury/classs/
- % prefixes on class file names.
- % Otherwise, the class files would be stored as
- % Mercury/classs/*.class
- % within the jar file, which is not what we want.
- UnprefixedClassFiles = list.map(
- string.remove_prefix_if_present(ClassSubdir ++ "/"), ClassFiles),
- Arguments = ["-C", ClassSubdir | UnprefixedClassFiles]
+ get_class_dir_name(ClassSubDir, !IO)
;
AnySubdirs = no,
- Arguments = ClassFiles
+ ClassSubDir = dir.this_directory
+ ),
+
+ list.filter_map(make_nested_class_prefix, MainClassFiles,
+ NestedClassPrefixes),
+ NestedClassPrefixesSet = set.from_list(NestedClassPrefixes),
+
+ SearchDir = ClassSubDir / "mercury",
+ FollowSymLinks = yes,
+ dir.recursive_foldl2(
+ accumulate_nested_class_files(NestedClassPrefixesSet),
+ SearchDir, FollowSymLinks, [], Result, !IO),
+ (
+ Result = ok(NestedClassFiles),
+ AllClassFiles0 = MainClassFiles ++ NestedClassFiles,
+ % Remove the `Mercury/classs' prefix if present.
+ ( ClassSubDir = dir.this_directory ->
+ AllClassFiles = AllClassFiles0
+ ;
+ AllClassFiles = list.map(
+ string.remove_prefix_if_present(ClassSubDir ++ "/"),
+ AllClassFiles0)
+ ),
+ list.sort(AllClassFiles, ListClassFiles)
+ ;
+ Result = error(_, Error),
+ unexpected(this_file, io.error_message(Error))
+ ).
+
+:- pred make_nested_class_prefix(string::in, string::out) is semidet.
+
+make_nested_class_prefix(ClassFileName, ClassPrefix) :-
+ % Nested class files are named "Class$Nested_1$Nested_2.class".
+ string.remove_suffix(ClassFileName, ".class", BaseName),
+ ClassPrefix = BaseName ++ "$".
+
+:- pred accumulate_nested_class_files(set(string)::in, string::in, string::in,
+ io.file_type::in, bool::out, list(string)::in, list(string)::out,
+ io::di, io::uo) is det.
+
+accumulate_nested_class_files(NestedClassPrefixes, DirName, BaseName,
+ _FileType, Continue, !Acc, !IO) :-
+ (
+ string.sub_string_search(BaseName, "$", Dollar),
+ BaseNameToDollar = string.left(BaseName, Dollar + 1),
+ set.contains(NestedClassPrefixes, DirName / BaseNameToDollar)
+ ->
+ !:Acc = [DirName / BaseName | !.Acc]
+ ;
+ true
),
- ListClassFiles = string.join_list(" ", Arguments).
+ Continue = yes.
-list_class_files_for_jar_mmake(ModuleName, ClassFiles, ListClassFiles, !IO) :-
+list_class_files_for_jar_mmake(ClassFiles, ListClassFiles, !IO) :-
globals.io_lookup_bool_option(use_subdirs, UseSubdirs, !IO),
globals.io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs, !IO),
AnySubdirs = UseSubdirs `or` UseGradeSubdirs,
(
AnySubdirs = yes,
- module_name_to_file_name(ModuleName, ".class", do_not_create_dirs,
- ClassFile, !IO),
- ClassSubdir = dir.dirname(ClassFile),
+ get_class_dir_name(ClassSubdir, !IO),
% Here we use the `-C' option of jar to change directory during
% execution, then use sed to strip away the Mercury/classs/
% prefix to the class files.
diff --git a/compiler/module_qual.m b/compiler/module_qual.m
index fdcb164..dc9c392 100644
--- a/compiler/module_qual.m
+++ b/compiler/module_qual.m
@@ -2138,7 +2138,7 @@ get_partial_qualifiers_2(ImplicitPart,
ExplicitPart, ModuleIdSet,
(
ImplicitPart = qualified(Parent, Child),
NextImplicitPart = Parent,
- NextExplicitPart = insert_module_qualifier(Child, ExplicitPart),
+ NextExplicitPart = add_outermost_qualifier(Child, ExplicitPart),
get_partial_qualifiers_2(NextImplicitPart, NextExplicitPart,
ModuleIdSet, !Qualifiers)
;
diff --git a/compiler/prog_type.m b/compiler/prog_type.m
index 90a8a81..6694ffc 100644
--- a/compiler/prog_type.m
+++ b/compiler/prog_type.m
@@ -531,10 +531,10 @@ type_to_ctor_and_args(Type, TypeCtor, Args) :-
SymName = SymName0
;
Purity = purity_semipure,
- SymName = insert_module_qualifier("semipure", SymName0)
+ SymName = add_outermost_qualifier("semipure", SymName0)
;
Purity = purity_impure,
- SymName = insert_module_qualifier("impure", SymName0)
+ SymName = add_outermost_qualifier("impure", SymName0)
),
TypeCtor = type_ctor(SymName, Arity)
;
diff --git a/compiler/write_deps_file.m b/compiler/write_deps_file.m
index 061fbd8..afe392c 100644
--- a/compiler/write_deps_file.m
+++ b/compiler/write_deps_file.m
@@ -1917,8 +1917,7 @@ generate_dep_file(SourceFileName, ModuleName,
DepsMap, DepStream, !IO) :-
], !IO),
ClassFiles = "$(" ++ MakeVarName ++ ".classes)",
- list_class_files_for_jar_mmake(ModuleName, ClassFiles, ListClassFiles,
- !IO),
+ list_class_files_for_jar_mmake(ClassFiles, ListClassFiles, !IO),
io.write_strings(DepStream, [
JarFileName, " : ", "$(", MakeVarName, ".classes)\n",
"\t$(JAR) $(JAR_CREATE_FLAGS) ", JarFileName, " ",
diff --git a/library/Mmakefile b/library/Mmakefile
index 5bcc831..53e0b0b 100644
--- a/library/Mmakefile
+++ b/library/Mmakefile
@@ -242,25 +242,11 @@ ils: $(STD_LIB_NAME).ils
javas: $(STD_LIB_NAME).javas
endif
-# The names `int', `float', and `char' can't be used as class names,
-# because they are Java keywords. So we use `mr_int', `mr_float', and
-# `mr_char' instead. `enum' is also a keyword in Java 1.5, so we
-# likewise use `mr_enum'. Since Java implementations often assume that
-# a class foo is located in a file foo.java, we similarly mangle the
-# Java file names for these standard library modules.
-# We also need to fix up the file names for nested modules.
-JAVAS = ` echo $($(STD_LIB_NAME).javas) | sed \
- -e 's/ int.java/ mr_int.java/' \
- -e 's/ float.java/ mr_float.java/' \
- -e 's/ char.java/ mr_char.java/' \
- -e 's/ enum.java/ mr_enum.java/' \
- -e 's: bit_buffer.read.java: bit_buffer_/read.java:' \
- -e 's: bit_buffer.write.java: bit_buffer_/write.java:' \
- -e 's: stream.string_writer.java: stream_/string_writer.java:' \
- -e 's: string.builder.java: string_/builder.java:' \
- -e 's: thread.channel.java: thread_/channel.java:' \
- -e 's: thread.mvar.java: thread_/mvar.java:' \
- -e 's: thread.semaphore.java: thread_/semaphore.java:' `
+# The compiler names Java files differently to the original source files to
+# avoid keywords, and will place them in subdirectories to reflect package
+# names. Instead of replicating that logic here we just use a wildcard to
+# find the file names.
+JAVAS = $(wildcard mercury/*.java mercury/*_/*.java)
# We need to invoke javac on all of the classes at the same time,
# rather than compiling them separately. This is needed because
@@ -269,16 +255,14 @@ JAVAS = ` echo $($(STD_LIB_NAME).javas) | sed \
classes: javas java_symlinks
$(JAVAC) $(ALL_JAVACFLAGS) $(JAVAS)
-# javac expects to find the sources for symbols named mercury.* in
-# files mercury/*, and likewise for symbols named mercury.runtime.*
-# in mercury/runtime/*. But in our sources, those symbols actually
-# come from this directory (library/*) and from java/runtime/*,
-# respectively. So we set up some symbolic links to help
-# javac find the way to the sources.
+# javac expects to find the sources for symbols named mercury.runtime.* in
+# mercury/runtime/*, but in our sources those symbols actually come from
+# java/runtime/*. So we set up a symbolic link to help javac find the way to
+# the sources.
.PHONY: java_symlinks
java_symlinks:
- [ -d mercury ] || ln -s . mercury
- [ -d runtime ] || ln -s $(MERCURY_DIR)/java/runtime .
+ [ -d mercury ] || mkdir mercury
+ [ -d mercury/runtime ] || ln -s ../../java/runtime mercury/runtime
# 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.
diff --git a/mdbcomp/prim_data.m b/mdbcomp/prim_data.m
index c00cb36..04b909f 100644
--- a/mdbcomp/prim_data.m
+++ b/mdbcomp/prim_data.m
@@ -249,17 +249,15 @@
%
:- func transform_sym_base_name(func(string) = string, sym_name) = sym_name.
- % insert_module_qualifier(ModuleName, SymName0) = SymName:
- %
- % Prepend the specified ModuleName onto the module qualifiers in SymName0,
- % giving SymName.
- %
-:- func insert_module_qualifier(string, sym_name) = sym_name.
-
% Given a sym_name return the top level qualifier of that name.
%
:- func outermost_qualifier(sym_name) = string.
+ % add_outermost_qualifier(ModuleName, SymName0) = SymName:
+ %
+ % Prepend the specified ModuleName onto the module qualifiers in SymName0,
+ % giving SymName.
+ %
:- func add_outermost_qualifier(string, sym_name) = sym_name.
% Remove and return the top level qualifier of a sym_name.
@@ -389,7 +387,7 @@ string_to_sym_name_sep(String, ModuleSeparator) = Result :-
% This would be simpler if we had a string.rev_sub_string_search/3 pred.
% With that, we could search for underscores right-to-left, and construct
% the resulting symbol directly. Instead, we search for them left-to-right,
- % and then call insert_module_qualifier to fix things up.
+ % and then call add_outermost_qualifier to fix things up.
(
string.sub_string_search(String, ModuleSeparator, LeftLength),
LeftLength > 0
@@ -400,7 +398,7 @@ string_to_sym_name_sep(String, ModuleSeparator) = Result :-
RightLength = StringLength - LeftLength - SeparatorLength,
string.right(String, RightLength, Name),
NameSym = string_to_sym_name_sep(Name, ModuleSeparator),
- Result = insert_module_qualifier(ModuleName, NameSym)
+ Result = add_outermost_qualifier(ModuleName, NameSym)
;
Result = unqualified(String)
).
@@ -484,16 +482,6 @@ transform_sym_base_name(TransformFunc, SymName0)
= SymName :-
SymName = qualified(Module, TransformFunc(Name0))
).
-insert_module_qualifier(ModuleName, SymName0) = SymName :-
- (
- SymName0 = unqualified(Name),
- SymName = qualified(unqualified(ModuleName), Name)
- ;
- SymName0 = qualified(ModuleSymName0, Name),
- ModuleSymName = insert_module_qualifier(ModuleName, ModuleSymName0),
- SymName = qualified(ModuleSymName, Name)
- ).
-
outermost_qualifier(SymName) = Name :-
(
SymName = unqualified(Name)
--------------------------------------------------------------------------
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