diff --git a/Compiler/PCU/PCUWrappers.cs b/Compiler/PCU/PCUWrappers.cs index 93985d7e0..3db26bf2d 100644 --- a/Compiler/PCU/PCUWrappers.cs +++ b/Compiler/PCU/PCUWrappers.cs @@ -287,30 +287,18 @@ namespace PascalABCCompiler.PCU public int offset; public wrapped_common_type_node(PCUReader pr, type_node base_type, string name, SemanticTree.type_access_level type_access_level, - common_namespace_node comprehensive_namespace, SymbolTable.ClassScope cs, location loc,int offset): - base(base_type, name, type_access_level, comprehensive_namespace,cs,loc) + common_namespace_node comprehensive_namespace, SymbolTable.ClassScope cs, location loc, int offset) : + base(base_type, name, type_access_level, comprehensive_namespace, cs, loc) { this.pr = pr; this.offset = offset; } - /* public override SymbolInfo find(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { - SymbolInfo si = scope.Find(name); - if (si == null) return si; - if (si.sym_info.semantic_node_type == semantic_node_type.wrap_def) - { - wrapped_definition_node wdn = (wrapped_definition_node)si.sym_info; - si.sym_info = pr.CreateInterfaceInClassMember(wdn.offset, name); - } - return si; - }*/ - - public override SymbolInfo find_in_type(string name) - { - return find_in_type(name,null); + return find_in_type(name, null, no_search_in_extension_methods); } - public override SymbolInfo find_in_type(string name, Scope CurrentScope) + public override SymbolInfo find_in_type(string name, Scope CurrentScope, bool no_search_in_extension_methods = false) { SymbolInfo si = scope.FindOnlyInType(name, CurrentScope); if (si == null) return si; @@ -325,7 +313,7 @@ namespace PascalABCCompiler.PCU } tsi = tsi.Next; } - return si; + return si; } } diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index e9e923c7f..0d29e9543 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -2154,7 +2154,10 @@ namespace PascalABCCompiler.NETGenerator Type[] tpars = new Type[tcount]; for (int i = 0; i < tcount; i++) { - tpars[i] = helper.GetTypeReference(igfi.generic_parameters[i]).tp; + TypeInfo ti = helper.GetTypeReference(igfi.generic_parameters[i]); + if (ti == null) + return; + tpars[i] = ti.tp; } MethodInfo rez = mi.MakeGenericMethod(tpars); helper.AddMethod(igfi, rez); diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 18fed8799..458560836 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -3198,23 +3198,35 @@ end; // Операции для HashSet //------------------------------------------------------------------------------ ///-- -function HashSet.operator in(x: T; Self: HashSet): boolean; +function operator in(x: T; Self: HashSet): boolean; extensionmethod; begin Result := Self.Contains(x); end; -function HashSet.operator+=(var Self: HashSet; x: T): HashSet; +function operator+=(var Self: HashSet; x: T): HashSet; extensionmethod; begin Self.Add(x); Result := Self; end; -function HashSet.operator-=(var Self: HashSet; x: T): HashSet; +function operator+=(var Self: HashSet; x: sequence of T): HashSet; extensionmethod; +begin + Self.UnionWith(x); + Result := Self; +end; + +function operator-=(var Self: HashSet; x: T): HashSet; extensionmethod; begin Self.Remove(x); Result := Self; end; +function operator-=(var Self: HashSet; x: sequence of T): HashSet; extensionmethod; +begin + Self.ExceptWith(x); + Result := Self; +end; + function operator=(x,y: HashSet): boolean; extensionmethod; begin Result := x.SetEquals(y) @@ -3269,23 +3281,86 @@ end; //------------------------------------------------------------------------------ // Операции для SortedSet //------------------------------------------------------------------------------ -function SortedSet.operator in(x: T; Self: SortedSet): boolean; +function operator in(x: T; Self: SortedSet): boolean; extensionmethod; begin Result := Self.Contains(x); end; -function SortedSet.operator+=(var Self: SortedSet; x: T): SortedSet; +function operator+=(var Self: SortedSet; x: T): SortedSet; extensionmethod; begin Self.Add(x); Result := Self; end; -function SortedSet.operator-=(var Self: SortedSet; x: T): SortedSet; +function operator+=(var Self: SortedSet; x: sequence of T): SortedSet; extensionmethod; +begin + Self.UnionWith(x); + Result := Self; +end; + +function operator-=(var Self: SortedSet; x: T): SortedSet; extensionmethod; begin Self.Remove(x); Result := Self; end; +function operator-=(var Self: SortedSet; x: sequence of T): SortedSet; extensionmethod; +begin + Self.ExceptWith(x); + Result := Self; +end; + +function operator=(x,y: SortedSet): boolean; extensionmethod; +begin + Result := x.SetEquals(y) +end; + +function operator<>(x,y: SortedSet): boolean; extensionmethod; +begin + Result := not x.SetEquals(y) +end; + +function operator-(x,y: SortedSet): SortedSet; extensionmethod; +begin + var v := new SortedSet(x); + v.ExceptWith(y); + Result := v; +end; + +function operator+(x,y: SortedSet): SortedSet; extensionmethod; +begin + var v := new SortedSet(x); + v.UnionWith(y); + Result := v; +end; + +function operator*(x,y: SortedSet): SortedSet; extensionmethod; +begin + var v := new SortedSet(x); + v.IntersectWith(y); + Result := v; +end; + +function operator< (x,y: SortedSet): boolean; extensionmethod; +begin + Result := x.IsProperSubsetOf(y); +end; + +function operator<= (x,y: SortedSet): boolean; extensionmethod; +begin + Result := x.IsSubsetOf(y); +end; + +function operator> (x,y: SortedSet): boolean; extensionmethod; +begin + Result := x.IsProperSupersetOf(y); +end; + +function operator>= (x,y: SortedSet): boolean; extensionmethod; +begin + Result := x.IsSupersetOf(y); +end; + //------------------------------------------------------------------------------ // Операции для Dictionary, SortedDictionary, SortedList //------------------------------------------------------------------------------ diff --git a/TestSuite/overloads5.pas b/TestSuite/overloads5.pas new file mode 100644 index 000000000..aaf922c27 --- /dev/null +++ b/TestSuite/overloads5.pas @@ -0,0 +1,11 @@ +function f(source: sequence of T): T; +begin + var sourceIterator := source.GetEnumerator(); + sourceIterator.MoveNext(); + var min: T := sourceIterator.Current; + Result := min; +end; + +begin +assert(f(Arr(2,3,4)) = 2); +end. \ No newline at end of file diff --git a/TreeConverter/NetWrappers/NetHelper.cs b/TreeConverter/NetWrappers/NetHelper.cs index 1c2b23911..6a1f3c2b2 100644 --- a/TreeConverter/NetWrappers/NetHelper.cs +++ b/TreeConverter/NetWrappers/NetHelper.cs @@ -1472,9 +1472,10 @@ namespace PascalABCCompiler.NetHelper //сущности будут одной природы (например, все - методы). Это неверно, //так как в случае наличия функции Ident и поля ident оба должны попасть //в список. - - //TODO: проанализировать и изменить алгоритмы, использующие поиск. + //TODO: проанализировать и изменить алгоритмы, использующие поиск. + List si_list = new List(); + SymbolInfo root_si = null; foreach (MemberInfo mi in mis) { if (mi.DeclaringType != null && PABCSystemType != null && mi.DeclaringType.Assembly == PABCSystemType.Assembly && !UsePABCRtl) @@ -1502,10 +1503,22 @@ namespace PascalABCCompiler.NetHelper default: continue; } - temp.Next = si; - si = temp; + if (root_si == null) + { + root_si = temp; + si = temp; + } + else + { + si.Next = temp; + si = temp; + } + + //temp.Next = si; + //si = temp; } } + si = root_si; Type nested_t = null; foreach (Type nt in t.GetNestedTypes()) { diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index 1125fb3a8..1a765d300 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -843,11 +843,11 @@ namespace PascalABCCompiler.TreeConverter /// Для единственного метода у которого типы параметров совпадают, но в качестве var параметра мы передаем константное значение мы можем сгенерировать более подробное сообщение об ошибке. /// Список преобразований типов. internal possible_type_convertions_list get_conversions(expressions_list factparams, - parameter_list formalparams,bool is_alone_method_defined, location locg) + parameter_list formalparams,bool is_alone_method_defined, location locg, out Errors.Error error) { //TODO:Явно указывать capacity при создании. possible_type_convertions_list tc = new possible_type_convertions_list(); - + error = null; possible_type_convertions ptc; if (factparams.Count>formalparams.Count) @@ -1097,7 +1097,8 @@ namespace PascalABCCompiler.TreeConverter { if (is_alone_method_defined) { - AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg)); + error = new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg); + //AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg)); } return null; @@ -1650,7 +1651,7 @@ namespace PascalABCCompiler.TreeConverter { return f; } - if (function_eq_params(fn,f)) + if (function_eq_params(fn, f)) { if (fn.original_function == f.original_function) { @@ -1661,9 +1662,9 @@ namespace PascalABCCompiler.TreeConverter return null; } - public function_node is_exist_eq_method_in_list(function_node fn,function_node_list funcs) + public function_node is_exist_eq_method_in_list(function_node fn, function_node_list funcs) { - return find_eq_method_in_list(fn,funcs); + return find_eq_return_value_method_in_list(fn, funcs); } public void init_reference_type(type_node ctn) @@ -1842,8 +1843,11 @@ namespace PascalABCCompiler.TreeConverter for (int i = 0; i < set_of_possible_functions.Count; i++) { + Errors.Error err = null; possible_type_convertions_list tc = get_conversions(parameters, set_of_possible_functions[i].parameters, - is_alone_method_defined, loc); + is_alone_method_defined, loc, out err); + if (err != null) + return AddError(err); //fix dlja lambd i extension metodov (c->c.IsDigit) if (tc == null) { @@ -1859,8 +1863,14 @@ namespace PascalABCCompiler.TreeConverter } } if (has_lambda_var) + { + err = null; tc = get_conversions(el, set_of_possible_functions[i].parameters, - is_alone_method_defined, loc); + is_alone_method_defined, loc, out err); + if (err != null) + return AddError(err); + } + } tcll.AddElement(tc); } @@ -1975,6 +1985,34 @@ namespace PascalABCCompiler.TreeConverter } SortedDictionary> distances = new SortedDictionary>(); + function_node best_function = null; + List to_remove = new List(); + foreach (function_node fn in set_of_possible_functions) + { + if (fn.return_value_type != null) + { + if (best_function == null) + { + best_function = fn; + } + else + { + type_compare tc = type_table.compare_types(best_function.return_value_type, fn.return_value_type); + if (tc == type_compare.greater_type) + { + to_remove.Add(best_function); + best_function = fn; + } + else if (tc == type_compare.less_type) + to_remove.Add(fn); + } + } + } + foreach (function_node fn in to_remove) + { + set_of_possible_functions.remove(fn); + } + foreach (function_node fn in set_of_possible_functions) { int distance = 0; @@ -1986,6 +2024,16 @@ namespace PascalABCCompiler.TreeConverter to = to.element_type; distance += get_type_distance(from, to); } + + /*if (fn.return_value_type != null) + { + if (fn.return_value_type.is_generic_type_instance || fn.return_value_type.is_generic_type_definition) + distance += 2; + else if (fn.return_value_type == SystemLibrary.SystemLibrary.object_type) + distance += 3; + else + distance += 1; + }*/ List lst; if (distances.TryGetValue(distance,out lst)) { @@ -2003,7 +2051,10 @@ namespace PascalABCCompiler.TreeConverter List funcs = distances[dist]; if (funcs.Count == 1) { - possible_type_convertions_list tcl = get_conversions(parameters, funcs[0].parameters, true, loc); + Errors.Error err = null; + possible_type_convertions_list tcl = get_conversions(parameters, funcs[0].parameters, true, loc, out err); + if (err != null) + return AddError(err); convert_function_call_expressions(funcs[0], parameters, tcl); return funcs[0]; } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index b68bd9edb..d70a41e96 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -176,7 +176,7 @@ namespace PascalABCCompiler.TreeConverter motivation_keeper.reset(); SystemLibrary.SystemLibInitializer.NeedsToRestore.Clear(); type_section_converting = false; - + ThrowCompilationError = true; #region MikhailoMMX, реинициализация класса OpenMP OpenMP.InternalReset(); CurrentParallelPosition = ParallelPosition.Outside; @@ -1031,7 +1031,7 @@ namespace PascalABCCompiler.TreeConverter return false; } - public expression_node find_operator(string name, expression_node left, expression_node right, location loc) + public expression_node find_operator(string name, expression_node left, expression_node right, location loc, bool no_search_in_extension_methods = true) { #if (DEBUG) if (name == null) @@ -1039,7 +1039,6 @@ namespace PascalABCCompiler.TreeConverter throw new CompilerInternalError("Invalid operator name"); } #endif - if (right.semantic_node_type == semantic_node_type.null_const_node) { if ( !type_table.is_with_nil_allowed(left.type) && !left.type.IsPointer) @@ -1078,7 +1077,7 @@ namespace PascalABCCompiler.TreeConverter //TODO: Посмотреть. //TODO: Не find а find_in_type. //SymbolInfo si=left_type.find(name, context.CurrentScope); - SymbolInfo si = left_type.find_in_type(name, left_type.Scope); + SymbolInfo si = left_type.find_in_type(name, left_type.Scope, no_search_in_extension_methods); SymbolInfo added_symbols = null; SymbolInfo si2 = null; if (left_type != right_type && !one_way_operation(name)) @@ -1086,7 +1085,7 @@ namespace PascalABCCompiler.TreeConverter //SymbolInfo si2 = right_type.find(name, context.CurrentScope); if (si != null) si = si.copy(); - si2 = right_type.find_in_type(name, right_type.Scope); + si2 = right_type.find_in_type(name, right_type.Scope, no_search_in_extension_methods); if ((si != null) && (si2 != null)) { //Важная проверка. Возможно один и тот же оператор с одними и теми же типами определен в двух разных классах. @@ -1204,10 +1203,22 @@ namespace PascalABCCompiler.TreeConverter else saved_si2 = si2; if (saved_si == null) - AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + { + if (!no_search_in_extension_methods) + AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + else + return find_operator(name, left, right, loc, false); + } + } else if (si == null) - AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + { + if (!no_search_in_extension_methods) + AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + else + return find_operator(name, left, right, loc, false); + } + } expressions_list pars = null; @@ -1222,8 +1233,18 @@ namespace PascalABCCompiler.TreeConverter pars = new expressions_list(); pars.AddElement(left); pars.AddElement(right); + bool tmp_throw_error = ThrowCompilationError; + ThrowCompilationError = !no_search_in_extension_methods; fnsel = convertion_data_and_alghoritms.select_function(pars, si, loc); + if (!ThrowCompilationError && fnsel == null) + { + RemoveLastError(); + ThrowCompilationError = tmp_throw_error; + return find_operator(name, left, right, loc, false); + } + else + ThrowCompilationError = tmp_throw_error; //function_node fnsel=convertion_data_and_alghoritms.select_function(pars,si,loc); CheckSpecialFunctionCall(si, pars,loc); //TODO: А это зачем? Можно передать в create_simple_function_call pars. diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 869909526..1e1ab0193 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -1721,21 +1721,21 @@ namespace PascalABCCompiler.TreeRealization return rez_start; } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { SymbolInfo si = _original_generic.find(name); si = ConvertSymbolInfo(si); return si; } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { SymbolInfo si = _original_generic.find_in_type(name); si = ConvertSymbolInfo(si); return si; } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { SymbolInfo si = _original_generic.find_in_type(name, CurrentScope); si = ConvertSymbolInfo(si); diff --git a/TreeConverter/TreeRealization/templates.cs b/TreeConverter/TreeRealization/templates.cs index e1cd34951..a15e5c2ef 100644 --- a/TreeConverter/TreeRealization/templates.cs +++ b/TreeConverter/TreeRealization/templates.cs @@ -479,13 +479,13 @@ namespace PascalABCCompiler.TreeRealization // return rez; //} - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { indefinite_definition_node idn = new indefinite_definition_node(name, this); return new SymbolInfo(idn, access_level.al_public, symbol_kind.sk_indefinite); } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return find_in_type(name); } diff --git a/TreeConverter/TreeRealization/types.cs b/TreeConverter/TreeRealization/types.cs index 454ba8871..dc3aa4729 100644 --- a/TreeConverter/TreeRealization/types.cs +++ b/TreeConverter/TreeRealization/types.cs @@ -426,13 +426,13 @@ namespace PascalABCCompiler.TreeRealization return null; } - public abstract SymbolInfo find(string name); - public virtual SymbolInfo find(string name, SymbolTable.Scope CurrentScope) + public abstract SymbolInfo find(string name, bool no_search_in_extension_methods = false); + public virtual SymbolInfo find(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return find(name); } - public abstract SymbolInfo find_in_type(string name); - public virtual SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public abstract SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false); + public virtual SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return find_in_type(name); } @@ -585,7 +585,7 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return null; } @@ -595,12 +595,12 @@ namespace PascalABCCompiler.TreeRealization } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { return null; } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return null; } @@ -748,12 +748,12 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return null; } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { return null; } @@ -904,17 +904,17 @@ namespace PascalABCCompiler.TreeRealization get { return name; } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return find_in_additional_names(name); } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { return find_in_additional_names(name); } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return find_in_additional_names(name); } @@ -1873,22 +1873,22 @@ namespace PascalABCCompiler.TreeRealization this._name = name; } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return Scope.Find(name,null);//int,:= } - public override SymbolInfo find(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return Scope.Find(name, CurrentScope);//int,:= } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { return Scope.FindOnlyInType(name, null);//:=,create,x } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { SymbolInfo si = Scope.FindOnlyInType(name, CurrentScope);//:=,create,x if (si == null && base_type is compiled_type_node && string.Compare(name,"create",true) != 0) @@ -2320,7 +2320,7 @@ namespace PascalABCCompiler.TreeRealization this.type_special_kind = SemanticTree.type_special_kind.short_string; } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { //return this.find_in_additional_names(name); return _scope.Find(name); @@ -2409,7 +2409,7 @@ namespace PascalABCCompiler.TreeRealization _scope.AddSymbol(name, si); } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { //return this.find_in_additional_names(name) //SymbolInfo si = _scope.FindOnlyInType(name, null); @@ -2418,7 +2418,7 @@ namespace PascalABCCompiler.TreeRealization return SystemLibrary.SystemLibrary.string_type.find_in_type(name); } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { //return this.find_in_additional_names(name); //SymbolInfo si = _scope.FindOnlyInType(name, CurrentScope); @@ -3165,7 +3165,7 @@ namespace PascalABCCompiler.TreeRealization //(ssyy) 24.10.2007. Эта функция работает неверно, возвращая дважды найденную функцию. //Попытался написать правильно. - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { /*//Старый код SymbolInfo si = AddToSymbolInfo(compiled_find(name), find_in_additional_names(name)); @@ -3179,8 +3179,6 @@ namespace PascalABCCompiler.TreeRealization { SymbolInfo si = compiled_find(name); SymbolInfo si2 = find_in_additional_names(name); - /*if (name == "Clear") //статическая функция для массива при наличии такого кода не конкурирует с одноименным методом расширения для массивов. Как определить тут, что она статическая??? - si = null;*/ if (si == null && si2 == null && string.Compare(name,"Create",true) != 0) { compiled_type_node bas_type = base_type as compiled_type_node; @@ -3212,63 +3210,45 @@ namespace PascalABCCompiler.TreeRealization SymbolInfo si2 = find_in_additional_names(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 (!no_search_in_extension_methods) { - SymbolInfo tmp_si = this.base_type.Scope.SymbolTable.Find(this.base_type.Scope, name); - if (tmp_si != null) + + if (this.type_special_kind == SemanticTree.type_special_kind.array_kind && this.base_type.Scope != null) { - if (si == null) - si = tmp_si; - else if (si.sym_info != tmp_si.sym_info) - si = AddToSymbolInfo(tmp_si, si, true); - 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) + SymbolInfo tmp_si = this.base_type.Scope.SymbolTable.Find(this.base_type.Scope, name); + if (tmp_si != null) { if (si == null) si = tmp_si; else if (si.sym_info != tmp_si.sym_info) - si = AddToSymbolInfo(si, tmp_si, true); + si = AddToSymbolInfo(tmp_si, si, true); clone = true; } } - } - compiled_type_node bas_type = base_type as compiled_type_node; - if (bas_type == null) - { - bas_type = compiled_type_node.get_type_node(typeof(object)); - } - 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 (this.compiled_type.IsGenericType && !this.compiled_type.IsGenericTypeDefinition) { - if (si == null) - si = tmp_si; - else + compiled_type_node ctn = compiled_type_node.get_type_node(this.compiled_type.GetGenericTypeDefinition()); + if (ctn.scope != null) { - if (si.sym_info != tmp_si.sym_info) - si = AddToSymbolInfo(si, tmp_si, true); + 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, true); + clone = true; + } } - 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) + compiled_type_node bas_type = base_type as compiled_type_node; + if (bas_type == null) { - SymbolInfo tmp_si = ctn.scope.SymbolTable.Find(ctn.scope, name); + bas_type = compiled_type_node.get_type_node(typeof(object)); + } + 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) @@ -3280,6 +3260,28 @@ namespace PascalABCCompiler.TreeRealization } 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, true); + } + clone = true; + } + } } } if (si != null) @@ -3300,15 +3302,15 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { - return find(name); + return find(name, no_search_in_extension_methods); } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { //return find(name); - SymbolInfo result = find(name); + SymbolInfo result = find(name, no_search_in_extension_methods); //Поищем также среди extentions-методов. if (is_generic_type_instance) { @@ -3664,7 +3666,7 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { //return this.find_in_additional_names(name); return _scope.Find(name); @@ -3727,13 +3729,13 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { //return this.find_in_additional_names(name); return _scope.FindOnlyInType(name, null); } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { //return this.find_in_additional_names(name); return _scope.FindOnlyInType(name, CurrentScope); @@ -3971,7 +3973,7 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return null; } @@ -3981,12 +3983,12 @@ namespace PascalABCCompiler.TreeRealization _scope.AddSymbol(name, si); } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { return _scope.FindOnlyInScope(name); } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return _scope.FindOnlyInScope(name); } @@ -4411,12 +4413,12 @@ namespace PascalABCCompiler.TreeRealization } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return find_in_type(name); } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { if (name != compiler_string_consts.plusassign_name && name != compiler_string_consts.minusassign_name) foreach (base_function_call fn in _proper_methods) @@ -4432,7 +4434,7 @@ namespace PascalABCCompiler.TreeRealization return compiled_type_node.get_type_node(typeof(Delegate)).find(name); //return null; } - public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope) + public override SymbolInfo find_in_type(string name, SymbolTable.Scope CurrentScope, bool no_search_in_extension_methods = false) { return find_in_type(name); } @@ -4707,12 +4709,12 @@ namespace PascalABCCompiler.TreeRealization get { return SemanticTree.node_kind.basic; } } - public override SymbolInfo find(string name) + public override SymbolInfo find(string name, bool no_search_in_extension_methods = false) { return null; } - public override SymbolInfo find_in_type(string name) + public override SymbolInfo find_in_type(string name, bool no_search_in_extension_methods = false) { return null; }