diff --git a/TestSuite/implicitexplicit2.pas b/TestSuite/implicitexplicit2.pas new file mode 100644 index 000000000..01e1ab6ed --- /dev/null +++ b/TestSuite/implicitexplicit2.pas @@ -0,0 +1,21 @@ +type TRec = record +val: integer; +class function operator implicit(self: BigInteger): TRec; +begin + Result.val := 3; +end; +end; + +function operator implicit(self: BigInteger): List; extensionmethod; +begin + Result := new System.Collections.Generic.List(); + Result.Add(2); +end; + +begin + var b: BigInteger := new BigInteger(2.5); + var r: List := b; + assert(r[0] = 2); + var rec: TRec := b; + assert(rec.val = 3); +end. \ No newline at end of file diff --git a/TreeConverter/NetWrappers/NetHelper.cs b/TreeConverter/NetWrappers/NetHelper.cs index a9063a1ac..0dd1e2885 100644 --- a/TreeConverter/NetWrappers/NetHelper.cs +++ b/TreeConverter/NetWrappers/NetHelper.cs @@ -994,16 +994,17 @@ namespace PascalABCCompiler.NetHelper return new List().ToArray(); } - private static compiled_function_node get_conversion(compiled_type_node in_type,compiled_type_node from, - compiled_type_node to,string op_name) + private static function_node get_conversion(compiled_type_node in_type,compiled_type_node from, + compiled_type_node to,string op_name, NetTypeScope scope) { - MethodInfo[] mia = in_type.compiled_type.GetMethods(); - foreach (MethodInfo mi in mia) + //MethodInfo[] mia = in_type.compiled_type.GetMethods(); + List mia = GetMembers(in_type.compiled_type, op_name); + + foreach (MemberInfo mbi in mia) { - if (mi.Name != op_name) - { + if (!(mbi is MethodInfo)) continue; - } + MethodInfo mi = mbi as MethodInfo; if (mi.ReturnType != to.compiled_type) { continue; @@ -1019,32 +1020,35 @@ namespace PascalABCCompiler.NetHelper } return compiled_function_node.get_compiled_method(mi); } + if (scope != null) + { + SymbolInfo si = scope.FindOnlyInType(op_name, scope); + while (si != null) + { + if (si.sym_info is common_namespace_function_node) + { + function_node fn = si.sym_info as function_node; + if (fn.return_value_type == to && fn.parameters.Count == 1 && fn.parameters[0].type == from) + { + return fn; + } + } + si = si.Next; + } + } return null; - /*Type[] arr = new Type[1]; - arr[0] = from.compiled_type; - MethodInfo mi=in_type.compiled_type.GetMethod(op_name,arr); - if (mi == null) - { - return null; - } - if (mi.ReturnType != to.compiled_type) - { - return null; - } - return compiled_function_node.get_compiled_method(mi); - */ } - public static compiled_function_node get_implicit_conversion(compiled_type_node in_type, compiled_type_node from, - compiled_type_node to) + public static function_node get_implicit_conversion(compiled_type_node in_type, compiled_type_node from, + compiled_type_node to, NetTypeScope scope) { - return get_conversion(in_type, from, to, compiler_string_consts.implicit_operator_name); + return get_conversion(in_type, from, to, compiler_string_consts.implicit_operator_name, scope); } - public static compiled_function_node get_explicit_conversion(compiled_type_node in_type, compiled_type_node from, - compiled_type_node to) + public static function_node get_explicit_conversion(compiled_type_node in_type, compiled_type_node from, + compiled_type_node to, NetTypeScope scope) { - return get_conversion(in_type, from, to, compiler_string_consts.explicit_operator_name); + return get_conversion(in_type, from, to, compiler_string_consts.explicit_operator_name, scope); } public static compiled_type_node get_array_type(compiled_type_node element_type) diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 43f35b848..b9ca46fea 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -11347,6 +11347,8 @@ namespace PascalABCCompiler.TreeConverter if ((cnfn.name == compiler_string_consts.implicit_operator_name || cnfn.name == compiler_string_consts.explicit_operator_name)) { + if (cnfn.parameters.Count != 1) + AddError(new SimpleSemanticError(cnfn.loc,"EXTENSION_METHODS_MUST_HAVE_LEAST_ONE_PARAMETER")); if (!convertion_data_and_alghoritms.eq_type_nodes(tn, cnfn.ConnectedToType) && !convertion_data_and_alghoritms.eq_type_nodes(cnfn.ConnectedToType as type_node, cnfn.parameters[0].type)) { AddError(get_location(_function_header.return_type), "RETURN_VALUE_SHOULD_HAVE_TYPE_{0}", (cnfn.ConnectedToType as type_node).PrintableName); diff --git a/TreeConverter/TreeRealization/types.cs b/TreeConverter/TreeRealization/types.cs index 31c5b50b4..85ee57717 100644 --- a/TreeConverter/TreeRealization/types.cs +++ b/TreeConverter/TreeRealization/types.cs @@ -2149,8 +2149,7 @@ namespace PascalABCCompiler.TreeRealization } return null; } - else - return null; + return null; } public override function_node get_explicit_conversion_to(type_node ctn) @@ -3310,9 +3309,11 @@ namespace PascalABCCompiler.TreeRealization function_node fn = null; if (!_implicit_convertions_to.TryGetValue(cctn, out fn)) { - fn = NetHelper.NetHelper.get_implicit_conversion(this, this, cctn); - _implicit_convertions_to.Add(cctn, fn); + fn = NetHelper.NetHelper.get_implicit_conversion(this, this, cctn, scope); + if (fn is compiled_function_node) + _implicit_convertions_to.Add(cctn, fn); } + return fn; } @@ -3327,8 +3328,9 @@ namespace PascalABCCompiler.TreeRealization function_node fn = null; if (!_implicit_convertions_from.TryGetValue(cctn, out fn)) { - fn = NetHelper.NetHelper.get_implicit_conversion(this, cctn, this); - _implicit_convertions_from.Add(cctn, fn); + fn = NetHelper.NetHelper.get_implicit_conversion(this, cctn, this, scope); + if (fn is compiled_function_node) + _implicit_convertions_from.Add(cctn, fn); } return fn; } @@ -3346,8 +3348,9 @@ namespace PascalABCCompiler.TreeRealization function_node fn = null; if (_explicit_convertions_to.TryGetValue(ctn, out fn)) return fn; - fn = NetHelper.NetHelper.get_explicit_conversion(this, this, cctn); - _explicit_convertions_to.Add(ctn, fn); + fn = NetHelper.NetHelper.get_explicit_conversion(this, this, cctn, scope); + if (fn is compiled_function_node) + _explicit_convertions_to.Add(ctn, fn); return fn; } @@ -3383,8 +3386,9 @@ namespace PascalABCCompiler.TreeRealization return fn; } - fn = NetHelper.NetHelper.get_explicit_conversion(this, cctn, this); - _explicit_convertions_from.Add(ctn, fn); + fn = NetHelper.NetHelper.get_explicit_conversion(this, cctn, this, scope); + if (fn is compiled_function_node) + _explicit_convertions_from.Add(ctn, fn); return fn; }