bug fix issues #84, #85, #89

This commit is contained in:
Бондарев Иван 2016-02-21 17:12:52 +01:00
parent 2b464dc59a
commit 1f31c20da2
17 changed files with 338 additions and 103 deletions

View file

@ -2802,6 +2802,8 @@ namespace PascalABCCompiler.PCU
cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn)); cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn));
else if (cnfn.ConnectedToType != null && cnfn.ConnectedToType.is_generic_parameter) else if (cnfn.ConnectedToType != null && cnfn.ConnectedToType.is_generic_parameter)
cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn)); cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn));
else if (cnfn.ConnectedToType is compiled_generic_instance_type_node && cnfn.ConnectedToType.original_generic.Scope != null)
cnfn.ConnectedToType.original_generic.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn));
return cnfn; return cnfn;
} }
@ -2902,6 +2904,8 @@ namespace PascalABCCompiler.PCU
cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn)); cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn));
else if (cnfn.ConnectedToType != null && cnfn.ConnectedToType.is_generic_parameter) else if (cnfn.ConnectedToType != null && cnfn.ConnectedToType.is_generic_parameter)
cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn)); cnfn.ConnectedToType.base_type.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn));
else if (cnfn.ConnectedToType is compiled_generic_instance_type_node && cnfn.ConnectedToType.original_generic.Scope != null)
cnfn.ConnectedToType.original_generic.Scope.AddSymbol(cnfn.name, new SymbolInfo(cnfn));
br.BaseStream.Seek(pos,SeekOrigin.Begin); br.BaseStream.Seek(pos,SeekOrigin.Begin);
return cnfn; return cnfn;
} }

View file

