bug fix issue #36

This commit is contained in:
Бондарев Иван 2016-01-03 13:55:04 +01:00
parent 1d2ed8f88b
commit f3582c893a
4 changed files with 67 additions and 36 deletions

View file

@ -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<integer>; extensionmethod;
begin
Result := new System.Collections.Generic.List<integer>();
Result.Add(2);
end;
begin
var b: BigInteger := new BigInteger(2.5);
var r: List<integer> := b;
assert(r[0] = 2);
var rec: TRec := b;
assert(rec.val = 3);
end.

View file

@ -994,16 +994,17 @@ namespace PascalABCCompiler.NetHelper
return new List<MethodInfo>().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<MemberInfo> 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)

View file

@ -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);

View file

@ -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;
}