diff --git a/Compiler/Compiler.cs b/Compiler/Compiler.cs index 1b20a0c1e..a0ee62c23 100644 --- a/Compiler/Compiler.cs +++ b/Compiler/Compiler.cs @@ -218,6 +218,15 @@ namespace PascalABCCompiler } } + public class AppTypeDllIsAllowedOnlyForLibraries : CompilerCompilationError + { + public AppTypeDllIsAllowedOnlyForLibraries(string FileName, SyntaxTree.SourceContext sc) + : base(StringResources.Get("COMPILATIONERROR_APPTYPE_DLL_IS_ALLOWED_ONLY_FOR_LIBRARIES"), FileName) + { + this.source_context = sc; + } + } + public class UnitModuleExpectedLibraryFound : CompilerCompilationError { public UnitModuleExpectedLibraryFound(string FileName, SyntaxTree.SourceContext sc) @@ -3131,10 +3140,10 @@ namespace PascalABCCompiler public static bool is_dll(SyntaxTree.compilation_unit cu) { - foreach (SyntaxTree.compiler_directive cd in cu.compiler_directives) - if (string.Compare(cd.Name.text, "apptype",true)==0 && string.Compare(cd.Directive.text,"dll",true)==0) - return true; - return false; + foreach (SyntaxTree.compiler_directive cd in cu.compiler_directives) + if (string.Compare(cd.Name.text, "apptype", true) == 0 && string.Compare(cd.Directive.text, "dll", true) == 0) + return true; + return false; } public CompilationUnit CompileUnit(PascalABCCompiler.TreeRealization.unit_node_list Units, SyntaxTree.unit_or_namespace SyntaxUsesUnit) @@ -3259,7 +3268,22 @@ namespace PascalABCCompiler throw new NamespacesCanBeCompiledOnlyInProjects(CurrentUnit.SyntaxTree.source_context); compilerOptions.UseDllForSystemUnits = false; } - + + // SSM 21/05/20 Проверка, что мы не записали apptype dll в небиблиотеку + + var ccu = CurrentUnit.SyntaxTree; + foreach (SyntaxTree.compiler_directive cd in ccu.compiler_directives) + if (string.Compare(cd.Name.text, "apptype", true) == 0 && string.Compare(cd.Directive.text, "dll", true) == 0) + { + if (!(ccu is SyntaxTree.unit_module) || + (ccu is SyntaxTree.unit_module um && um.unit_name.HeaderKeyword != SyntaxTree.UnitHeaderKeyword.Library)) + { + ErrorsList.Add(new AppTypeDllIsAllowedOnlyForLibraries(ccu.file_name, cd.source_context)); + break; + } + } + // + if (is_dll(CurrentUnit.SyntaxTree)) compilerOptions.OutputFileType = PascalABCCompiler.CompilerOptions.OutputType.ClassLibrary; CurrentUnit.CaseSensitive = ParsersController.LastParser.CaseSensitive; diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 87f168c16..cab66cc6e 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "6"; public const string Build = "3"; - public const string Revision = "2471"; + public const string Revision = "2485"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index ab01459d8..04ab0649f 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=6 -%REVISION%=2471 +%REVISION%=2485 %COREVERSION%=3 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index e81858615..bd2601765 100644 Binary files a/Localization/DefaultLang.resources and b/Localization/DefaultLang.resources differ diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 11b0a421a..a3474b3eb 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.6.3.2471 +3.6.3.2485 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 21ab300ad..0227d5f61 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.6.3.2471' +!define VERSION '3.6.3.2485' diff --git a/TestSuite/AccessToFieldBaseInPropInGenClass.pas b/TestSuite/AccessToFieldBaseInPropInGenClass.pas new file mode 100644 index 000000000..44276a558 --- /dev/null +++ b/TestSuite/AccessToFieldBaseInPropInGenClass.pas @@ -0,0 +1,13 @@ +type + A = class + fielda: T; + end; + + B = class(A) + property PropA: T read fielda; + end; + +begin + var b1 := new B; + Assert(b1.PropA = 0); +end. \ No newline at end of file diff --git a/TestSuite/AccessToFieldBaseInPropInGenClass1.pas b/TestSuite/AccessToFieldBaseInPropInGenClass1.pas new file mode 100644 index 000000000..c2c0fd6c0 --- /dev/null +++ b/TestSuite/AccessToFieldBaseInPropInGenClass1.pas @@ -0,0 +1,13 @@ +type + A = class + fielda: integer := 1; + end; + + B = class(A) + property PropA: integer read fielda; + end; + +begin + var b1 := B&.Create; + Assert(b1.Propa = 1); +end. \ No newline at end of file diff --git a/TestSuite/AccessToFieldBaseInPropInGenClass2.pas b/TestSuite/AccessToFieldBaseInPropInGenClass2.pas new file mode 100644 index 000000000..e04fa06e2 --- /dev/null +++ b/TestSuite/AccessToFieldBaseInPropInGenClass2.pas @@ -0,0 +1,14 @@ +type + A = class + fielda: integer := 1; + end; + + B = class(A) + property PropA: integer write fielda read fielda; + end; + +begin + var b1 := B&.Create; + b1.Propa := 2; + Assert(b1.Propa = 2); +end. \ No newline at end of file diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 78fa6ebad..51839eb5d 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -10739,6 +10739,15 @@ begin yield (i, j) end; +/// Возвращает по заданному двумерному массиву последовательность индексов элементов, удовлетворяющих заданному условию +function Indices(Self: array [,] of T; cond: (T,integer,integer) -> boolean): sequence of (integer, integer); extensionmethod; +begin + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + if cond(Self[i,j],i,j) then + yield (i, j) +end; + /// Возвращает по заданному двумерному массиву последовательность его элементов по строкам function ElementsByRow(Self: array [,] of T): sequence of T; extensionmethod; begin diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index b1bf4ff7b..e9292ab48 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -4293,6 +4293,11 @@ namespace PascalABCCompiler.TreeConverter AddError(loc1, "NAME_IN_PROPERTY_READ_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); } + /*if (sil.FirstOrDefault().scope != context.CurrentScope) // SSM 22/05/20 + { + AddError(loc1, "NAME_IN_PROPERTY_READ_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); + }*/ + //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name, // si, loc1, general_node_type.function_node, general_node_type.variable_node); @@ -4427,6 +4432,11 @@ namespace PascalABCCompiler.TreeConverter AddError(loc2, "NAME_IN_PROPERTY_WRITE_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); } + /*if (sil.FirstOrDefault().scope != context.CurrentScope) // SSM 22/05/20 + { + AddError(loc2, "NAME_IN_PROPERTY_WRITE_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); + }*/ + //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name, // si, loc2, general_node_type.function_node, general_node_type.variable_node); @@ -4504,30 +4514,31 @@ namespace PascalABCCompiler.TreeConverter } write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc); } - else + else + { + class_field cfield = sil.FirstOrDefault().sym_info as class_field; + if (cfield == null) { - class_field cfield = sil.FirstOrDefault().sym_info as class_field; - if (cfield == null) - { - AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); - } - if (_simple_property.parameter_list != null) - { - AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); - } - if (cfield.type != pn.internal_property_type) - { - AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); - } - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); - if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); - write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2); + AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } - //Вот здесь уже можем добавить акцессор для чтения. - pn.internal_set_function = write_accessor; + + if (_simple_property.parameter_list != null) + { + AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); + } + if (cfield.type != pn.internal_property_type) + { + AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); + } + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); + if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); + write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2); } + //Вот здесь уже можем добавить акцессор для чтения. + pn.internal_set_function = write_accessor; + } if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name); if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) @@ -4641,7 +4652,7 @@ namespace PascalABCCompiler.TreeConverter } } common_method_node cmn = new common_method_node( - AcessorName, loc, cf.cont_type, + AcessorName, loc, /*cf.cont_type,*/ cpn.comprehensive_type as common_type_node, cf.polymorphic_state, context.get_field_access_level(), null); cpn.common_comprehensive_type.methods.AddElement(cmn); common_parameter cp = new common_parameter( @@ -4660,7 +4671,7 @@ namespace PascalABCCompiler.TreeConverter var_ref = new static_class_field_reference(cf, loc); } cmn.function_code = find_operator(compiler_string_consts.assign_name, var_ref, cpr, loc); - cf.cont_type.scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); + cf.cont_type.Scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); return cmn; } @@ -4687,7 +4698,7 @@ namespace PascalABCCompiler.TreeConverter } } common_method_node cmn = new common_method_node( - AcessorName, loc, cf.cont_type, + AcessorName, loc, /*cf.cont_type,*/ cpn.comprehensive_type as common_type_node, cf.polymorphic_state, context.get_field_access_level(), null); cpn.common_comprehensive_type.methods.AddElement(cmn); cmn.return_value_type = cf.type; @@ -4702,7 +4713,7 @@ namespace PascalABCCompiler.TreeConverter var_ref = new static_class_field_reference(cf, loc); } cmn.function_code = new return_node(var_ref, loc); - cf.cont_type.scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); + cf.cont_type.Scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); // scope -> Scope SSM 23/05/20 - return cmn; } diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index b546e3766..d94c17f1b 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -10741,6 +10741,15 @@ begin yield (i, j) end; +/// Возвращает по заданному двумерному массиву последовательность индексов элементов, удовлетворяющих заданному условию +function Indices(Self: array [,] of T; cond: (T,integer,integer) -> boolean): sequence of (integer, integer); extensionmethod; +begin + for var i := 0 to Self.RowCount - 1 do + for var j := 0 to Self.ColCount - 1 do + if cond(Self[i,j],i,j) then + yield (i, j) +end; + /// Возвращает по заданному двумерному массиву последовательность его элементов по строкам function ElementsByRow(Self: array [,] of T): sequence of T; extensionmethod; begin diff --git a/bin/Lng/Eng/CompilerErrors.dat b/bin/Lng/Eng/CompilerErrors.dat index fa1f8734a..ad5a5bbbc 100644 --- a/bin/Lng/Eng/CompilerErrors.dat +++ b/bin/Lng/Eng/CompilerErrors.dat @@ -17,6 +17,7 @@ DUPLICATE_DIRECTIVE{0}=Duplicate directive {0} FILE_{0}_NOT_FOUND=File '{0}' not found NAMESPACE_CAN_BE_COMPILED_ONLY_IN_PROJECTS=Files with namespaces can be compiled only inside projects NAMESPACE_CANNOT_HAVE_IN_SECTION=Namespace cannot have 'in' section +APPTYPE_DLL_IS_ALLOWED_ONLY_FOR_LIBRARIES= {$apptype dll} directive is allowed only for libraries %PREFIX%= COMPILER_INTERNAL_ERROR_IN_UNIT_{0}_:{1}=Internal compiler error in module {0} :'{1}' \ No newline at end of file diff --git a/bin/Lng/Rus/CompilerErrors.dat b/bin/Lng/Rus/CompilerErrors.dat index 7ccf1186c..b62ae7ed4 100644 --- a/bin/Lng/Rus/CompilerErrors.dat +++ b/bin/Lng/Rus/CompilerErrors.dat @@ -17,6 +17,7 @@ DUPLICATE_DIRECTIVE{0}=Повторное объявление директив NAMESPACE_CAN_BE_COMPILED_ONLY_IN_PROJECTS=Компиляция файлов с пространствами имен допустима только в проектах FILE_{0}_NOT_FOUND=Файл '{0}' не найден NAMESPACE_CANNOT_HAVE_IN_SECTION=Для пространства имен не может указываться секция in +APPTYPE_DLL_IS_ALLOWED_ONLY_FOR_LIBRARIES=Директива {$apptype dll} возможна только для библиотек %PREFIX%= COMPILER_INTERNAL_ERROR_IN_UNIT_{0}_:{1}=Внутренняя ошибка компилятора в модуле {0} :'{1}' \ No newline at end of file diff --git a/bin/Lng/Rus/SemanticErrors_nv.dat b/bin/Lng/Rus/SemanticErrors_nv.dat index 4cb5cc4f7..2aeaf5332 100644 --- a/bin/Lng/Rus/SemanticErrors_nv.dat +++ b/bin/Lng/Rus/SemanticErrors_nv.dat @@ -54,7 +54,7 @@ PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE=Несоответс PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE=Несоответствие типа свойства и возвращаемого значения метода {1} для чтения PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE=Метод для чтения свойства не может быть процедурой PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE=Несоответствие типа свойства {0} и типа последнего параметра метода для записи -PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION=Метод для чтения не может быть функцией +PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION=Метод для записи не может быть функцией PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT=Неправильное число параметров при обращении к свойству {0} NO_DEFAULT_PROPERTY_TO_TYPE_{0}=Нет индексного свойства по умолчанию для типа {0} DUPLICATE_DEFAULT_PROPERTY_IN_CLASS=Два индексных свойства по умолчанию в классе