@ -0,0 +1,12 @@
function operator*<T1, T2, T3> (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod;
begin
Result := (Self[0],Self[1],v);
end;
begin
var t0 := (1,2);
var t1 := t0 * System.DateTime.Now.DayOfWeek;
assert(t1.Item3 = System.DateTime.Now.DayOfWeek);
var s := 4+Seq(1,2,3);
assert(s.ToArray()[0]=4);
end.

9
TestSuite/in1.pas Normal file
View file

@ -0,0 +1,9 @@
begin
var arr := Arr(1,2,3);
assert(5 in arr = false);
assert(2 in arr = true);
var l := new List<integer>();
l += 4;
l += 5;
assert(4 in l = true);
end.

View file

@ -1,5 +1,5 @@
begin begin
{var b: byte := 2; var b: byte := 2;
var i: integer := 3; var i: integer := 3;
var s: shortint := 4; var s: shortint := 4;
var w: word := 5; var w: word := 5;
@ -12,5 +12,5 @@ begin
assert(min(b,lw)=2); assert(min(b,lw)=2);
assert(min(i,lw)=3); assert(min(i,lw)=3);
assert(min(b,i64)=2); assert(min(b,i64)=2);
assert(min(i64,ui64)=7);} assert(min(i64,ui64)=7);
end. end.

29
TestSuite/overloads4.pas Normal file
View file

@ -0,0 +1,29 @@
var a: integer;
procedure Test(p: integer);
begin
a := 1;
end;
procedure Test<T>(p: T);
begin
a := 2;
end;
procedure Test(params p: array of integer);
begin
a := 3;
end;
procedure Test<T>(params p: array of T);
begin
a := 4;
end;
begin
Test(3);
assert(a = 1);
Test('a');
assert(a = 2);
Test(byte(3));
assert(a = 2);
Test(1,2);
assert(a = 3);
Test('a','b');
assert(a = 4);
end.

8
TestSuite/params8.pas Normal file
View file

@ -0,0 +1,8 @@
function Test<T>(a: T): sequence of T;
begin
Result := Seq(a);
end;
begin
assert(Test(2).ToArray()[0]=2);
end.

View file

@ -51,4 +51,7 @@ begin
assert(StrToInt('234')=234); assert(StrToInt('234')=234);
assert(StrToFloat('2.67')=2.67); assert(StrToFloat('2.67')=2.67);
assert(IntToStr(45)='45'); assert(IntToStr(45)='45');
var c: char := 'a';
var o: object := 'bc';
assert(c+o='abc');
end. end.

View file

@ -0,0 +1,13 @@
unit u_extensionmethods15;
function operator*<T1, T2, T3> (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod;
begin
Result := (Self[0],Self[1],v);
end;
begin
var t0 := (1,2);
var t1 := t0 * System.DateTime.Now.DayOfWeek;
assert(t1.Item3 = System.DateTime.Now.DayOfWeek);
var s := 4+Seq(1,2,3);
assert(s.ToArray()[0]=4);
end.

View file

@ -0,0 +1,31 @@
unit u_extensionmethods4;
function string.ToInt2: integer;
begin
Result := integer.Parse(Self);
end;
function string.ToWords2(params delim: array of char): array of string;
begin
Result := Self.Split(delim,System.StringSplitOptions.RemoveEmptyEntries);
end;
begin
var s := '123';
//assert(s.ToInt = 123);
var i := s.ToInt2;
assert(i=123);
s := '222';
i := s.ToInt2;
assert(i=222);
s := '111';
i := s.ToInt2();
assert(i=111);
s := 'abc def';
var arr := s.ToWords2;
assert(arr[0]='abc');
arr := 'ttt xxx'.ToWords2;
assert(arr[1] = 'xxx');
s := 'p p p';
foreach c: string in s.ToWords2 do
assert(c = 'p');
end.

View file

@ -0,0 +1,24 @@
unit u_nested_lambdas_1;
procedure p(f: Func<string, IEnumerable<string>>);
begin
end;
procedure p(f: Func<integer, IEnumerable<integer>>);
begin
var res := f(3).ToList();
assert(res.Count = 4);
assert(res[0] = 0);
assert(res[1] = 1);
assert(res[2] = 4);
assert(res[3] = 9);
end;
procedure Test;
begin
p(x -> Range(0, x).Select(y -> y * y));
end;
begin
Test;
end.

View file

@ -0,0 +1,3 @@
uses u_extensionmethods15;
begin
end.

View file

@ -0,0 +1,4 @@
uses u_extensionmethods4;
begin
end.

View file

@ -0,0 +1,4 @@
uses u_nested_lambdas_1;
begin
end.

View file

@ -295,7 +295,9 @@ namespace PascalABCCompiler.NetHelper
private static Dictionary<Type,MethodInfo[]> extension_methods = new Dictionary<Type,MethodInfo[]>(); private static Dictionary<Type,MethodInfo[]> extension_methods = new Dictionary<Type,MethodInfo[]>();
private static Dictionary<Type,List<MethodInfo>> type_extensions = new Dictionary<Type, List<MethodInfo>>(); private static Dictionary<Type,List<MethodInfo>> type_extensions = new Dictionary<Type, List<MethodInfo>>();
private static Dictionary<Type, Type> arrays_with_extension_methods = new Dictionary<Type, Type>(); private static Dictionary<Type, Type> arrays_with_extension_methods = new Dictionary<Type, Type>();
private static Dictionary<Type, Type> generics_with_extension_methods = new Dictionary<Type, Type>();
private static Dictionary<int, List<MethodInfo>> generic_array_type_extensions = new Dictionary<int, List<MethodInfo>>(); private static Dictionary<int, List<MethodInfo>> generic_array_type_extensions = new Dictionary<int, List<MethodInfo>>();
private static List<MethodInfo> generic_parameter_type_extensions = new List<MethodInfo>();
public static Type PABCSystemType = null; public static Type PABCSystemType = null;
public static Type PT4Type = null; public static Type PT4Type = null;
public static Type StringType = typeof(string); public static Type StringType = typeof(string);
@ -522,6 +524,7 @@ namespace PascalABCCompiler.NetHelper
} }
if (mths2 != null) if (mths2 != null)
mths2.Add(mi); mths2.Add(mi);
Dictionary<string, List<MemberInfo>> mht; Dictionary<string, List<MemberInfo>> mht;
if (members.TryGetValue(tmp, out mht)) if (members.TryGetValue(tmp, out mht))
{ {
@ -537,6 +540,28 @@ namespace PascalABCCompiler.NetHelper
if (!mis2.Contains(mi)) if (!mis2.Contains(mi))
mis2.Add(mi); mis2.Add(mi);
} }
if (tmp.IsGenericParameter && !generic_parameter_type_extensions.Contains(mi))
{
generic_parameter_type_extensions.Add(mi);
foreach (Type tt in members.Keys)
{
if (members.TryGetValue(tt, out mht))
{
List<MemberInfo> mis2 = null;
string name = compiler_string_consts.GetNETOperName(mi.Name);
if (name == null)
name = mi.Name;
if (!mht.TryGetValue(name, out mis2))
{
mis2 = new List<MemberInfo>();
mht.Add(name, mis2);
}
if (!mis2.Contains(mi))
mis2.Add(mi);
}
}
}
foreach (Type arr_t in arrays_with_extension_methods.Keys) foreach (Type arr_t in arrays_with_extension_methods.Keys)
{ {
if (members.TryGetValue(arr_t, out mht)) if (members.TryGetValue(arr_t, out mht))
@ -554,6 +579,24 @@ namespace PascalABCCompiler.NetHelper
mis2.Add(mi); mis2.Add(mi);
} }
} }
foreach (Type gen_t in generics_with_extension_methods.Keys)
{
if (members.TryGetValue(gen_t, out mht))
{
List<MemberInfo> mis2 = null;
string name = compiler_string_consts.GetNETOperName(mi.Name);
if (name == null)
name = mi.Name;
if (!mht.TryGetValue(name, out mis2))
{
mis2 = new List<MemberInfo>();
mht.Add(name, mis2);
}
if (!mis2.Contains(mi))
mis2.Add(mi);
}
}
} }
} }
extension_methods.Add(t, ext_meths.ToArray()); extension_methods.Add(t, ext_meths.ToArray());
@ -1077,11 +1120,6 @@ namespace PascalABCCompiler.NetHelper
} }
} }
//public static void AddMembersOfInterfaceToList(Type t, BindingFlags bf, List<MemberInfo> mem_info)
//{
//
//}
public static bool IsExtensionMethod(MethodInfo mi) public static bool IsExtensionMethod(MethodInfo mi)
{ {
if (ExtensionAttributeType != null && mi.GetCustomAttributes(ExtensionAttributeType, false).Length > 0) if (ExtensionAttributeType != null && mi.GetCustomAttributes(ExtensionAttributeType, false).Length > 0)
@ -1104,16 +1142,6 @@ namespace PascalABCCompiler.NetHelper
} }
else else
{ {
//(ssyy) Забираем также и не public члены
//(ds) добавил BindingFlags.FlattenHierarchy
//(ssyy) убрал BindingFlags.FlattenHierarchy. Зачем оно было нужно? :)
//(ds) добавил BindingFlags.FlattenHierarchy, затем что:
//Ваня Бондарев (00:52:19 16/12/2007)
//BindingFlags.FlattenHierarchy eto flag kotoryj ukazyvaet, chto chleny
//tipa nado brat' ne tolko iz samogo tipa, no i ego bazovyh klassov
//t.GetMembers(BindingFlags.FlattenHierarchy) naprimer. Dlja vybora staticheskih
//chlenov eto objazatelno.
//Без этого не работает пример
BindingFlags bf = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic; BindingFlags bf = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic;
MemberInfo[] mis; MemberInfo[] mis;
if (t.IsInterface) if (t.IsInterface)
@ -1146,20 +1174,36 @@ namespace PascalABCCompiler.NetHelper
{ {
ht[mi.Name].Add(mi); ht[mi.Name].Add(mi);
} }
if (ExtensionAttributeType != null /*&& t != StringType*/ && cur_used_assemblies.ContainsKey(SystemCoreAssembly)) if (ExtensionAttributeType != null)
{ {
List<MethodInfo> meths = null; List<MethodInfo> meths = null;
Type tmp_t = t; Type tmp_t = t;
if (tmp_t.IsArray) if (tmp_t.IsArray)
arrays_with_extension_methods[tmp_t] = tmp_t; arrays_with_extension_methods[tmp_t] = tmp_t;
if (tmp_t.IsGenericTypeDefinition)
generics_with_extension_methods[tmp_t] = tmp_t;
cached_type_extensions[t] = t; cached_type_extensions[t] = t;
while (tmp_t != null) while (tmp_t != null)
{ {
if (type_extensions.TryGetValue(tmp_t, out meths) List<MethodInfo> meths1 = null;
|| tmp_t.IsGenericType && type_extensions.TryGetValue(tmp_t.GetGenericTypeDefinition(), out meths) List<MethodInfo> meths2 = null;
|| tmp_t.IsArray && generic_array_type_extensions.TryGetValue(tmp_t.GetArrayRank(), out meths)) List<MethodInfo> meths3 = generic_parameter_type_extensions;
if (tmp_t.IsGenericType && !tmp_t.IsGenericTypeDefinition)
type_extensions.TryGetValue(tmp_t.GetGenericTypeDefinition(), out meths1);
if (tmp_t.IsArray)
generic_array_type_extensions.TryGetValue(tmp_t.GetArrayRank(), out meths2);
if (type_extensions.TryGetValue(tmp_t, out meths) || meths1 != null || meths2 != null || meths3 != null)
{ {
foreach (MethodInfo mi in meths) List<MethodInfo> all_meths = new List<MethodInfo>();
if (meths != null)
all_meths.AddRange(meths);
if (meths1 != null)
all_meths.AddRange(meths1);
if (meths2 != null)
all_meths.AddRange(meths2);
if (meths3 != null)
all_meths.AddRange(meths3);
foreach (MethodInfo mi in all_meths)
{ {
if (cur_used_assemblies.ContainsKey(mi.DeclaringType.Assembly)) if (cur_used_assemblies.ContainsKey(mi.DeclaringType.Assembly))
{ {

View file

@ -1997,61 +1997,6 @@ namespace PascalABCCompiler.TreeConverter
} }
// TODO: Исправить этот алгоритм, сделав каждый с каждым - вроде исправил - см. выше
/*j = 1;
while(j<set_of_possible_functions.Count)
{
method_compare mc = compare_methods(set_of_possible_functions[0],
set_of_possible_functions[j], tcll[0], tcll[j]);
if (mc==method_compare.greater_method)
{
tcll.remove_at(j);
set_of_possible_functions.remove_at(j);
remove=true;
}
else if (mc==method_compare.less_method)
{
tcll[0]=tcll[j];
set_of_possible_functions[0]=set_of_possible_functions[j];
tcll.remove_at(j);
set_of_possible_functions.remove_at(j);
remove=true;
}
else
{
j++;
}
}
}*/
/*remove=true;
while (remove)
{
if (set_of_possible_functions.Count == 1)
{
check_single_possible_convertion(loc, tcll[0]);
convert_function_call_expressions(set_of_possible_functions[0], parameters, tcll[0]);
return set_of_possible_functions[0];
}
remove = false;
j = 1;
while (j < set_of_possible_functions.Count)
{
}
}*/
//Тут некоторое дублирование кода, но сюда программа не должна никогда зайти.
//Должен быть выполнен if выше.
//Но пусть пока повисит. Потом нужно разобраться и убрать.
/*if (set_of_possible_functions.Count==1)
{
check_single_possible_conversion(func_call,tcll[0]);
func_call.function=set_of_possible_functions[0];
convert_function_call_expressions(func_call,tcll[0]);
func_call.type=func_call.function.return_value_type;
return func_call;
}*/
//Тупая заглушка для примитивных типов. иначе не работает +=, у нас лишком много неявных приведений //Тупая заглушка для примитивных типов. иначе не работает +=, у нас лишком много неявных приведений
//в дальнейшем может вызвать странное поведение, это надо проверить //в дальнейшем может вызвать странное поведение, это надо проверить
if (set_of_possible_functions.Count == 2 && indefinits.Count == 0) if (set_of_possible_functions.Count == 2 && indefinits.Count == 0)
@ -2083,9 +2028,59 @@ namespace PascalABCCompiler.TreeConverter
return new indefinite_functions_set(indefinits); return new indefinite_functions_set(indefinits);
} }
SortedDictionary<int, List<function_node>> distances = new SortedDictionary<int, List<function_node>>();
foreach (function_node fn in set_of_possible_functions)
{
int distance = 0;
for (int i = 0; i < parameters.Count; i++)
{
type_node from = parameters[i].type;
type_node to = fn.parameters[Math.Min(i,fn.parameters.Count-1)].type;
if (fn.parameters[Math.Min(i, fn.parameters.Count - 1)].is_params)
to = to.element_type;
distance += get_type_distance(from, to);
}
List<function_node> lst;
if (distances.TryGetValue(distance,out lst))
{
lst.Add(fn);
}
else
{
lst = new List<function_node>();
lst.Add(fn);
distances[distance] = lst;
}
}
foreach (int dist in distances.Keys)
{
List<function_node> funcs = distances[dist];
if (funcs.Count == 1)
{
possible_type_convertions_list tcl = get_conversions(parameters, funcs[0].parameters, true, loc);
convert_function_call_expressions(funcs[0], parameters, tcl);
return funcs[0];
}
}
return AddError<function_node>(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions)); return AddError<function_node>(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions));
} }
private int get_type_distance(type_node from, type_node to)
{
if (from == to)
return 0;
type_compare tc = type_table.compare_types(from, to);
if (tc == type_compare.non_comparable_type)
return 1000;
if (!from.IsInterface && to.IsInterface)
return 2;
if (tc == type_compare.less_type)
return 1;
if (tc == type_compare.greater_type)
return 3;
return 1000;
}
private function_node is_exist_eq_return_value_method(function_node fn, function_node_list funcs) private function_node is_exist_eq_return_value_method(function_node fn, function_node_list funcs)
{ {
fn = find_eq_return_value_method_in_list(fn, funcs); fn = find_eq_return_value_method_in_list(fn, funcs);

View file

@ -12170,6 +12170,8 @@ namespace PascalABCCompiler.TreeConverter
top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function));
else if (top_function.ConnectedToType.is_generic_parameter) else if (top_function.ConnectedToType.is_generic_parameter)
top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function));
else if (top_function.ConnectedToType is compiled_generic_instance_type_node && top_function.ConnectedToType.original_generic.Scope != null)
top_function.ConnectedToType.original_generic.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function));
break; break;
} }
default: default:

