mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
compiler/mlds.m:
Delete the mlds_class_kind type, because
- after the simplification of mlds_interface_ids, its mlds_interface
function symbol became unused, and
- after the deleting of that function symbol, it would have become
a dummy type anyway.
Delete mlds_class_kind fields from the mlds_class_defn and mlds_class_id
types.
compiler/mlds_to_cs_class.m:
Conform to the changes above.
Inline two predicates, and simplify the resulting code.
compiler/ml_code_util.m:
compiler/ml_rename_classes.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/ml_unify_gen_util.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_class.m:
compiler/mlds_to_c_type.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_class.m:
compiler/mlds_to_java_type.m:
compiler/mlds_to_java_wrap.m:
compiler/mlds_to_target_util.m:
Conform to the changes above.
349 lines
13 KiB
Mathematica
349 lines
13 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2010-2012 The University of Melbourne.
|
|
% Copyright (C) 2013-2018 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output class declarations and definitions in C#.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module ml_backend.mlds_to_cs_class.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.indent.
|
|
:- import_module ml_backend.mlds.
|
|
:- import_module ml_backend.mlds_to_cs_util.
|
|
|
|
:- import_module io.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred output_class_defn_for_csharp(csharp_out_info::in,
|
|
io.text_output_stream::in, indent::in, mlds_class_defn::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred output_enum_class_defn_for_csharp(csharp_out_info::in,
|
|
io.text_output_stream::in, indent::in, mlds_enum_class_defn::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred output_env_defn_for_csharp(csharp_out_info::in,
|
|
io.text_output_stream::in, indent::in, mlds_env_defn::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred output_struct_defn_for_csharp(csharp_out_info::in,
|
|
io.text_output_stream::in, indent::in, mlds_struct_defn::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module libs.globals.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module ml_backend.mlds_to_cs_data.
|
|
:- import_module ml_backend.mlds_to_cs_func.
|
|
:- import_module ml_backend.mlds_to_cs_name.
|
|
:- import_module ml_backend.mlds_to_cs_type.
|
|
:- import_module ml_backend.mlds_to_target_util.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.java_names.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module bool.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module maybe.
|
|
:- import_module require.
|
|
:- import_module string.
|
|
:- import_module term.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
output_class_defn_for_csharp(Info0, Stream, Indent, ClassDefn, !IO) :-
|
|
ClassDefn = mlds_class_defn(ClassName, ClassArity, _Context, Flags,
|
|
_Imports, Inherits, Implements, TypeParams,
|
|
MemberFields, MemberClasses, MemberMethods, Ctors),
|
|
expect(unify(MemberMethods, []), $pred, "MemberMethods != []"),
|
|
Info = Info0 ^ csoi_univ_tvars := TypeParams,
|
|
|
|
IndentStr = indent2_string(Indent),
|
|
Flags = mlds_class_decl_flags(Access, Overridability, Constness),
|
|
AccessPrefix = access_prefix_for_csharp(Access),
|
|
OverridePrefix = overrideability_prefix_for_csharp(Overridability),
|
|
ConstnessPrefix = constness_prefix_for_csharp(Constness),
|
|
ClassNameStr =
|
|
unqual_class_name_to_ll_string_for_csharp(ClassName, ClassArity),
|
|
OutputGenerics = Info ^ csoi_output_generics,
|
|
(
|
|
OutputGenerics = do_output_generics,
|
|
GenericTypeParamsStr = generic_tvars_to_string(TypeParams)
|
|
;
|
|
OutputGenerics = do_not_output_generics,
|
|
GenericTypeParamsStr = ""
|
|
),
|
|
io.format(Stream, "%s[System.Serializable]\n", [s(IndentStr)], !IO),
|
|
io.format(Stream, "%s%s%s%sclass %s%s\n",
|
|
[s(IndentStr), s(AccessPrefix),
|
|
s(OverridePrefix), s(ConstnessPrefix),
|
|
s(ClassNameStr), s(GenericTypeParamsStr)], !IO),
|
|
SuperClassNames = get_superclass_names(Info, Inherits, Implements),
|
|
(
|
|
SuperClassNames = []
|
|
;
|
|
SuperClassNames = [_ | _],
|
|
SuperClassesStr = string.join_list(", ", SuperClassNames),
|
|
io.format(Stream, "%s : %s\n",
|
|
[s(IndentStr), s(SuperClassesStr)], !IO)
|
|
),
|
|
|
|
io.format(Stream, "%s{\n", [s(IndentStr)], !IO),
|
|
Indent1 = Indent + 1,
|
|
list.foldl(
|
|
output_field_var_defn_for_csharp(Info, Stream, Indent1),
|
|
MemberFields, !IO),
|
|
list.foldl(
|
|
output_class_defn_for_csharp(Info, Stream, Indent1),
|
|
MemberClasses, !IO),
|
|
io.nl(Stream, !IO),
|
|
|
|
CtorsAux = oa_cname(ClassName, ClassArity),
|
|
list.foldl(
|
|
output_function_defn_for_csharp(Info, Stream, Indent1, CtorsAux),
|
|
Ctors, !IO),
|
|
io.format(Stream, "%s}\n\n", [s(IndentStr)], !IO).
|
|
|
|
output_enum_class_defn_for_csharp(Info0, Stream, Indent, EnumDefn, !IO) :-
|
|
EnumDefn = mlds_enum_class_defn(ClassName, ClassArity, _Context,
|
|
Inherits, Implements, TypeParams, _ValueField, EnumConsts, Ctors),
|
|
Info = Info0 ^ csoi_univ_tvars := TypeParams,
|
|
|
|
IndentStr = indent2_string(Indent),
|
|
AccessPrefix = access_prefix_for_csharp(class_public),
|
|
PerInstancePrefix = per_instance_prefix_for_csharp(per_instance),
|
|
OverridePrefix = overrideability_prefix_for_csharp(overridable),
|
|
ConstnessPrefix = constness_prefix_for_csharp(modifiable),
|
|
ClassNameStr =
|
|
unqual_class_name_to_ll_string_for_csharp(ClassName, ClassArity),
|
|
OutputGenerics = Info ^ csoi_output_generics,
|
|
(
|
|
OutputGenerics = do_output_generics,
|
|
GenericTypeParamsStr = generic_tvars_to_string(TypeParams)
|
|
;
|
|
OutputGenerics = do_not_output_generics,
|
|
GenericTypeParamsStr = ""
|
|
),
|
|
io.format(Stream, "%s[System.Serializable]\n", [s(IndentStr)], !IO),
|
|
io.format(Stream, "%s%s%s%s%senum %s%s\n",
|
|
[s(IndentStr), s(AccessPrefix), s(PerInstancePrefix),
|
|
s(OverridePrefix), s(ConstnessPrefix),
|
|
s(ClassNameStr), s(GenericTypeParamsStr)], !IO),
|
|
expect(unify(Inherits, inherits_nothing), $pred,
|
|
"Inherits != inherits_nothing"),
|
|
expect(unify(Implements, no), $pred, "Implements != no"),
|
|
|
|
io.format(Stream, "%s{\n", [s(IndentStr)], !IO),
|
|
Indent1 = Indent + 1,
|
|
Indent2Str = indent2_string(Indent1),
|
|
list.foldl(output_enum_constant_for_csharp(Info, Stream, Indent2Str),
|
|
EnumConsts, !IO),
|
|
|
|
CtorsAux = oa_cname(ClassName, ClassArity),
|
|
list.foldl(
|
|
output_function_defn_for_csharp(Info, Stream, Indent1, CtorsAux),
|
|
Ctors, !IO),
|
|
io.format(Stream, "%s}\n\n", [s(IndentStr)], !IO).
|
|
|
|
output_env_defn_for_csharp(Info, Stream, Indent, EnvDefn, !IO) :-
|
|
EnvDefn = mlds_env_defn(EnvName, _Context, MemberFields),
|
|
IndentStr = indent2_string(Indent),
|
|
Indent1 = Indent + 1,
|
|
Indent1Str = indent2_string(Indent1),
|
|
EnvNameStr = unqual_class_name_to_ll_string_for_csharp(EnvName, 0),
|
|
EnvTypeStr = type_to_string_for_csharp(Info, mlds_generic_env_ptr_type),
|
|
|
|
io.format(Stream, "%s[System.Serializable]\n", [s(IndentStr)], !IO),
|
|
io.format(Stream, "%sprivate class %s\n",
|
|
[s(IndentStr), s(EnvNameStr)], !IO),
|
|
io.format(Stream, "%s: %s\n", [s(Indent1Str), s(EnvTypeStr)], !IO),
|
|
io.format(Stream, "%s{\n", [s(IndentStr)], !IO),
|
|
list.foldl(
|
|
output_field_var_defn_for_csharp(Info, Stream, Indent1),
|
|
MemberFields, !IO),
|
|
io.format(Stream, "%s}\n\n", [s(IndentStr)], !IO).
|
|
|
|
output_struct_defn_for_csharp(Info, Stream, Indent, StructDefn, !IO) :-
|
|
StructDefn = mlds_struct_defn(StructName, _Context,
|
|
MemberFields, MaybeCtor),
|
|
(
|
|
MaybeCtor = no,
|
|
unexpected($pred, "MaybeCtor = no")
|
|
;
|
|
MaybeCtor = yes(Ctor)
|
|
),
|
|
Indent1 = Indent + 1,
|
|
IndentStr = indent2_string(Indent),
|
|
StructNameStr = unqual_class_name_to_ll_string_for_csharp(StructName, 0),
|
|
|
|
io.format(Stream, "%sprivate struct %s\n",
|
|
[s(IndentStr), s(StructNameStr)], !IO),
|
|
io.format(Stream, "%s{\n", [s(IndentStr)], !IO),
|
|
list.foldl(
|
|
output_field_var_defn_for_csharp(Info, Stream, Indent1),
|
|
MemberFields, !IO),
|
|
io.nl(Stream, !IO),
|
|
output_function_defn_for_csharp(Info, Stream, Indent1,
|
|
oa_cname(StructName, 0), Ctor, !IO),
|
|
io.format(Stream, "%s}\n\n", [s(IndentStr)], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Output superclass that this class extends and interfaces implemented.
|
|
% C# does not support multiple inheritance, so more than one superclass
|
|
% is an error.
|
|
% XXX This predicate does not output anything.
|
|
%
|
|
:- func get_superclass_names(csharp_out_info,
|
|
mlds_class_inherits, list(mlds_interface_id)) = list(string).
|
|
|
|
get_superclass_names(Info, Inherits, Interfaces) = Supers :-
|
|
Supers0 = list.map(interface_to_string_for_csharp, Interfaces),
|
|
(
|
|
Inherits = inherits_nothing,
|
|
Supers = Supers0
|
|
;
|
|
Inherits = inherits_class(BaseClassId),
|
|
BaseClassType = mlds_class_type(BaseClassId),
|
|
BaseClassTypeName = type_to_string_for_csharp(Info, BaseClassType),
|
|
Supers = [BaseClassTypeName | Supers0]
|
|
).
|
|
|
|
:- func interface_to_string_for_csharp(mlds_interface_id) = string.
|
|
|
|
interface_to_string_for_csharp(InterfaceId) = String :-
|
|
InterfaceId = mlds_interface_id(ModuleName, ClassName),
|
|
SymName = mlds_module_name_to_sym_name(ModuleName),
|
|
mangle_sym_name_for_csharp(SymName, module_qual, ".", ModuleNameStr),
|
|
|
|
% Check if the interface is one of the ones in the runtime system.
|
|
% If it is, we don't need to output the arity.
|
|
( if interface_is_special_for_csharp(ClassName) then
|
|
String = string.format("%s.%s", [s(ModuleNameStr), s(ClassName)])
|
|
else
|
|
Arity = 0,
|
|
String = string.format("%s.%s%d",
|
|
[s(ModuleNameStr), s(ClassName), i(Arity)])
|
|
).
|
|
|
|
% Succeeds iff a given string matches the unqualified interface name
|
|
% of a interface in Mercury's C# runtime system.
|
|
%
|
|
:- pred interface_is_special_for_csharp(string::in) is semidet.
|
|
|
|
interface_is_special_for_csharp("MercuryType").
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred output_field_var_defn_for_csharp(csharp_out_info::in,
|
|
io.text_output_stream::in, indent::in, mlds_field_var_defn::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_field_var_defn_for_csharp(Info, Stream, Indent, FieldVarDefn, !IO) :-
|
|
FieldVarDefn = mlds_field_var_defn(FieldVarName, _Context, Flags,
|
|
Type, Initializer, _),
|
|
IndentStr = indent2_string(Indent),
|
|
Flags = mlds_field_var_decl_flags(PerInstance, Constness),
|
|
AccessPrefix = "public ",
|
|
PerInstancePrefix = per_instance_prefix_for_csharp(PerInstance),
|
|
ConstnessPrefix = constness_prefix_for_csharp(Constness),
|
|
TypeStr = type_to_string_for_csharp(Info, Type),
|
|
FieldVarNameStr = field_var_name_to_ll_string_for_csharp(FieldVarName),
|
|
io.format(Stream, "%s%s%s%s%s %s",
|
|
[s(IndentStr), s(AccessPrefix), s(PerInstancePrefix),
|
|
s(ConstnessPrefix), s(TypeStr), s(FieldVarNameStr)], !IO),
|
|
output_initializer_for_csharp(Info, Stream, oa_none, Indent + 1,
|
|
Type, Initializer, ";", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred output_enum_constant_for_csharp(csharp_out_info::in,
|
|
io.text_output_stream::in, string::in, mlds_enum_const_defn::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_enum_constant_for_csharp(Info, Stream, IndentStr, EnumConstDefn, !IO) :-
|
|
EnumConstDefn = mlds_enum_const_defn(VarName, _Context, EnumConst),
|
|
VarNameStr = field_var_name_to_ll_string_for_csharp(VarName),
|
|
(
|
|
EnumConst = mlds_enum_const_uint(EnumUInt),
|
|
io.format(Stream, "%s%s = %u,\n",
|
|
[s(IndentStr), s(VarNameStr), u(EnumUInt)], !IO)
|
|
;
|
|
EnumConst = mlds_enum_const_foreign(Lang, EnumNameStr, Type),
|
|
% The name might require mangling.
|
|
expect(unify(Lang, lang_csharp), $pred, "Lang != lang_csharp"),
|
|
TypeStr = type_to_string_for_csharp(Info, Type),
|
|
io.format(Stream, "%s%s = (%s) %s,\n",
|
|
[s(IndentStr), s(VarNameStr), s(TypeStr), s(EnumNameStr)], !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Every prefix string that is not empty should end with a space.
|
|
%
|
|
|
|
:- func access_prefix_for_csharp(class_access) = string.
|
|
|
|
access_prefix_for_csharp(Access) = AccessPrefix :-
|
|
(
|
|
Access = class_public,
|
|
AccessPrefix = "public "
|
|
;
|
|
Access = class_private,
|
|
AccessPrefix = "private "
|
|
).
|
|
|
|
:- func per_instance_prefix_for_csharp(per_instance) = string.
|
|
|
|
per_instance_prefix_for_csharp(PerInstance) = PerInstancePrefix :-
|
|
(
|
|
PerInstance = per_instance,
|
|
PerInstancePrefix = ""
|
|
;
|
|
PerInstance = one_copy,
|
|
PerInstancePrefix = "static "
|
|
).
|
|
|
|
:- func overrideability_prefix_for_csharp(overridability) = string.
|
|
|
|
overrideability_prefix_for_csharp(Overridability) = OverridePrefix :-
|
|
(
|
|
Overridability = sealed,
|
|
OverridePrefix = "sealed "
|
|
;
|
|
Overridability = overridable,
|
|
OverridePrefix = ""
|
|
).
|
|
|
|
:- func constness_prefix_for_csharp(constness) = string.
|
|
|
|
constness_prefix_for_csharp(Constness) = ConstnessPrefix :-
|
|
(
|
|
Constness = const,
|
|
ConstnessPrefix = "readonly "
|
|
;
|
|
Constness = modifiable,
|
|
ConstnessPrefix = ""
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module ml_backend.mlds_to_cs_class.
|
|
%---------------------------------------------------------------------------%
|