diff --git a/Compiler/PCU/PCUFileFormatVersion.cs b/Compiler/PCU/PCUFileFormatVersion.cs index 21b3e08fa..cc42464f0 100644 --- a/Compiler/PCU/PCUFileFormatVersion.cs +++ b/Compiler/PCU/PCUFileFormatVersion.cs @@ -6,6 +6,6 @@ namespace PascalABCCompiler.PCU { public static class PCUFileFormatVersion { - public static System.Int16 Version = 110; + public static System.Int16 Version = 112; } } diff --git a/Compiler/PCU/PCUReader.cs b/Compiler/PCU/PCUReader.cs index b52e5d2e1..02d75ba18 100644 --- a/Compiler/PCU/PCUReader.cs +++ b/Compiler/PCU/PCUReader.cs @@ -652,6 +652,16 @@ namespace PascalABCCompiler.PCU return sn; } + public statement_node GetCodeWithOverridedMethod(common_method_node meth, int offset) + { + int tmp = (int)br.BaseStream.Position; + br.BaseStream.Seek(start_pos+offset,SeekOrigin.Begin); + statement_node sn = CreateStatement(); + meth.overrided_method = GetMethodReference(); + br.BaseStream.Seek(tmp,SeekOrigin.Begin); + return sn; + } + //перейти на указанную позицию в списке импорт. сущ-тей private void SeekInExternal(int pos) { @@ -1739,7 +1749,8 @@ namespace PascalABCCompiler.PCU cmn.cont_type.static_constr = cmn; cmn.num_of_default_variables = br.ReadInt32(); cmn.num_of_for_cycles = br.ReadInt32(); - br.ReadBoolean(); + bool has_overrided_method = br.ReadBoolean(); + int num_var = br.ReadInt32(); GetVariables(cmn, num_var); int num_consts = br.ReadInt32(); @@ -1753,7 +1764,10 @@ namespace PascalABCCompiler.PCU cmn.functions_nodes_list.AddElement(GetNestedFunction()); //br.ReadInt32();//code; cmn.loc = ReadDebugInfo(); - cmn.function_code = GetCode(br.ReadInt32()); + if (has_overrided_method) + cmn.function_code = GetCodeWithOverridedMethod(cmn, br.ReadInt32()); + else + cmn.function_code = GetCode(br.ReadInt32()); cmn.cont_type.methods.AddElement(cmn); if (cmn.name == "op_Equality") cmn.cont_type.scope.AddSymbol(compiler_string_consts.eq_name, new SymbolInfo(cmn)); diff --git a/Compiler/PCU/PCUWriter.cs b/Compiler/PCU/PCUWriter.cs index 7e2a86c74..4fb5d3ac5 100644 --- a/Compiler/PCU/PCUWriter.cs +++ b/Compiler/PCU/PCUWriter.cs @@ -2843,7 +2843,8 @@ namespace PascalABCCompiler.PCU bw.Write((byte)meth.polymorphic_state); bw.Write(meth.num_of_default_variables); bw.Write(meth.num_of_for_cycles); - bw.Write(meth.overrided_method != null); + bw.Write(meth.overrided_method != null && meth.name.IndexOf('.') != -1); + //ssyy- //if (meth.pascal_associated_constructor != null) //{ @@ -3057,6 +3058,8 @@ namespace PascalABCCompiler.PCU { VisitStatement(meth.function_code); } + if (meth.overrided_method != null && meth.name.IndexOf('.') != -1) + WriteMethodReference(meth.overrided_method); //} } diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 7fd1ad5fd..8297839f4 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -6122,6 +6122,15 @@ namespace PascalABCCompiler.NETGenerator cur_meth = tmp; il = tmp_il; num_scope--; + if (value.overrided_method != null && value.name.IndexOf('.') != -1) + { + MethodInfo mi = null; + if (helper.GetMethod(value.overrided_method) != null) + mi = helper.GetMethod(value.overrided_method).mi; + else + mi = (value.overrided_method as ICompiledMethodNode).method_info; + cur_type.DefineMethodOverride(methb, mi); + } } private MethInfo ConvertMethodWithNested(SemanticTree.ICommonMethodNode meth, ConstructorBuilder methodb) diff --git a/TestSuite/explicitinterface.pas b/TestSuite/explicitinterface.pas index fe7f3c607..0c5a47336 100644 --- a/TestSuite/explicitinterface.pas +++ b/TestSuite/explicitinterface.pas @@ -1,6 +1,9 @@ -type +type IEnr = System.Collections.IEnumerator; IEnb = System.Collections.IEnumerable; + TRec = record + a: integer; + end; var a : integer; type My = class(IEnumerable) @@ -15,7 +18,18 @@ type end; end; - + My2 = class(IEnumerable) + public + function IEnb.GetEnumerator(): IEnr; + begin + a := 1; + end; + function GetEnumerator(): IEnumerator; + begin + a := 2; + end; + + end; begin var ien: IEnb := new My; ien.GetEnumerator; @@ -27,4 +41,8 @@ a := 0; var mc := new My; mc.GetEnumerator(); assert(a=2); +var ien3: IEnumerable := new My2; +a := 0; +ien3.GetEnumerator(); +assert(a=2); end. \ No newline at end of file diff --git a/TestSuite/explicitinterface3.pas b/TestSuite/explicitinterface3.pas new file mode 100644 index 000000000..b95f35e95 --- /dev/null +++ b/TestSuite/explicitinterface3.pas @@ -0,0 +1,34 @@ +var s: string; + +type + IWindow = interface + procedure Menu; + end; + IRestaurant = interface + procedure Menu; + end; + RestaurantSystem = class(IWindow,IRestaurant) + public + procedure Menu; virtual; + begin + s := 'RestaurantSystem.Menu'; + end; + procedure IWindow.Menu; + begin + s := 'IWindow.Menu'; + end; + procedure IRestaurant.Menu; + begin + s := 'IRestaurant.Menu'; + end; + end; + +begin + var r := new RestaurantSystem; + r.Menu; + assert(s = 'RestaurantSystem.Menu'); + IWindow(r).Menu; + assert(s = 'IWindow.Menu'); + IRestaurant(r).Menu; + assert(s = 'IRestaurant.Menu'); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index 1cc3d63de..a87620893 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -2723,7 +2723,8 @@ namespace PascalABCCompiler.TreeConverter } else { - fn_common.SetName(meth.name); + if (fn_common.name.IndexOf('.') == -1) + fn_common.SetName(meth.name); fn_common.name_case_fixed = true; } @@ -2790,6 +2791,8 @@ namespace PascalABCCompiler.TreeConverter //Делаем её virtual final commn.is_final = true; commn.newslot_awaited = true; + if (commn.name.IndexOf('.') != -1) + commn.overrided_method = meth; } } else