View file

@ -3108,7 +3108,7 @@ namespace PascalABCCompiler.TreeRealization
} }
} }
private SymbolInfo AddToSymbolInfo(SymbolInfo to, SymbolInfo from) private SymbolInfo AddToSymbolInfo(SymbolInfo to, SymbolInfo from, bool clone=false)
{ {
if (to==null) if (to==null)
{ {
@ -3117,6 +3117,16 @@ namespace PascalABCCompiler.TreeRealization
if (from == null) if (from == null)
{ {
return to; return to;
}
if (clone)
{
SymbolInfo old = to;
to = new SymbolInfo();
to.sym_info = old.sym_info;
to.Next = old.Next;
to.scope = old.scope;
to.symbol_kind = old.symbol_kind;
to.access_level = old.access_level;
} }
SymbolInfo iter=to; SymbolInfo iter=to;
while(iter.Next!=null) while(iter.Next!=null)
@ -3175,13 +3185,74 @@ namespace PascalABCCompiler.TreeRealization
SymbolInfo si = scope.SymbolTable.Find(scope, name); SymbolInfo si = scope.SymbolTable.Find(scope, name);
SymbolInfo si2 = find_in_additional_names(name); SymbolInfo si2 = find_in_additional_names(name);
SymbolInfo si3 = compiled_find(name); SymbolInfo si3 = compiled_find(name);
bool clone = false;
if (this.type_special_kind == SemanticTree.type_special_kind.array_kind && this.base_type.Scope != null) if (this.type_special_kind == SemanticTree.type_special_kind.array_kind && this.base_type.Scope != null)
{ {
SymbolInfo tmp_si = this.base_type.Scope.SymbolTable.Find(this.base_type.Scope, name); SymbolInfo tmp_si = this.base_type.Scope.SymbolTable.Find(this.base_type.Scope, name);
if (tmp_si != null) if (tmp_si != null)
{ {
tmp_si.Next = si; if (si == null)
si = tmp_si; si = tmp_si;
else if (si.sym_info != tmp_si.sym_info)
{
tmp_si.Next = si;
si = tmp_si;
}
clone = true;
}
}
if (this.compiled_type.IsGenericType && !this.compiled_type.IsGenericTypeDefinition)
{
compiled_type_node ctn = compiled_type_node.get_type_node(this.compiled_type.GetGenericTypeDefinition());
if (ctn.scope != null)
{
SymbolInfo tmp_si = ctn.scope.SymbolTable.Find(ctn.scope, name);
if (tmp_si != null && tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method)
{
if (si == null)
si = tmp_si;
else if (si.sym_info != tmp_si.sym_info)
si = AddToSymbolInfo(si, tmp_si);
clone = true;
}
}
}
compiled_type_node bas_type = base_type as compiled_type_node;
while (bas_type != null && bas_type.scope != null)
{
SymbolInfo tmp_si = bas_type.scope.SymbolTable.Find(bas_type.scope, name);
if (tmp_si != null && tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method)
{
if (si == null)
si = tmp_si;
else
{
if (si.sym_info != tmp_si.sym_info)
si = AddToSymbolInfo(si, tmp_si);
}
clone = true;
}
bas_type = bas_type.base_type as compiled_type_node;
}
for (int i = 0; i < ImplementingInterfaces.Count; i++)
{
compiled_type_node ctn = ImplementingInterfaces[i] as compiled_type_node;
if (ctn.is_generic_type_instance)
ctn = ctn.original_generic as compiled_type_node;
if (ctn != null && ctn.scope != null)
{
SymbolInfo tmp_si = ctn.scope.SymbolTable.Find(ctn.scope, name);
if (tmp_si != null && tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method)
{
if (si == null)
si = tmp_si;
else
{
if (si.sym_info != tmp_si.sym_info)
si = AddToSymbolInfo(si, tmp_si);
}
clone = true;
}
} }
} }
if (si != null) if (si != null)
@ -3193,33 +3264,12 @@ namespace PascalABCCompiler.TreeRealization
} }
else if (si3 != null) else if (si3 != null)
si = si3; si = si3;
if (si == null && si2 == null && string.Compare(name, "Create", true) != 0)
{
compiled_type_node bas_type = base_type as compiled_type_node;
while (si == null && bas_type != null && bas_type.scope != null)
{
si = bas_type.scope.SymbolTable.Find(bas_type.scope, name);
bas_type = bas_type.base_type as compiled_type_node;
}
if (si == null)
{
for (int i = 0; i < ImplementingInterfaces.Count; i++)
{
compiled_type_node ctn = ImplementingInterfaces[i] as compiled_type_node;
if (ctn.is_generic_type_instance)
ctn = ctn.original_generic as compiled_type_node;
if (ctn != null && ctn.scope != null)
si = ctn.scope.SymbolTable.Find(ctn.scope, name);
if (si != null)
break;
}
}
}
if (si == null && si2 == null && this == SystemLibrary.SystemLibrary.string_type && SystemLibrary.SystemLibrary.syn_visitor.from_pabc_dll) if (si == null && si2 == null && this == SystemLibrary.SystemLibrary.string_type && SystemLibrary.SystemLibrary.syn_visitor.from_pabc_dll)
{ {
si = compiled_type_node.get_type_node(NetHelper.NetHelper.PABCSystemType).find_in_type(name); si = compiled_type_node.get_type_node(NetHelper.NetHelper.PABCSystemType).find_in_type(name);
} }
return AddToSymbolInfo(si, si2); return AddToSymbolInfo(si, si2, clone);
} }
} }