Перемещение модулей SPython в Lib\SPython (#3371)

* Replace languageCaseSensitive by languageName data in PCU and caseSensitive parameters in Compiler functions

* Implement SearchDirectories filling in Compiler and move SPython standard modules to their new directory

* Implement search using current language extension first in Compiler

* Delete LibForVB folder and update TestRunner to support different Lib dirs

* Update installer scripts to create separate Lib folder for SPython

* Take into account Lib dirs not found

* Delete supportedSourceFiles variable in Compiler

* Delete unused functions from LanguageIntegrator
This commit is contained in:
Александр Земляк 2026-01-13 08:20:13 +03:00 committed by GitHub
parent d7a81d312c
commit 51e4ae050a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 224 additions and 9949 deletions

View file

@ -9,6 +9,7 @@ using PascalABCCompiler.Parsers;
using PascalABCCompiler.Errors; using PascalABCCompiler.Errors;
using System.IO; using System.IO;
using Languages.Facade; using Languages.Facade;
using System.Linq;
namespace CodeCompletion namespace CodeCompletion
{ {
@ -280,17 +281,28 @@ namespace CodeCompletion
} }
const string LibSourceDirectoryIdent = "%LIBSOURCEDIRECTORY%"; const string LibSourceDirectoryIdent = "%LIBSOURCEDIRECTORY%";
public static string FindSourceFileName(string unit_name, out int found_dir_ind, bool caseSensitiveSearch, params string[] ddirs) public static string FindSourceFileName(string unit_name, out int found_dir_ind, ILanguage currentUnitLanguage, params string[] ddirs)
{ {
// TODO: check error in older version // TODO: check error in older version
List<string> Dirs = new List<string>(); List<string> Dirs = new List<string>();
Dirs.AddRange(ddirs); Dirs.AddRange(ddirs);
if (CodeCompletionController.comp != null) if (CodeCompletionController.comp != null)
Dirs.AddRange(CodeCompletionController.comp.CompilerOptions.SearchDirectories); Dirs.AddRange(CodeCompletionController.comp.GetCurrentSearchDirectories(currentUnitLanguage));
// Надо как-то проверять, что мы не в инсталированной версии EVA // Надо как-то проверять, что мы не в инсталированной версии EVA
if (CodeCompletionController.StandartDirectories.ContainsKey(LibSourceDirectoryIdent) && Directory.Exists(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent])) if (CodeCompletionController.StandartDirectories.ContainsKey(LibSourceDirectoryIdent) && Directory.Exists(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent]))
Dirs.Add(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent]); Dirs.AddRange(GetLibSourceDirectories(currentUnitLanguage));
return CodeCompletionController.comp.FindSourceFileNameInDirs(unit_name, out found_dir_ind, caseSensitiveSearch, Dirs.ToArray()); return CodeCompletionController.comp.FindSourceFileNameInDirs(unit_name, out found_dir_ind, currentUnitLanguage, Dirs.ToArray());
}
private static string[] GetLibSourceDirectories(ILanguage currentUnitLanguage)
{
return LanguageProvider.Instance.Languages
.Where(lang => lang == currentUnitLanguage)
.Concat(LanguageProvider.Instance.Languages.Where(lang => lang != currentUnitLanguage))
.Select(lang => Path.Combine(CodeCompletionController.StandartDirectories[LibSourceDirectoryIdent],
lang.Name.Replace(PascalABCCompiler.StringConstants.pascalLanguageName, ""))) // для PascalABC.NET прямо в LibSource, остальные во внутренних папках
.Where(dir => Directory.Exists(dir))
.ToArray();
} }
public static CodeCompletionNameHelper Helper public static CodeCompletionNameHelper Helper

View file

@ -79,6 +79,7 @@ namespace CodeCompletion
pcu_file.Version = br.ReadInt16(); pcu_file.Version = br.ReadInt16();
pcu_file.Revision = br.ReadInt32(); pcu_file.Revision = br.ReadInt32();
pcu_file.CRC = br.ReadInt64(); pcu_file.CRC = br.ReadInt64();
pcu_file.UseRtlDll = br.ReadBoolean();
pcu_file.IncludeDebugInfo = br.ReadBoolean(); pcu_file.IncludeDebugInfo = br.ReadBoolean();
return true; return true;
} }
@ -108,7 +109,10 @@ namespace CodeCompletion
pcu_file.SourceFileName = br.ReadString(); pcu_file.SourceFileName = br.ReadString();
else else
pcu_file.SourceFileName = Path.GetFileNameWithoutExtension(FileName); pcu_file.SourceFileName = Path.GetFileNameWithoutExtension(FileName);
int num_names = br.ReadInt32();
pcu_file.languageName = br.ReadString();
int num_names = br.ReadInt32();
pcu_file.names = new NameRef[num_names]; pcu_file.names = new NameRef[num_names];
for (int i=0; i<num_names; i++) for (int i=0; i<num_names; i++)
{ {
@ -116,6 +120,7 @@ namespace CodeCompletion
pcu_file.names[i].offset = br.ReadInt32(); pcu_file.names[i].offset = br.ReadInt32();
pcu_file.names[i].symbol_kind = (symbol_kind)br.ReadByte(); pcu_file.names[i].symbol_kind = (symbol_kind)br.ReadByte();
pcu_file.names[i].special_scope = br.ReadByte(); pcu_file.names[i].special_scope = br.ReadByte();
pcu_file.names[i].always_restore = br.ReadBoolean();
} }
//ssyy //ssyy
num_names = br.ReadInt32(); num_names = br.ReadInt32();
@ -126,6 +131,7 @@ namespace CodeCompletion
pcu_file.implementation_names[i].offset = br.ReadInt32(); pcu_file.implementation_names[i].offset = br.ReadInt32();
pcu_file.implementation_names[i].symbol_kind = (symbol_kind)br.ReadByte(); pcu_file.implementation_names[i].symbol_kind = (symbol_kind)br.ReadByte();
pcu_file.implementation_names[i].special_scope = br.ReadByte(); pcu_file.implementation_names[i].special_scope = br.ReadByte();
pcu_file.implementation_names[i].always_restore = br.ReadBoolean();
} }
//\ssyy //\ssyy
int num_incl = br.ReadInt32(); int num_incl = br.ReadInt32();

View file

@ -1,5 +1,6 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using Languages.Facade;
using PascalABCCompiler; using PascalABCCompiler;
using PascalABCCompiler.Parsers; using PascalABCCompiler.Parsers;
using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SyntaxTree;
@ -2698,14 +2699,14 @@ namespace CodeCompletion
{ {
unit_or_namespace s = _interface_node.uses_modules.units[j]; unit_or_namespace s = _interface_node.uses_modules.units[j];
CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_unit_module.file_name), CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_unit_module.file_name),
cur_scope, ns_cache, unl, currentUnitLanguage.CaseSensitive); cur_scope, ns_cache, unl, currentUnitLanguage);
} }
} }
// компиляция зависимостей из конструкций import и from import // компиляция зависимостей из конструкций import и from import
if (cur_scope != null && _unit_module.initialization_part != null) if (cur_scope != null && _unit_module.initialization_part != null)
{ {
CompileImportedDependencies(_unit_module.initialization_part, _unit_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage.CaseSensitive); CompileImportedDependencies(_unit_module.initialization_part, _unit_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage);
} }
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
@ -2716,7 +2717,7 @@ namespace CodeCompletion
// Добавление всех стандартных модулей EVA // Добавление всех стандартных модулей EVA
foreach (var standardUnitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer)) foreach (var standardUnitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer))
{ {
AddStandardUnit(standardUnitName, currentUnitLanguage.CaseSensitive, currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope); AddStandardUnit(standardUnitName, currentUnitLanguage);
} }
} }
@ -2853,14 +2854,14 @@ namespace CodeCompletion
PascalABCCompiler.TreeRealization.using_namespace_list unl = new PascalABCCompiler.TreeRealization.using_namespace_list(); PascalABCCompiler.TreeRealization.using_namespace_list unl = new PascalABCCompiler.TreeRealization.using_namespace_list();
public SymScope cur_scope; public SymScope cur_scope;
public static string FindPCUFileName(string UnitName, string curr_path, bool caseSensitiveSearch) public static string FindPCUFileName(string UnitName, string curr_path, Languages.Facade.ILanguage currentUnitLanguage)
{ {
return CodeCompletionController.comp.FindPCUFileName(UnitName, curr_path, out _, caseSensitiveSearch); return CodeCompletionController.comp.FindPCUFileName(UnitName, curr_path, out _, currentUnitLanguage);
} }
private void AddStandardUnit(string unitName, bool caseSensitiveSearch, bool addStandardUnitNameToCurrentScope) private void AddStandardUnit(string unitName, Languages.Facade.ILanguage currentUnitLanguage)
{ {
string unitPath = CodeCompletionNameHelper.FindSourceFileName(unitName, out _, caseSensitiveSearch); string unitPath = CodeCompletionNameHelper.FindSourceFileName(unitName, out _, currentUnitLanguage);
if (unitPath != null) if (unitPath != null)
{ {
DomConverter dc = CodeCompletionController.comp_modules[unitPath] as DomConverter; DomConverter dc = CodeCompletionController.comp_modules[unitPath] as DomConverter;
@ -2880,7 +2881,7 @@ namespace CodeCompletion
//get_standart_types(dc.stv); //get_standart_types(dc.stv);
// для SPython, например, не нужно подсказывать стандартные модули в программе, это условие для этого EVA // для SPython, например, не нужно подсказывать стандартные модули в программе, это условие для этого EVA
if (addStandardUnitNameToCurrentScope) if (currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope)
{ {
entry_scope.AddName(unitName, dc.visitor.entry_scope); entry_scope.AddName(unitName, dc.visitor.entry_scope);
} }
@ -2898,7 +2899,7 @@ namespace CodeCompletion
dc.visitor.entry_scope.InitAssemblies(); dc.visitor.entry_scope.InitAssemblies();
entry_scope.AddUsedUnit(dc.visitor.entry_scope); entry_scope.AddUsedUnit(dc.visitor.entry_scope);
//get_standart_types(dc.stv); //get_standart_types(dc.stv);
if (addStandardUnitNameToCurrentScope) if (currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope)
{ {
entry_scope.AddName(unitName, dc.visitor.entry_scope); entry_scope.AddName(unitName, dc.visitor.entry_scope);
} }
@ -2907,14 +2908,14 @@ namespace CodeCompletion
} }
private void CompileUsedUnitOrNamespace(unit_or_namespace s, string curr_path, private void CompileUsedUnitOrNamespace(unit_or_namespace s, string curr_path,
SymScope cur_scope, Hashtable ns_cache, using_namespace_list unl, bool caseSensitiveSearch) SymScope cur_scope, Hashtable ns_cache, using_namespace_list unl, Languages.Facade.ILanguage currentUnitLanguage)
{ {
try try
{ {
if (s is uses_unit_in uui) if (s is uses_unit_in uui)
{ {
string unit_name = CodeCompletionNameHelper.FindSourceFileName(uui.in_file.Value, out _, caseSensitiveSearch, curr_path); string unit_name = CodeCompletionNameHelper.FindSourceFileName(uui.in_file.Value, out _, currentUnitLanguage, curr_path);
if (unit_name == null) throw new InvalidOperationException($"uses '{uui.in_file.Value}';"); if (unit_name == null) throw new InvalidOperationException($"uses '{uui.in_file.Value}';");
CompileUnit(unit_name, cur_scope); CompileUnit(unit_name, cur_scope);
@ -2930,8 +2931,8 @@ namespace CodeCompletion
// на случай имен модулей, отличающихся от имен файла EVA // на случай имен модулей, отличающихся от имен файла EVA
string realName = GetRealNameForModule(usedName); string realName = GetRealNameForModule(usedName);
string pcu_unit_name = FindPCUFileName(realName, curr_path, caseSensitiveSearch); string pcu_unit_name = FindPCUFileName(realName, curr_path, currentUnitLanguage);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, caseSensitiveSearch, curr_path); string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, currentUnitLanguage, curr_path);
/*if (pcu_unit_name != null && unit_name != null && string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(pcu_unit_name), true) == 0 /*if (pcu_unit_name != null && unit_name != null && string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(pcu_unit_name), true) == 0
&& string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(unit_name), true) != 0) && string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(unit_name), true) != 0)
@ -3032,15 +3033,15 @@ namespace CodeCompletion
} }
private void CompileImportedUnit(string importedName, statement importStatement, as_statement_list asStatementsList, string curr_path, private void CompileImportedUnit(string importedName, statement importStatement, as_statement_list asStatementsList, string curr_path,
SymScope cur_scope, using_namespace_list unl, bool caseSensitiveSearch) SymScope cur_scope, using_namespace_list unl, ILanguage currentUnitLanguage)
{ {
try try
{ {
// на случай имен модулей, отличающихся от имен файла EVA // на случай имен модулей, отличающихся от имен файла EVA
string realName = GetRealNameForModule(importedName); string realName = GetRealNameForModule(importedName);
string pcu_unit_name = FindPCUFileName(realName, curr_path, caseSensitiveSearch); string pcu_unit_name = FindPCUFileName(realName, curr_path, currentUnitLanguage);
string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, caseSensitiveSearch, curr_path); string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, currentUnitLanguage, curr_path);
if (unit_name != null) if (unit_name != null)
{ {
@ -3273,14 +3274,14 @@ namespace CodeCompletion
{ {
unit_or_namespace s = _program_module.used_units.units[j]; unit_or_namespace s = _program_module.used_units.units[j];
CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_program_module.file_name), CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_program_module.file_name),
cur_scope, ns_cache, unl, currentUnitLanguage.CaseSensitive); cur_scope, ns_cache, unl, currentUnitLanguage);
} }
} }
// компиляция зависимостей из конструкций import и from import // компиляция зависимостей из конструкций import и from import
if (cur_scope != null && _program_module.program_block.program_code != null) if (cur_scope != null && _program_module.program_block.program_code != null)
{ {
CompileImportedDependencies(_program_module.program_block.program_code, _program_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage.CaseSensitive); CompileImportedDependencies(_program_module.program_block.program_code, _program_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage);
} }
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
@ -3288,7 +3289,7 @@ namespace CodeCompletion
// Добавление всех стандартных модулей EVA // Добавление всех стандартных модулей EVA
foreach (var unitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer)) foreach (var unitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer))
{ {
AddStandardUnit(unitName, currentUnitLanguage.CaseSensitive, currentUnitLanguage.LanguageInformation.AddStandardUnitNamesToUserScope); AddStandardUnit(unitName, currentUnitLanguage);
} }
foreach (string s in namespaces) foreach (string s in namespaces)
@ -3350,7 +3351,7 @@ namespace CodeCompletion
} }
} }
private void CompileImportedDependencies(statement_list statementList, string fileName, Hashtable ns_cache, List<string> usedUnitNames, bool caseSensitiveSearch) private void CompileImportedDependencies(statement_list statementList, string fileName, Hashtable ns_cache, List<string> usedUnitNames, Languages.Facade.ILanguage currentUnitLanguage)
{ {
var importStatements = statementList.list.Where(st => st is import_statement || st is from_import_statement); var importStatements = statementList.list.Where(st => st is import_statement || st is from_import_statement);
@ -3362,7 +3363,7 @@ namespace CodeCompletion
{ {
CompileImportedUnit(unitNode.name, import, import.modules_names, CompileImportedUnit(unitNode.name, import, import.modules_names,
Path.GetDirectoryName(fileName), Path.GetDirectoryName(fileName),
cur_scope, unl, caseSensitiveSearch); cur_scope, unl, currentUnitLanguage);
usedUnitNames.Add(unitNode.name); usedUnitNames.Add(unitNode.name);
} }
@ -3371,7 +3372,7 @@ namespace CodeCompletion
{ {
CompileImportedUnit(fromImport.module_name.name, fromImport, fromImport.imported_names, CompileImportedUnit(fromImport.module_name.name, fromImport, fromImport.imported_names,
Path.GetDirectoryName(fileName), Path.GetDirectoryName(fileName),
cur_scope, unl, caseSensitiveSearch); cur_scope, unl, currentUnitLanguage);
usedUnitNames.Add(fromImport.module_name.name); usedUnitNames.Add(fromImport.module_name.name);
} }
@ -5063,7 +5064,7 @@ namespace CodeCompletion
{ {
unit_or_namespace s = _implementation_node.uses_modules.units[j]; unit_or_namespace s = _implementation_node.uses_modules.units[j];
CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(this.cur_unit_file_name), CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(this.cur_unit_file_name),
cur_scope, ns_cache, unl, currentLanguage.CaseSensitive); cur_scope, ns_cache, unl, currentLanguage);
} }
} }
impl_scope = cur_scope; impl_scope = cur_scope;

View file

@ -363,8 +363,6 @@ namespace PascalABCCompiler
} }
} }
public string[] ParserSearchPaths;
// LeftToAll - слева во все модули, RightToMain - справа, только в основную программу // LeftToAll - слева во все модули, RightToMain - справа, только в основную программу
public enum StandardModuleAddMethod { LeftToAll, RightToMain }; public enum StandardModuleAddMethod { LeftToAll, RightToMain };
@ -458,8 +456,7 @@ namespace PascalABCCompiler
{ "%PABCSYSTEM%", SystemDirectory } { "%PABCSYSTEM%", SystemDirectory }
}; };
ParserSearchPaths = new string[] { Path.Combine(SystemDirectory, "Lib") }; SearchDirectories = new List<string>();
SearchDirectories = ParserSearchPaths.ToList();
} }
@ -634,10 +631,6 @@ namespace PascalABCCompiler
get { return state; } get { return state; }
} }
private void SetSupportedSourceFiles()
{
supportedSourceFiles = LanguageProvider.Languages.Select(language => SupportedSourceFile.Make(language)).ToArray();
}
private void SetSupportedProjectFiles() private void SetSupportedProjectFiles()
{ {
@ -645,13 +638,6 @@ namespace PascalABCCompiler
supportedProjectFiles = new SupportedSourceFile[] { new SupportedSourceFile(new string[1] { ".pabcproj" }, "PascalABC.NET") }; supportedProjectFiles = new SupportedSourceFile[] { new SupportedSourceFile(new string[1] { ".pabcproj" }, "PascalABC.NET") };
} }
private SupportedSourceFile[] supportedSourceFiles = null;
public SupportedSourceFile[] SupportedSourceFiles
{
get { return supportedSourceFiles; }
set { supportedSourceFiles = value; }
}
private SupportedSourceFile[] supportedProjectFiles = null; private SupportedSourceFile[] supportedProjectFiles = null;
public SupportedSourceFile[] SupportedProjectFiles public SupportedSourceFile[] SupportedProjectFiles
{ {
@ -805,7 +791,6 @@ namespace PascalABCCompiler
if (ChangeCompilerState != null) if (ChangeCompilerState != null)
OnChangeCompilerState += ChangeCompilerState; OnChangeCompilerState += ChangeCompilerState;
supportedSourceFiles = comp.SupportedSourceFiles;
supportedProjectFiles = comp.SupportedProjectFiles; supportedProjectFiles = comp.SupportedProjectFiles;
// 29.07.2024 EVA // 29.07.2024 EVA
@ -842,7 +827,6 @@ namespace PascalABCCompiler
SyntaxTreeToSemanticTreeConverter = new TreeConverter.SyntaxTreeToSemanticTreeConverter(); SyntaxTreeToSemanticTreeConverter = new TreeConverter.SyntaxTreeToSemanticTreeConverter();
CodeGeneratorsController = new CodeGenerators.Controller(); CodeGeneratorsController = new CodeGenerators.Controller();
SetSupportedSourceFiles();
SetSupportedProjectFiles(); SetSupportedProjectFiles();
semanticTreeConvertersController = new SemanticTreeConvertersController(this); semanticTreeConvertersController = new SemanticTreeConvertersController(this);
@ -1133,14 +1117,14 @@ namespace PascalABCCompiler
if (implementationUsesList != null) if (implementationUsesList != null)
{ {
SetUseDLLForSystemUnits(Path.GetDirectoryName(unitFileName), implementationUsesList, implementationUsesList.Count - 1, CurrentUnit.Language.CaseSensitive); SetUseDLLForSystemUnits(Path.GetDirectoryName(unitFileName), implementationUsesList, implementationUsesList.Count - 1, CurrentUnit.Language);
for (int i = implementationUsesList.Count - 1; i >= 0; i--) for (int i = implementationUsesList.Count - 1; i >= 0; i--)
{ {
if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, Path.GetDirectoryName(unitFileName), CurrentUnit.Language.CaseSensitive)) if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, Path.GetDirectoryName(unitFileName), CurrentUnit.Language))
{ {
// докомпилируем юнит, если он не является пространством имен или стандартным pas файлом из Lib // докомпилируем юнит, если он не является пространством имен или стандартным pas файлом из Lib
CompileUnit(CurrentUnit.ImplementationUsedUnits, CurrentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], Path.GetDirectoryName(unitFileName), CurrentUnit.Language.CaseSensitive); CompileUnit(CurrentUnit.ImplementationUsedUnits, CurrentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], Path.GetDirectoryName(unitFileName), CurrentUnit.Language);
} }
else else
{ {
@ -1946,7 +1930,7 @@ namespace PascalABCCompiler
return usesSection; return usesSection;
} }
public string FindPCUFileName(string fileName, string currentPath, out int folderPriority, bool caseSensitiveSearch) public string FindPCUFileName(string fileName, string currentPath, out int folderPriority, ILanguage currentUnitLanguage)
{ {
if (string.IsNullOrEmpty(Path.GetExtension(fileName))) if (string.IsNullOrEmpty(Path.GetExtension(fileName)))
fileName += CompilerOptions.CompiledUnitExtension; fileName += CompilerOptions.CompiledUnitExtension;
@ -1958,11 +1942,12 @@ namespace PascalABCCompiler
if (Path.GetExtension(fileName) != CompilerOptions.CompiledUnitExtension) if (Path.GetExtension(fileName) != CompilerOptions.CompiledUnitExtension)
fileNameWithPriority = null; fileNameWithPriority = null;
else if (FindFileWithExtensionInDirs(fileName, out _, caseSensitiveSearch, currentPath) is string resultFileName1) else if (FindFileWithExtensionInDirs(fileName, out _, currentUnitLanguage, currentPath) is string resultFileName1)
fileNameWithPriority = Tuple.Create(resultFileName1, 1); fileNameWithPriority = Tuple.Create(resultFileName1, 1);
else if (CompilerOptions.OutputDirectory != CompilerOptions.SourceFileDirectory && FindFileWithExtensionInDirs(Path.GetFileName(fileName), out _, caseSensitiveSearch, CompilerOptions.OutputDirectory) is string resultFileName2) else if (CompilerOptions.OutputDirectory != CompilerOptions.SourceFileDirectory && FindFileWithExtensionInDirs(Path.GetFileName(fileName), out _, currentUnitLanguage, CompilerOptions.OutputDirectory) is string resultFileName2)
fileNameWithPriority = Tuple.Create(resultFileName2, 2); fileNameWithPriority = Tuple.Create(resultFileName2, 2);
else if (FindFileWithExtensionInDirs(fileName, out var dirIndex, caseSensitiveSearch, CompilerOptions.SearchDirectories.ToArray()) is string resultFileName3) else if (FindFileWithExtensionInDirs(
fileName, out var dirIndex, currentUnitLanguage, GetCurrentSearchDirectories(currentUnitLanguage)) is string resultFileName3)
fileNameWithPriority = Tuple.Create(resultFileName3, 3 + dirIndex); fileNameWithPriority = Tuple.Create(resultFileName3, 3 + dirIndex);
else else
fileNameWithPriority = null; fileNameWithPriority = null;
@ -1974,16 +1959,28 @@ namespace PascalABCCompiler
return fileNameWithPriority?.Item1; return fileNameWithPriority?.Item1;
} }
public string FindSourceFileName(string fileName, string currentPath, out int folderPriority, bool caseSensitiveSearch) public string[] GetCurrentSearchDirectories(ILanguage currentUnitLanguage)
{
var libDirs = LanguageProvider.Languages
.Where(lang => lang == currentUnitLanguage)
.Concat(LanguageProvider.Languages.Where(lang => lang != currentUnitLanguage))
.Select(lang => Path.Combine(CompilerOptions.SystemDirectory, "Lib",
lang.Name.Replace(StringConstants.pascalLanguageName, ""))) // для PascalABC.NET прямо в Lib, остальные во внутренних папках
.Where(dir => Directory.Exists(dir));
return CompilerOptions.SearchDirectories.Concat(libDirs).ToArray();
}
public string FindSourceFileName(string fileName, string currentPath, out int folderPriority, ILanguage currentUnitLanguage)
{ {
var cacheKey = Tuple.Create(fileName.ToLower(), currentPath?.ToLower()); var cacheKey = Tuple.Create(fileName.ToLower(), currentPath?.ToLower());
if (!SourceFileNamesDictionary.TryGetValue(cacheKey, out var fileNameWithPriority)) if (!SourceFileNamesDictionary.TryGetValue(cacheKey, out var fileNameWithPriority))
{ {
if (FindSourceFileNameInDirs(fileName, out _, caseSensitiveSearch, currentPath) is string resultFileName1) if (FindSourceFileNameInDirs(fileName, out _, currentUnitLanguage, currentPath) is string resultFileName1)
fileNameWithPriority = Tuple.Create(resultFileName1, 1); fileNameWithPriority = Tuple.Create(resultFileName1, 1);
else if (FindSourceFileNameInDirs(fileName, out var dirIndex, caseSensitiveSearch, CompilerOptions.SearchDirectories.ToArray()) is string resultFileName2) else if (FindSourceFileNameInDirs(fileName, out var dirIndex, currentUnitLanguage, GetCurrentSearchDirectories(currentUnitLanguage)) is string resultFileName2)
fileNameWithPriority = Tuple.Create(resultFileName2, 3 + dirIndex); fileNameWithPriority = Tuple.Create(resultFileName2, 3 + dirIndex);
else else
fileNameWithPriority = null; fileNameWithPriority = null;
@ -1995,27 +1992,25 @@ namespace PascalABCCompiler
return fileNameWithPriority?.Item1; return fileNameWithPriority?.Item1;
} }
public string FindSourceFileNameInDirs(string fileName, out int foundDirIndex, bool caseSensitiveSearch, params string[] Dirs) public string FindSourceFileNameInDirs(string fileName, out int foundDirIndex, ILanguage currentUnitLanguage, params string[] Dirs)
{ {
var fileNameExtension = Path.GetExtension(fileName); var fileNameExtension = Path.GetExtension(fileName);
var isExtensionEmpty = string.IsNullOrEmpty(fileNameExtension); var isExtensionEmpty = string.IsNullOrEmpty(fileNameExtension);
// TODO: ищем сперва для расширения текущего языка EVA // Ищем сначала по расширениям текущего языка, потом по всем остальным
foreach (ILanguage lang in new ILanguage[] { currentUnitLanguage }.Concat(LanguageProvider.Languages.Where(l => l != currentUnitLanguage)))
foreach (SupportedSourceFile sf in SupportedSourceFiles)
{ {
foreach (string extension in sf.Extensions) foreach (string extension in lang.FilesExtensions)
{ {
if (isExtensionEmpty || fileNameExtension == extension) if (isExtensionEmpty || fileNameExtension == extension)
{ {
var resultFileName = FindFileWithExtensionInDirs(isExtensionEmpty ? fileName + extension : fileName, out foundDirIndex, caseSensitiveSearch, Dirs); var resultFileName = FindFileWithExtensionInDirs(isExtensionEmpty ? fileName + extension : fileName, out foundDirIndex, currentUnitLanguage, Dirs);
if (resultFileName != null) if (resultFileName != null)
return resultFileName; return resultFileName;
} }
} }
} }
foundDirIndex = 0; foundDirIndex = 0;
return null; return null;
} }
@ -2082,13 +2077,13 @@ namespace PascalABCCompiler
throw new InvalidOperationException($"Could not find path to \"{u2.UnitFileName}\" relative to \"{u1.UnitFileName}\""); throw new InvalidOperationException($"Could not find path to \"{u2.UnitFileName}\" relative to \"{u1.UnitFileName}\"");
} }
private string FindFileWithExtensionInDirs(string fileName, out int foundDirIndex, bool caseSensitiveSearch, params string[] dirs) private string FindFileWithExtensionInDirs(string fileName, out int foundDirIndex, ILanguage currentUnitLanguage, params string[] dirs)
{ {
if (Path.IsPathRooted(fileName)) if (Path.IsPathRooted(fileName))
{ {
foundDirIndex = 0; foundDirIndex = 0;
if (caseSensitiveSearch) if (currentUnitLanguage.CaseSensitive)
{ {
var foundFileName = Directory.GetFiles(Path.GetDirectoryName(fileName), Path.GetFileName(fileName), SearchOption.TopDirectoryOnly) var foundFileName = Directory.GetFiles(Path.GetDirectoryName(fileName), Path.GetFileName(fileName), SearchOption.TopDirectoryOnly)
.FirstOrDefault(f => f == fileName); .FirstOrDefault(f => f == fileName);
@ -2106,7 +2101,7 @@ namespace PascalABCCompiler
var dir = dirs[dirIndex]; var dir = dirs[dirIndex];
var fullFileName = Path.Combine(dir, fileName); var fullFileName = Path.Combine(dir, fileName);
if (caseSensitiveSearch) if (currentUnitLanguage.CaseSensitive)
{ {
var foundFileName = Directory.GetFiles(dir, fileName, SearchOption.TopDirectoryOnly) var foundFileName = Directory.GetFiles(dir, fileName, SearchOption.TopDirectoryOnly)
.FirstOrDefault(f => f == fullFileName); .FirstOrDefault(f => f == fullFileName);
@ -2202,7 +2197,7 @@ namespace PascalABCCompiler
} }
public string GetUnitFileName(SyntaxTree.unit_or_namespace unitNode, string currentPath, bool caseSensitiveSearch) public string GetUnitFileName(SyntaxTree.unit_or_namespace unitNode, string currentPath, ILanguage currentUnitLanguage)
{ {
if (unitNode is SyntaxTree.uses_unit_in unitNodeCasted && unitNodeCasted.name == null) if (unitNode is SyntaxTree.uses_unit_in unitNodeCasted && unitNodeCasted.name == null)
return unitNodeCasted.in_file.Value; return unitNodeCasted.in_file.Value;
@ -2221,10 +2216,10 @@ namespace PascalABCCompiler
} }
return GetUnitFileName(unitName, unitNode.UsesPath(), currentPath, unitNode.source_context, caseSensitiveSearch); return GetUnitFileName(unitName, unitNode.UsesPath(), currentPath, unitNode.source_context, currentUnitLanguage);
} }
public string GetUnitFileName(string unitName, string usesPath, string currentPath, SyntaxTree.SourceContext sourceContext, bool caseSensitiveSearch) public string GetUnitFileName(string unitName, string usesPath, string currentPath, SyntaxTree.SourceContext sourceContext, ILanguage currentUnitLanguage)
{ {
var cacheKey = Tuple.Create(usesPath.ToLower(), currentPath?.ToLower()); var cacheKey = Tuple.Create(usesPath.ToLower(), currentPath?.ToLower());
@ -2232,7 +2227,7 @@ namespace PascalABCCompiler
if (GetUnitFileNameCache.TryGetValue(cacheKey, out var unitPaths)) if (GetUnitFileNameCache.TryGetValue(cacheKey, out var unitPaths))
{ {
if (caseSensitiveSearch) if (currentUnitLanguage.CaseSensitive)
{ {
foreach (var unitPath in unitPaths) foreach (var unitPath in unitPaths)
{ {
@ -2249,8 +2244,8 @@ namespace PascalABCCompiler
} }
// число приоритета меньше означает, что папка более важная // число приоритета меньше означает, что папка более важная
var sourceFileName = FindSourceFileName(usesPath, currentPath, out var sourceFilePriority, caseSensitiveSearch); var sourceFileName = FindSourceFileName(usesPath, currentPath, out var sourceFilePriority, currentUnitLanguage);
var pcuFileName = FindPCUFileName(usesPath, currentPath, out var pcuFilePriority, caseSensitiveSearch); var pcuFileName = FindPCUFileName(usesPath, currentPath, out var pcuFilePriority, currentUnitLanguage);
bool sourceFileExists = sourceFileName != null; bool sourceFileExists = sourceFileName != null;
bool pcuFileExists = pcuFileName != null; bool pcuFileExists = pcuFileName != null;
@ -2455,7 +2450,7 @@ namespace PascalABCCompiler
namespaces[unitModule.unit_name.idunit_name.name] = namespaceNode; namespaces[unitModule.unit_name.idunit_name.name] = namespaceNode;
} }
AddDeclarationsAndReferencedUnitsToNamespaces(namespaceModules, file, unitModule, namespaceNode, compilationUnit.Language.CaseSensitive); AddDeclarationsAndReferencedUnitsToNamespaces(namespaceModules, file, unitModule, namespaceNode, compilationUnit.Language);
} }
// корневой модуль является чем-то одним из этого // корневой модуль является чем-то одним из этого
@ -2511,7 +2506,7 @@ namespace PascalABCCompiler
} }
private void AddDeclarationsAndReferencedUnitsToNamespaces(List<SyntaxTree.unit_or_namespace> namespace_modules, string file, private void AddDeclarationsAndReferencedUnitsToNamespaces(List<SyntaxTree.unit_or_namespace> namespace_modules, string file,
SyntaxTree.unit_module unitModule, SyntaxTree.syntax_namespace_node namespaceNode, bool caseSensitive) SyntaxTree.unit_module unitModule, SyntaxTree.syntax_namespace_node namespaceNode, ILanguage currentUnitLanguage)
{ {
if (unitModule.interface_part.interface_definitions != null) if (unitModule.interface_part.interface_definitions != null)
{ {
@ -2524,7 +2519,7 @@ namespace PascalABCCompiler
CheckForDuplicatesInUsesSection(unitModule.interface_part.uses_modules.units); CheckForDuplicatesInUsesSection(unitModule.interface_part.uses_modules.units);
foreach (SyntaxTree.unit_or_namespace name_space in unitModule.interface_part.uses_modules.units) foreach (SyntaxTree.unit_or_namespace name_space in unitModule.interface_part.uses_modules.units)
{ {
if (IsPossibleNetNamespaceOrStandardPasFile(name_space, false, Path.GetDirectoryName(file), caseSensitive)) if (IsPossibleNetNamespaceOrStandardPasFile(name_space, false, Path.GetDirectoryName(file), currentUnitLanguage))
{ {
namespaceNode.referenced_units.AddElement(new namespace_unit_node(GetNamespace(name_space), GetLocationFromTreenode(name_space, unitModule.file_name)), null); namespaceNode.referenced_units.AddElement(new namespace_unit_node(GetNamespace(name_space), GetLocationFromTreenode(name_space, unitModule.file_name)), null);
} }
@ -2752,7 +2747,7 @@ namespace PascalABCCompiler
NetHelper.AssemblyResolveScope assemblyResolveScope; NetHelper.AssemblyResolveScope assemblyResolveScope;
private bool IsPossibleNetNamespaceOrStandardPasFile(SyntaxTree.unit_or_namespace name_space, bool addToStandardModules, string currentPath, bool caseSensitiveSearch) private bool IsPossibleNetNamespaceOrStandardPasFile(SyntaxTree.unit_or_namespace name_space, bool addToStandardModules, string currentPath, ILanguage currentUnitLanguage)
{ {
if (name_space is SyntaxTree.uses_unit_in) if (name_space is SyntaxTree.uses_unit_in)
return false; return false;
@ -2761,8 +2756,8 @@ namespace PascalABCCompiler
if (name_space.name.idents.Count > 1) if (name_space.name.idents.Count > 1)
return true; return true;
string sourceFileName = FindSourceFileName(name_space.name.idents[0].name, currentPath, out _, caseSensitiveSearch); string sourceFileName = FindSourceFileName(name_space.name.idents[0].name, currentPath, out _, currentUnitLanguage);
string pcuFileName = FindPCUFileName(name_space.name.idents[0].name, currentPath, out _, caseSensitiveSearch); string pcuFileName = FindPCUFileName(name_space.name.idents[0].name, currentPath, out _, currentUnitLanguage);
// если нет исходников и pcu // если нет исходников и pcu
if (sourceFileName == null && pcuFileName == null) if (sourceFileName == null && pcuFileName == null)
@ -2951,9 +2946,9 @@ namespace PascalABCCompiler
/// <param name="currentUnitNode">Синтаксический узел текущего модуля (или пространства имен)</param> /// <param name="currentUnitNode">Синтаксический узел текущего модуля (или пространства имен)</param>
/// <param name="previousPath">Директория родительского модуля</param> /// <param name="previousPath">Директория родительского модуля</param>
/// <returns>Скомпилированный юнит</returns> /// <returns>Скомпилированный юнит</returns>
public CompilationUnit CompileUnit(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, string previousPath, bool caseSensitiveSearch = false) public CompilationUnit CompileUnit(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, string previousPath, ILanguage previousUnitLanguage = null)
{ {
string unitFileName = GetUnitFileName(currentUnitNode, previousPath, caseSensitiveSearch); string unitFileName = GetUnitFileName(currentUnitNode, previousPath, previousUnitLanguage);
string unitId = Path.ChangeExtension(unitFileName, null); string unitId = Path.ChangeExtension(unitFileName, null);
// Имя папки, в которой лежит текущий модуль // Имя папки, в которой лежит текущий модуль
// Используется для подключения модулей, $include и т.п. из модуля, подключённого с uses-in // Используется для подключения модулей, $include и т.п. из модуля, подключённого с uses-in
@ -2983,7 +2978,7 @@ namespace PascalABCCompiler
else else
{ {
// если есть pcu - возврат EVA // если есть pcu - возврат EVA
if (UnitHasPCU(unitsFromUsesSection, directUnitsFromUsesSection, currentUnitNode, ref unitFileName, ref currentUnit, caseSensitiveSearch)) if (UnitHasPCU(unitsFromUsesSection, directUnitsFromUsesSection, currentUnitNode, ref unitFileName, ref currentUnit, previousUnitLanguage))
return currentUnit; return currentUnit;
// нет pcu и модуль не откомпилирован => новый модуль EVA // нет pcu и модуль не откомпилирован => новый модуль EVA
@ -3156,7 +3151,7 @@ namespace PascalABCCompiler
{ {
interfaceUsesList = GetInterfaceUsesSection(currentUnit.SyntaxTree); interfaceUsesList = GetInterfaceUsesSection(currentUnit.SyntaxTree);
SetUseDLLForSystemUnits(currentDirectory, interfaceUsesList, interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count, currentUnit.Language.CaseSensitive); SetUseDLLForSystemUnits(currentDirectory, interfaceUsesList, interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count, currentUnit.Language);
references = GetReferences(currentUnit); references = GetReferences(currentUnit);
@ -3230,9 +3225,9 @@ namespace PascalABCCompiler
{ {
for (int i = implementationUsesList.Count - 1; i >= 0; i--) for (int i = implementationUsesList.Count - 1; i >= 0; i--)
{ {
if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, currentPath, currentUnit.Language.CaseSensitive)) if (!IsPossibleNetNamespaceOrStandardPasFile(implementationUsesList[i], true, currentPath, currentUnit.Language))
{ {
CompilationUnit unitFromUsesSection = UnitTable[Path.ChangeExtension(GetUnitFileName(implementationUsesList[i], currentPath, currentUnit.Language.CaseSensitive), null)]; CompilationUnit unitFromUsesSection = UnitTable[Path.ChangeExtension(GetUnitFileName(implementationUsesList[i], currentPath, currentUnit.Language), null)];
// защита от попадания в бесконечный цикл (когда мы вернемся в тот юнит, в котором уже были (еще не скомпилированный), а затем спустимся по дереву зависимостей сюда же и т.д.) // защита от попадания в бесконечный цикл (когда мы вернемся в тот юнит, в котором уже были (еще не скомпилированный), а затем спустимся по дереву зависимостей сюда же и т.д.)
// первая часть условия - если мы встречаем юнит не первый раз, вторая часть - если интерфейс еще не скомпилирован // первая часть условия - если мы встречаем юнит не первый раз, вторая часть - если интерфейс еще не скомпилирован
@ -3246,7 +3241,7 @@ namespace PascalABCCompiler
} }
else else
{ {
CompileUnit(currentUnit.ImplementationUsedUnits, currentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], currentPath, currentUnit.Language.CaseSensitive); CompileUnit(currentUnit.ImplementationUsedUnits, currentUnit.ImplementationUsedDirectUnits, implementationUsesList[i], currentPath, currentUnit.Language);
} }
} }
else else
@ -3322,7 +3317,7 @@ namespace PascalABCCompiler
shouldReturnCurrentUnit = false; shouldReturnCurrentUnit = false;
for (int i = interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count; i >= 0; i--) // здесь откидываются модули с уже откомпилированными интерфейсами из секции uses (см. комментарий, обозначенный #1710) for (int i = interfaceUsesList.Count - 1 - currentUnit.InterfaceUsedUnits.Count; i >= 0; i--) // здесь откидываются модули с уже откомпилированными интерфейсами из секции uses (см. комментарий, обозначенный #1710)
{ {
if (IsPossibleNetNamespaceOrStandardPasFile(interfaceUsesList[i], true, currentPath, currentUnit.Language.CaseSensitive) || namespaces.ContainsKey(interfaceUsesList[i].name.idents[0].name)) if (IsPossibleNetNamespaceOrStandardPasFile(interfaceUsesList[i], true, currentPath, currentUnit.Language) || namespaces.ContainsKey(interfaceUsesList[i].name.idents[0].name))
{ {
currentUnit.InterfaceUsedUnits.AddElement(new namespace_unit_node(GetNamespace(interfaceUsesList[i])), null); currentUnit.InterfaceUsedUnits.AddElement(new namespace_unit_node(GetNamespace(interfaceUsesList[i])), null);
currentUnit.possibleNamespaces.Add(interfaceUsesList[i]); currentUnit.possibleNamespaces.Add(interfaceUsesList[i]);
@ -3336,7 +3331,7 @@ namespace PascalABCCompiler
#endregion #endregion
// компиляция модулей из интерфейса текущего модуля // компиляция модулей из интерфейса текущего модуля
CompileUnit(currentUnit.InterfaceUsedUnits, currentUnit.InterfaceUsedDirectUnits, interfaceUsesList[i], currentPath, currentUnit.Language.CaseSensitive); CompileUnit(currentUnit.InterfaceUsedUnits, currentUnit.InterfaceUsedDirectUnits, interfaceUsesList[i], currentPath, currentUnit.Language);
// если текущий модуль был откомпилирован в другом рекурсивном вызове // если текущий модуль был откомпилирован в другом рекурсивном вызове
if (currentUnit.State == UnitState.Compiled) if (currentUnit.State == UnitState.Compiled)
@ -3351,7 +3346,7 @@ namespace PascalABCCompiler
private void SemanticCheckNoLoopDependenciesOfInterfaces(CompilationUnit currentUnit, string unitFileName, SyntaxTree.unit_or_namespace usedUnitNode, string currentPath) private void SemanticCheckNoLoopDependenciesOfInterfaces(CompilationUnit currentUnit, string unitFileName, SyntaxTree.unit_or_namespace usedUnitNode, string currentPath)
{ {
var usedUnitFileName = GetUnitFileName(usedUnitNode, currentPath, currentUnit.Language.CaseSensitive); var usedUnitFileName = GetUnitFileName(usedUnitNode, currentPath, currentUnit.Language);
var usedUnitId = Path.ChangeExtension(usedUnitFileName, null); var usedUnitId = Path.ChangeExtension(usedUnitFileName, null);
// когда образуется цикл здесь сохранится смежная вершина графа (используемый юнит), которая тоже принадлежит циклу // когда образуется цикл здесь сохранится смежная вершина графа (используемый юнит), которая тоже принадлежит циклу
@ -3378,13 +3373,13 @@ namespace PascalABCCompiler
/// <summary> /// <summary>
/// Если в программе в секции uses есть не про-во имен и не стандартный модуль, то использование PABCRtl.dll отменяется /// Если в программе в секции uses есть не про-во имен и не стандартный модуль, то использование PABCRtl.dll отменяется
/// </summary> /// </summary>
private void SetUseDLLForSystemUnits(string currentDirectory, List<SyntaxTree.unit_or_namespace> usesList, int lastUnitIndex, bool caseSensitive) private void SetUseDLLForSystemUnits(string currentDirectory, List<SyntaxTree.unit_or_namespace> usesList, int lastUnitIndex, ILanguage currentUnitLanguage)
{ {
if (usesList != null && CompilerOptions.UseDllForSystemUnits) if (usesList != null && CompilerOptions.UseDllForSystemUnits)
{ {
for (int i = lastUnitIndex; i >= 0; i--) for (int i = lastUnitIndex; i >= 0; i--)
{ {
if (!IsPossibleNetNamespaceOrStandardPasFile(usesList[i], false, currentDirectory, caseSensitive)) if (!IsPossibleNetNamespaceOrStandardPasFile(usesList[i], false, currentDirectory, currentUnitLanguage))
{ {
CompilerOptions.UseDllForSystemUnits = false; CompilerOptions.UseDllForSystemUnits = false;
break; break;
@ -3648,7 +3643,7 @@ namespace PascalABCCompiler
return docs; return docs;
} }
private bool UnitHasPCU(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, ref string UnitFileName, ref CompilationUnit currentUnit, bool caseSensitiveSearch) private bool UnitHasPCU(unit_node_list unitsFromUsesSection, Dictionary<unit_node, CompilationUnit> directUnitsFromUsesSection, SyntaxTree.unit_or_namespace currentUnitNode, ref string UnitFileName, ref CompilationUnit currentUnit, ILanguage previousUnitLanguage)
{ {
if (Path.GetExtension(UnitFileName).ToLower() == CompilerOptions.CompiledUnitExtension) if (Path.GetExtension(UnitFileName).ToLower() == CompilerOptions.CompiledUnitExtension)
{ {
@ -3657,7 +3652,7 @@ namespace PascalABCCompiler
if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitFileName, null); if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitFileName, null);
try try
{ {
if ((currentUnit = ReadPCU(UnitFileName, caseSensitiveSearch)) != null) if ((currentUnit = ReadPCU(UnitFileName, previousUnitLanguage)) != null)
{ {
AddCurrentUnitAndItsReferencesToUsesLists(unitsFromUsesSection, directUnitsFromUsesSection, AddCurrentUnitAndItsReferencesToUsesLists(unitsFromUsesSection, directUnitsFromUsesSection,
currentUnitNode, currentUnit, GetReferences(currentUnit)); currentUnitNode, currentUnit, GetReferences(currentUnit));
@ -3683,7 +3678,7 @@ namespace PascalABCCompiler
throw new CompilerInternalError("PCUReader", e); throw new CompilerInternalError("PCUReader", e);
#endif #endif
} }
string SourceFileName = FindSourceFileName(Path.ChangeExtension(UnitFileName, null), null, out _, caseSensitiveSearch); string SourceFileName = FindSourceFileName(Path.ChangeExtension(UnitFileName, null), null, out _, previousUnitLanguage);
if (SourceFileName == null) if (SourceFileName == null)
throw new ReadPCUError(UnitFileName); throw new ReadPCUError(UnitFileName);
else else
@ -3786,7 +3781,7 @@ namespace PascalABCCompiler
} }
} }
public CompilationUnit ReadPCU(string FileName, bool caseSensitiveSearch) public CompilationUnit ReadPCU(string FileName, ILanguage currentUnitLanguage)
{ {
if (CompilerOptions.ForIntellisense && false) if (CompilerOptions.ForIntellisense && false)
{ {
@ -3797,14 +3792,14 @@ namespace PascalABCCompiler
return unit; return unit;
} }
PCUReader pr = new PCUReader(this, pr_ChangeState); PCUReader pr = new PCUReader(this, pr_ChangeState);
unit = pr.GetCompilationUnit(FileName, CompilerOptions.Debug, caseSensitiveSearch); unit = pr.GetCompilationUnit(FileName, CompilerOptions.Debug, currentUnitLanguage);
pcuCompilationUnits[FileName] = unit; pcuCompilationUnits[FileName] = unit;
return unit; return unit;
} }
else else
{ {
PCUReader pr = new PCUReader(this, pr_ChangeState); PCUReader pr = new PCUReader(this, pr_ChangeState);
return pr.GetCompilationUnit(FileName, CompilerOptions.Debug, caseSensitiveSearch); return pr.GetCompilationUnit(FileName, CompilerOptions.Debug, currentUnitLanguage);
} }
} }
@ -4010,10 +4005,10 @@ namespace PascalABCCompiler
return null; return null;
return compilationUnit; return compilationUnit;
}*/ }*/
public bool NeedRecompiled(string pcu_name, string[] included, PCUReader pr, bool caseSensitive) public bool NeedRecompiled(string pcu_name, string[] included, PCUReader pr, ILanguage currentUnitLanguage)
{ {
if (!Path.IsPathRooted(pcu_name)) throw new InvalidOperationException(); if (!Path.IsPathRooted(pcu_name)) throw new InvalidOperationException();
string pas_name = FindSourceFileName(Path.ChangeExtension(pcu_name, null), null, out _, caseSensitive); string pas_name = FindSourceFileName(Path.ChangeExtension(pcu_name, null), null, out _, currentUnitLanguage);
var dir = Path.GetDirectoryName(pcu_name); var dir = Path.GetDirectoryName(pcu_name);
if (UnitTable[Path.ChangeExtension(pas_name, null)] != null) if (UnitTable[Path.ChangeExtension(pas_name, null)] != null)
@ -4024,7 +4019,7 @@ namespace PascalABCCompiler
{ {
//if (included[i].Contains("$")) //if (included[i].Contains("$"))
// continue; // continue;
var used_unit_fname = GetUnitFileName(Path.GetFileNameWithoutExtension(included[i]), included[i], dir, null, caseSensitive); var used_unit_fname = GetUnitFileName(Path.GetFileNameWithoutExtension(included[i]), included[i], dir, null, currentUnitLanguage);
var used_unit_is_pcu = Path.GetExtension(used_unit_fname) == CompilerOptions.CompiledUnitExtension; var used_unit_is_pcu = Path.GetExtension(used_unit_fname) == CompilerOptions.CompiledUnitExtension;
if (!used_unit_is_pcu) if (!used_unit_is_pcu)
@ -4045,7 +4040,7 @@ namespace PascalABCCompiler
//Console.WriteLine("{0} {1}",name,RecompileList.Count); //Console.WriteLine("{0} {1}",name,RecompileList.Count);
for (int i = 0; i < included.Length; i++) for (int i = 0; i < included.Length; i++)
{ {
string pcu_name2 = FindPCUFileName(included[i], dir, out _, caseSensitive); string pcu_name2 = FindPCUFileName(included[i], dir, out _, currentUnitLanguage);
//TODO: Спросить у Сащи насчет < и <=. //TODO: Спросить у Сащи насчет < и <=.
if ((File.Exists(pcu_name2) && File.GetLastWriteTime(pcu_name) < File.GetLastWriteTime(pcu_name2) && !pr.AlreadyCompiled(pcu_name2))) if ((File.Exists(pcu_name2) && File.GetLastWriteTime(pcu_name) < File.GetLastWriteTime(pcu_name2) && !pr.AlreadyCompiled(pcu_name2)))

View file

@ -51,11 +51,6 @@ namespace PascalABCCompiler
get; get;
} }
SupportedSourceFile[] SupportedSourceFiles
{
get;
}
SupportedSourceFile[] SupportedProjectFiles SupportedSourceFile[] SupportedProjectFiles
{ {
get; get;

View file

@ -7,6 +7,6 @@ namespace PascalABCCompiler.PCU
{ {
public static class PCUFileFormatVersion public static class PCUFileFormatVersion
{ {
public static System.Int16 Version = 122; public static System.Int16 Version = 123;
} }
} }

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using PascalABCCompiler.TreeConverter; using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using Languages.Facade;
namespace PascalABCCompiler.PCU namespace PascalABCCompiler.PCU
{ {
@ -217,10 +218,10 @@ namespace PascalABCCompiler.PCU
ReadPCUHeader(); ReadPCUHeader();
} }
public string GetFullUnitName(string UnitName, bool caseSensitiveSearch) public string GetFullUnitName(string UnitName, ILanguage currentUnitLanguage)
{ {
var FullUnitName = comp.FindPCUFileName(UnitName, dir, out _, caseSensitiveSearch); var FullUnitName = comp.FindPCUFileName(UnitName, dir, out _, currentUnitLanguage);
if (FullUnitName == null) throw new Errors.FileNotFound(UnitName, null); if (FullUnitName == null) throw new Errors.FileNotFound(UnitName, null);
return FullUnitName; return FullUnitName;
@ -229,25 +230,28 @@ namespace PascalABCCompiler.PCU
private PCUReader GetPCUReaderForUnitId(int id) private PCUReader GetPCUReaderForUnitId(int id)
{ {
if (id == -1) return this; if (id == -1) return this;
string s = GetFullUnitName(pcu_file.incl_modules[id], pcu_file.languageCaseSensitive);
ILanguage currentUnitLanguage = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName);
string s = GetFullUnitName(pcu_file.incl_modules[id], currentUnitLanguage);
if ( !units.TryGetValue(s, out var pr) ) if ( !units.TryGetValue(s, out var pr) )
{ {
pr = new PCUReader(this); pr = new PCUReader(this);
pr.GetCompilationUnit(s, this.readDebugInfo, pcu_file.languageCaseSensitive); pr.GetCompilationUnit(s, this.readDebugInfo, currentUnitLanguage);
} }
return pr; return pr;
} }
//десериализация модуля //десериализация модуля
//читается только шапка PCU и заполняются имена сущностей модуля в таблицу символов //читается только шапка PCU и заполняются имена сущностей модуля в таблицу символов
public CompilationUnit GetCompilationUnit(string FileName, bool readDebugInfo, bool caseSensitiveSearch) public CompilationUnit GetCompilationUnit(string FileName, bool readDebugInfo, ILanguage currentUnitLanguage)
{ {
try try
{ {
// Compiler.CombinePath всегда должно быть применено к имени файла, перед тем как кидать его сюда // Compiler.CombinePath всегда должно быть применено к имени файла, перед тем как кидать его сюда
if (!Path.IsPathRooted(FileName)) throw new InvalidOperationException(); if (!Path.IsPathRooted(FileName)) throw new InvalidOperationException();
FileName = GetFullUnitName(FileName, caseSensitiveSearch); FileName = GetFullUnitName(FileName, currentUnitLanguage);
dir = Path.GetDirectoryName(FileName); dir = Path.GetDirectoryName(FileName);
this.FileName = FileName; this.FileName = FileName;
@ -277,8 +281,9 @@ namespace PascalABCCompiler.PCU
ChangeState(this, PCUReaderWriterState.BeginReadTree, unit); ChangeState(this, PCUReaderWriterState.BeginReadTree, unit);
cun.scope = new WrappedUnitInterfaceScope(this); cun.scope = new WrappedUnitInterfaceScope(this);
//TODO сохранить в PCU bool unitLanguageCaseSensitive = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName).CaseSensitive;
cun.scope.CaseSensitive = pcu_file.languageCaseSensitive;
cun.scope.CaseSensitive = unitLanguageCaseSensitive;
if (string.Compare(unit_name, StringConstants.pascalSystemUnitName, true)==0) if (string.Compare(unit_name, StringConstants.pascalSystemUnitName, true)==0)
PascalABCCompiler.TreeConverter.syntax_tree_visitor.init_system_module(cun); PascalABCCompiler.TreeConverter.syntax_tree_visitor.init_system_module(cun);
@ -287,8 +292,7 @@ namespace PascalABCCompiler.PCU
cun.implementation_scope = new WrappedUnitImplementationScope(this, cun.scope); cun.implementation_scope = new WrappedUnitImplementationScope(this, cun.scope);
//\ssyy //\ssyy
//TODO сохранить в PCU cun.implementation_scope.CaseSensitive = unitLanguageCaseSensitive;
cun.implementation_scope.CaseSensitive = pcu_file.languageCaseSensitive;
string SourceFileName = pcu_file.SourceFileName; string SourceFileName = pcu_file.SourceFileName;
if (Path.GetDirectoryName(SourceFileName) == "") if (Path.GetDirectoryName(SourceFileName) == "")
@ -354,7 +358,10 @@ namespace PascalABCCompiler.PCU
need = true; need = true;
return need; return need;
}*/ }*/
if (comp.NeedRecompiled(FileName, pcu_file.incl_modules, this, pcu_file.languageCaseSensitive))
ILanguage currentUnitLanguage = LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName);
if (comp.NeedRecompiled(FileName, pcu_file.incl_modules, this, currentUnitLanguage))
{ {
//comp.RecompileList.Add(unit_name,unit_name); //comp.RecompileList.Add(unit_name,unit_name);
comp.RecompileList.Add(FileName); comp.RecompileList.Add(FileName);
@ -366,7 +373,7 @@ namespace PascalABCCompiler.PCU
{ {
//if (pcu_file.incl_modules[i].Contains("$")) //if (pcu_file.incl_modules[i].Contains("$"))
// continue; // continue;
var used_unit_fname = comp.GetUnitFileName(Path.GetFileNameWithoutExtension(pcu_file.incl_modules[i]), pcu_file.incl_modules[i], dir, new SyntaxTree.SourceContext(0,0,0,0, FileName), pcu_file.languageCaseSensitive); var used_unit_fname = comp.GetUnitFileName(Path.GetFileNameWithoutExtension(pcu_file.incl_modules[i]), pcu_file.incl_modules[i], dir, new SyntaxTree.SourceContext(0,0,0,0, FileName), currentUnitLanguage);
if (Path.GetExtension(used_unit_fname) != comp.CompilerOptions.CompiledUnitExtension) return true; if (Path.GetExtension(used_unit_fname) != comp.CompilerOptions.CompiledUnitExtension) return true;
if ( !units.TryGetValue(used_unit_fname, out var pr) ); if ( !units.TryGetValue(used_unit_fname, out var pr) );
@ -377,7 +384,7 @@ namespace PascalABCCompiler.PCU
used_units.Add(used_unit_fname); used_units.Add(used_unit_fname);
if (!already_compiled.Contains(used_unit_fname)) if (!already_compiled.Contains(used_unit_fname))
{ {
var sub_u = pr.GetCompilationUnit(used_unit_fname, this.readDebugInfo, pcu_file.languageCaseSensitive); var sub_u = pr.GetCompilationUnit(used_unit_fname, this.readDebugInfo, currentUnitLanguage);
if (sub_u == null) return true; if (sub_u == null) return true;
this.unit.InterfaceUsedDirectUnits.Add(sub_u.SemanticTree, sub_u); this.unit.InterfaceUsedDirectUnits.Add(sub_u.SemanticTree, sub_u);
this.unit.InterfaceUsedUnits.AddElement(sub_u.SemanticTree, pcu_file.incl_modules[i]); this.unit.InterfaceUsedUnits.AddElement(sub_u.SemanticTree, pcu_file.incl_modules[i]);
@ -580,7 +587,7 @@ namespace PascalABCCompiler.PCU
else else
cur_doc = new document(pcu_file.SourceFileName); cur_doc = new document(pcu_file.SourceFileName);
pcu_file.languageCaseSensitive = br.ReadBoolean(); pcu_file.languageName = br.ReadString();
int num_names = br.ReadInt32(); int num_names = br.ReadInt32();
pcu_file.names = new NameRef[num_names]; pcu_file.names = new NameRef[num_names];
@ -2490,7 +2497,8 @@ namespace PascalABCCompiler.PCU
//Добавляем подключенные модули //Добавляем подключенные модули
for (int i = 0; i < uses_count; i++) for (int i = 0; i < uses_count; i++)
{ {
if ( units.TryGetValue(GetFullUnitName(pcu_file.incl_modules[i], pcu_file.languageCaseSensitive), out var pcu_r) ); if ( units.TryGetValue(GetFullUnitName(pcu_file.incl_modules[i],
LanguageProvider.Instance.SelectLanguageByName(pcu_file.languageName)), out var pcu_r) );
{ {
top_scopes.Add(pcu_r.cun.scope); top_scopes.Add(pcu_r.cun.scope);
} }

View file

@ -171,7 +171,7 @@ namespace PascalABCCompiler.PCU
public string SourceFileName; public string SourceFileName;
public bool languageCaseSensitive; public string languageName;
public NameRef[] names; //список имен интерфейсной части модуля public NameRef[] names; //список имен интерфейсной части модуля
public string[] incl_modules; //список подключаемых модулей public string[] incl_modules; //список подключаемых модулей
@ -305,7 +305,7 @@ namespace PascalABCCompiler.PCU
GetUsedUnits();//заполняем список полключаемых модулей GetUsedUnits();//заполняем список полключаемых модулей
pcu_file.languageCaseSensitive = Unit.Language.CaseSensitive; pcu_file.languageName = Unit.Language.Name;
GetCountOfMembers();//заполняем список имен интерфейсных сущностей GetCountOfMembers();//заполняем список имен интерфейсных сущностей
WriteUnit();//пишем имя interface_namespace WriteUnit();//пишем имя interface_namespace
@ -439,7 +439,7 @@ namespace PascalABCCompiler.PCU
if (pcu_file.IncludeDebugInfo) if (pcu_file.IncludeDebugInfo)
fbw.Write(pcu_file.SourceFileName); fbw.Write(pcu_file.SourceFileName);
fbw.Write(pcu_file.languageCaseSensitive); fbw.Write(pcu_file.languageName);
fbw.Write(pcu_file.names.Length); fbw.Write(pcu_file.names.Length);
for (int i=0; i<pcu_file.names.Length; i++) for (int i=0; i<pcu_file.names.Length; i++)

View file

@ -19,72 +19,19 @@ namespace Languages.Integration
private static readonly LanguageProvider LanguageProvider = LanguageProvider.Instance; private static readonly LanguageProvider LanguageProvider = LanguageProvider.Instance;
/// <summary> /// <summary>
/// Имя директории, содержащей установленные плагины языков программирования /// Событие, информирующее об успешной загрузке языкового пакета
/// </summary>
private const string languageKitsDirectoryName = "LanguageKits";
/// <summary>
/// Событие, информирующее об успешной загрузке плагина языка
/// </summary> /// </summary>
public static event Action<ILanguage> LanguageLoaded; public static event Action<ILanguage> LanguageLoaded;
/// <summary> /// <summary>
/// Событие, информирующее об ошибке загрузки плагина языка /// Событие, информирующее об ошибке загрузки языкового пакета
/// </summary> /// </summary>
public static event Action<string> LanguageLoadErrorOccured; public static event Action<string> LanguageLoadErrorOccured;
/// <summary> /// <summary>
/// Возвращает директорию, содержащую комплекты языков (если ее нет, то вернется null) /// Загружает все языки платформы из папки bin
/// </summary>
private static DirectoryInfo GetLanguageKitsDirectory()
{
string binDirectoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string languageKitsDirectoryPath = Path.Combine(binDirectoryPath, languageKitsDirectoryName);
if (Directory.Exists(languageKitsDirectoryPath))
return new DirectoryInfo(languageKitsDirectoryPath);
return null;
}
/// <summary>
/// Загружает все языковые комплекты для использования (имя "главной" dll должно заканчиваться на Language)
/// </summary>
public static void LoadAllLanguageKits()
{
DirectoryInfo languageKitsDirectory = GetLanguageKitsDirectory();
if (languageKitsDirectory == null)
return;
foreach (var languageKit in languageKitsDirectory.GetDirectories())
{
FileInfo[] dllFiles = languageKit.GetFiles();
foreach (var dll in dllFiles)
{
if (dll.Name.EndsWith("LanguageInfo.dll"))
{
IntegrateLanguageFromAssembly(dll);
break;
}
}
}
}
/// <summary>
/// Загружает все языки, доступные в системе
/// </summary> /// </summary>
public static void LoadAllLanguages() public static void LoadAllLanguages()
{
LoadStandardLanguages();
LoadAllLanguageKits();
}
/// <summary>
/// Загружает стандартные языки платформы из папки bin
/// </summary>
public static void LoadStandardLanguages()
{ {
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName); string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);

View file

@ -35,6 +35,12 @@ namespace PascalABCCompiler
public class FormatTools public class FormatTools
{ {
public static string LanguageAndExtensionsFormatted(string languageName, string[] extensions)
{
return string.Format("{0} ({1})", languageName, ExtensionsToString(extensions, "*", ";"));
}
public static string ExtensionsToString(string[] Extensions,string Mask,string Delimer) public static string ExtensionsToString(string[] Extensions,string Mask,string Delimer)
{ {
string res = ""; string res = "";

View file

@ -2,6 +2,7 @@ cd ..\bin
del ..\Release\PACNETConsole.zip del ..\Release\PACNETConsole.zip
..\utils\pkzipc\pkzipc.exe -add ..\Release\PABCNETC.zip pabcnetc.exe pabcnetcclear.exe Compiler.dll CompilerTools.dll Errors.dll Localization.dll NETGenerator.dll ParserTools.dll ICSharpCode.NRefactory.dll SemanticTree.dll SyntaxTree.dll TreeConverter.dll OptimizerConversion.dll PascalABCParser.dll PascalABCLanguageInfo.dll licence.txt PascalABCNET.chm System.Threading.dll SyntaxTreeConverters.dll YieldHelpers.dll SyntaxVisitors.dll LambdaAnySynToSemConverter.dll LanguageIntegrator.dll StringConstants.dll ..\utils\pkzipc\pkzipc.exe -add ..\Release\PABCNETC.zip pabcnetc.exe pabcnetcclear.exe Compiler.dll CompilerTools.dll Errors.dll Localization.dll NETGenerator.dll ParserTools.dll ICSharpCode.NRefactory.dll SemanticTree.dll SyntaxTree.dll TreeConverter.dll OptimizerConversion.dll PascalABCParser.dll PascalABCLanguageInfo.dll licence.txt PascalABCNET.chm System.Threading.dll SyntaxTreeConverters.dll YieldHelpers.dll SyntaxVisitors.dll LambdaAnySynToSemConverter.dll LanguageIntegrator.dll StringConstants.dll
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lib\*.pcu ..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lib\*.pcu
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lib\SPython\*.pcu
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lng\*.dat ..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lng\*.dat
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lng\*.LanguageName ..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip Lng\*.LanguageName
..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip doc\*.* ..\utils\pkzipc\pkzipc.exe -add -nozip -dir ..\Release\PABCNETC.zip doc\*.*

View file

@ -108,7 +108,9 @@ SectionEnd
Section Section
${AddDirectory} "$INSTDIR\LibSource" ${AddDirectory} "$INSTDIR\LibSource"
${AddDirectory} "$INSTDIR\LibSource\SPython"
${AddDirectory} "$INSTDIR\Lib" ${AddDirectory} "$INSTDIR\Lib"
${AddDirectory} "$INSTDIR\Lib\SPython"
${AddDirectory} "$INSTDIR\Highlighting" ${AddDirectory} "$INSTDIR\Highlighting"
${AddDirectory} "$INSTDIR\PT4" ${AddDirectory} "$INSTDIR\PT4"
${AddDirectory} "$INSTDIR\Ico" ${AddDirectory} "$INSTDIR\Ico"

View file

@ -1,7 +1,7 @@
uses uses
// SPython // SPython
//SPythonSystem, SPythonHidden, //SPythonSystem, SPythonHidden,
time1, time1, random1,
SPythonSystemPys, itertools, math SPythonSystemPys, itertools, math
; ;

View file

@ -180,13 +180,6 @@
File ..\bin\Lib\Tasks1Arr.pcu File ..\bin\Lib\Tasks1Arr.pcu
File ..\bin\Lib\WPF.pcu File ..\bin\Lib\WPF.pcu
File ..\bin\Lib\SPythonHidden.pcu
File ..\bin\Lib\SPythonSystem.pcu
File ..\bin\Lib\time1.pcu
File ..\bin\Lib\SPythonSystemPys.pcu
File ..\bin\Lib\itertools.pcu
File ..\bin\Lib\math.pcu
File ..\bin\Lib\PABCRtl.dll File ..\bin\Lib\PABCRtl.dll
File ..\bin\Lib\HelixToolkit.Wpf.dll File ..\bin\Lib\HelixToolkit.Wpf.dll
File ..\bin\Lib\HelixToolkit.dll File ..\bin\Lib\HelixToolkit.dll
@ -280,14 +273,6 @@
${AddFile} "Tasks1Arr.pcu" ${AddFile} "Tasks1Arr.pcu"
${AddFile} "WPF.pcu" ${AddFile} "WPF.pcu"
;SPython
${AddFile} "SPythonHidden.pcu"
${AddFile} "SPythonSystem.pcu"
${AddFile} "time1.pcu"
${AddFile} "SPythonSystemPys.pcu"
${AddFile} "itertools.pcu"
${AddFile} "math.pcu"
${AddFile} "turtle.png" ${AddFile} "turtle.png"
${AddFile} "PABCRtl.dll" ${AddFile} "PABCRtl.dll"
@ -299,6 +284,27 @@
${AddFile} "PABCRtl.pdb" ${AddFile} "PABCRtl.pdb"
;SPython
Delete "$INSTDIR\Lib\SPython\*.pas"
Delete "$INSTDIR\Lib\SPython\*.pys"
SetOutPath "$INSTDIR\Lib\SPython"
File ..\bin\Lib\SPython\SPythonHidden.pcu
File ..\bin\Lib\SPython\SPythonSystem.pcu
File ..\bin\Lib\SPython\SPythonSystemPys.pcu
File ..\bin\Lib\SPython\time1.pcu
File ..\bin\Lib\SPython\random1.pcu
File ..\bin\Lib\SPython\itertools.pcu
File ..\bin\Lib\SPython\math.pcu
${AddFile} "SPythonHidden.pcu"
${AddFile} "SPythonSystem.pcu"
${AddFile} "SPythonSystemPys.pcu"
${AddFile} "time1.pcu"
${AddFile} "random1.pcu"
${AddFile} "itertools.pcu"
${AddFile} "math.pcu"
SetOutPath "$INSTDIR\Doc" SetOutPath "$INSTDIR\Doc"
File ..\doc\NumLibABC.pdf File ..\doc\NumLibABC.pdf
${AddFile} "NumLibABC.pdf" ${AddFile} "NumLibABC.pdf"
@ -396,15 +402,6 @@
File ..\bin\Lib\Мозаика.pas File ..\bin\Lib\Мозаика.pas
File ..\bin\Lib\WPF.pas File ..\bin\Lib\WPF.pas
;SPython
File ..\bin\Lib\SPythonHidden.pas
File ..\bin\Lib\SPythonSystem.pas
File ..\bin\Lib\time1.pas
File ..\bin\Lib\SPythonSystemPys.pys
File ..\bin\Lib\itertools.pys
File ..\bin\Lib\math.pys
File ..\bin\Lib\__RedirectIOMode.vb File ..\bin\Lib\__RedirectIOMode.vb
File ..\bin\Lib\VBSystem.vb File ..\bin\Lib\VBSystem.vb
@ -485,19 +482,31 @@
${AddFile} "Мозаика.pas" ${AddFile} "Мозаика.pas"
${AddFile} "WPF.pas" ${AddFile} "WPF.pas"
${AddFile} "__RedirectIOMode.vb"
${AddFile} "VBSystem.vb"
;SPython ;SPython
SetOutPath "$INSTDIR\LibSource\SPython"
File ..\bin\Lib\SPython\SPythonHidden.pas
File ..\bin\Lib\SPython\SPythonSystem.pas
File ..\bin\Lib\SPython\time1.pas
File ..\bin\Lib\SPython\SPythonSystemPys.pys
File ..\bin\Lib\SPython\random1.pys
File ..\bin\Lib\SPython\itertools.pys
File ..\bin\Lib\SPython\math.pys
${AddFile} "SPythonHidden.pas" ${AddFile} "SPythonHidden.pas"
${AddFile} "SPythonSystem.pas" ${AddFile} "SPythonSystem.pas"
${AddFile} "time1.pas" ${AddFile} "time1.pas"
${AddFile} "SPythonSystemPys.pys" ${AddFile} "SPythonSystemPys.pys"
${AddFile} "random1.pys"
${AddFile} "itertools.pys" ${AddFile} "itertools.pys"
${AddFile} "math.pys" ${AddFile} "math.pys"
${AddFile} "__RedirectIOMode.vb"
${AddFile} "VBSystem.vb"
CreateDirectory "$COMMONSTARTMENU\PascalABC.NET" CreateDirectory "$COMMONSTARTMENU\PascalABC.NET"
CreateDirectory "$SMPROGRAMS\PascalABC.NET" CreateDirectory "$SMPROGRAMS\PascalABC.NET"
Push "OptimizerConversion.dll" Push "OptimizerConversion.dll"

View file

@ -8,6 +8,7 @@ using System.IO;
using VisualPascalABCPlugins; using VisualPascalABCPlugins;
using System.Threading; using System.Threading;
using Languages.Integration; using Languages.Integration;
using Languages.Facade;
namespace VisualPascalABC namespace VisualPascalABC
{ {
@ -174,10 +175,10 @@ namespace VisualPascalABC
if (standartCompiler == null) if (standartCompiler == null)
return null; return null;
string Filter = "", AllFilter = ""; string Filter = "", AllFilter = "";
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles) foreach (ILanguage lang in LanguageProvider.Instance.Languages)
{ {
Filter = Tools.MakeFilter(Filter, ssf.LanguageName, ssf.Extensions); Filter = Tools.MakeFilter(Filter, lang.Name, lang.FilesExtensions);
AllFilter = Tools.MakeAllFilter(AllFilter, ssf.LanguageName, ssf.Extensions); AllFilter = Tools.MakeAllFilter(AllFilter, lang.Name, lang.FilesExtensions);
} }
Filter += "Программы на C# (*.cs)|*.cs|"; Filter += "Программы на C# (*.cs)|*.cs|";
AllFilter += "*.cs;"; AllFilter += "*.cs;";
@ -390,8 +391,9 @@ namespace VisualPascalABC
if (!(defaultCompilerType == PascalABCCompiler.CompilerType.Remote) || (standartCompiler.State == PascalABCCompiler.CompilerState.Ready && (remoteCompiler != null && remoteCompiler.State == PascalABCCompiler.CompilerState.Ready))) if (!(defaultCompilerType == PascalABCCompiler.CompilerType.Remote) || (standartCompiler.State == PascalABCCompiler.CompilerState.Ready && (remoteCompiler != null && remoteCompiler.State == PascalABCCompiler.CompilerState.Ready)))
StartingCompleted = true; StartingCompleted = true;
AddCompilerTextToCompilerMessages(sender, VECStringResources.Get("SUPPORTED_LANGUAGES") + Environment.NewLine); AddCompilerTextToCompilerMessages(sender, VECStringResources.Get("SUPPORTED_LANGUAGES") + Environment.NewLine);
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles) foreach (ILanguage lang in LanguageProvider.Instance.Languages)
AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"), ssf) + Environment.NewLine); AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"),
PascalABCCompiler.FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions) + Environment.NewLine));
if (StartingCompleted) if (StartingCompleted)
{ {
ChangeVisualEnvironmentState(VisualEnvironmentState.FinishCompilerLoading, standartCompiler); ChangeVisualEnvironmentState(VisualEnvironmentState.FinishCompilerLoading, standartCompiler);

View file

@ -1,12 +1,13 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using Languages.Facade;
using Languages.Integration;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using System.IO;
using VisualPascalABCPlugins; using VisualPascalABCPlugins;
using Languages.Integration;
namespace VisualPascalABC namespace VisualPascalABC
{ {
@ -172,10 +173,10 @@ namespace VisualPascalABC
if (standartCompiler == null) if (standartCompiler == null)
return null; return null;
string Filter = "", AllFilter = ""; string Filter = "", AllFilter = "";
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles) foreach (ILanguage lang in LanguageProvider.Instance.Languages)
{ {
Filter = Tools.MakeFilter(Filter, ssf.LanguageName, ssf.Extensions); Filter = Tools.MakeFilter(Filter, lang.Name, lang.FilesExtensions);
AllFilter = Tools.MakeAllFilter(AllFilter, ssf.LanguageName, ssf.Extensions); AllFilter = Tools.MakeAllFilter(AllFilter, lang.Name, lang.FilesExtensions);
} }
Filter += "Программы на C# (*.cs)|*.cs|"; Filter += "Программы на C# (*.cs)|*.cs|";
AllFilter += "*.cs;"; AllFilter += "*.cs;";
@ -377,8 +378,9 @@ namespace VisualPascalABC
if (!(defaultCompilerType == PascalABCCompiler.CompilerType.Remote) || (standartCompiler.State == PascalABCCompiler.CompilerState.Ready && (remoteCompiler != null && remoteCompiler.State == PascalABCCompiler.CompilerState.Ready))) if (!(defaultCompilerType == PascalABCCompiler.CompilerType.Remote) || (standartCompiler.State == PascalABCCompiler.CompilerState.Ready && (remoteCompiler != null && remoteCompiler.State == PascalABCCompiler.CompilerState.Ready)))
StartingCompleted = true; StartingCompleted = true;
AddCompilerTextToCompilerMessages(sender, VECStringResources.Get("SUPPORTED_LANGUAGES") + Environment.NewLine); AddCompilerTextToCompilerMessages(sender, VECStringResources.Get("SUPPORTED_LANGUAGES") + Environment.NewLine);
foreach (PascalABCCompiler.SupportedSourceFile ssf in standartCompiler.SupportedSourceFiles) foreach (ILanguage lang in LanguageProvider.Instance.Languages)
AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"), ssf) + Environment.NewLine); AddCompilerTextToCompilerMessages(sender, string.Format(VECStringResources.Get("CM_LANGUAGE_{0}"),
PascalABCCompiler.FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions) + Environment.NewLine));
if (StartingCompleted) if (StartingCompleted)
{ {
ChangeVisualEnvironmentState(VisualEnvironmentState.FinishCompilerLoading, standartCompiler); ChangeVisualEnvironmentState(VisualEnvironmentState.FinishCompilerLoading, standartCompiler);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,380 +0,0 @@
unit GraphABCHelper;
//#apptype windows
#reference 'System.Windows.Forms.dll'
#reference 'System.Drawing.dll'
#savepcu false
interface
uses System.Drawing;
type Color = System.Drawing.Color;
// Primitives
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillCircle(x,y,r: integer; gr: Graphics);
procedure DrawCircle(x,y,r: integer; gr: Graphics);
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure Circle(x,y,r: integer; gr: Graphics);
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPolygon(a: array of Point; gr: Graphics);
procedure FillPolygon(a: array of Point; gr: Graphics);
procedure Polygon(a: array of Point; gr: Graphics);
procedure Polyline(a: array of Point; gr: Graphics);
procedure Curve(a: array of Point; gr: Graphics);
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
procedure FillClosedCurve(a: array of Point; gr: Graphics);
procedure ClosedCurve(a: array of Point; gr: Graphics);
procedure TextOut(x,y: integer; s: string; gr: Graphics);
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
function ImageIntersect(b1,b2: Bitmap): boolean;
var
CurrentTextBrush: SolidBrush;
implementation
uses System, System.Drawing, System.Drawing.Drawing2D, GraphABC;
var
sf: StringFormat;
ColorLinePen: System.Drawing.Pen;
function ImageIntersect(b1,b2: Bitmap): boolean;
// Предполагается, что b1 и b2 - одного размера
type
RGB = record
r,g,b: byte;
end;
PRGB = ^uint32;
label 1;
var
ptr1,ptr2: pointer;
iptr1,iptr2: integer;
p1,p2: PRGB;
rect: System.Drawing.Rectangle;
bmpData1,bmpData2: System.Drawing.Imaging.BitmapData;
begin
rect := new System.Drawing.Rectangle(0,0,b1.Width,b1.Height);
bmpData1 := b1.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b1.PixelFormat);
ptr1 := bmpData1.Scan0.ToPointer;
iptr1 := integer(ptr1);
bmpData2 := b2.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b2.PixelFormat);
ptr2 := bmpData2.Scan0.ToPointer;
iptr2 := integer(ptr2);
var pixelFormatSize := Image.GetPixelFormatSize(b1.PixelFormat) div 8;
var Offset := bmpData1.stride - b1.Width * pixelFormatSize;
Result := False;
for var y:=0 to b1.Height-1 do
begin
for var x:=0 to b1.Width-1 do
begin
p1 := PRGB(pointer(iptr1));
p2 := PRGB(pointer(iptr2));
//writeln(p1^.R,' ',p1^.G,' ',p1^.B,' ',p2^.R,' ',p2^.G,' ',p2^.B);
// if ((p1^.R and p1^.G and p1^.B)<>$FF) and ((p2^.R and p2^.G and p2^.B)<>$FF) then
if (p1^<>$FFFFFFFF) and (p2^<>$FFFFFFFF) then
begin
Result := True;
goto 1;
end;
iptr1 += pixelFormatSize;
iptr2 += pixelFormatSize;
end;
iptr1 += Offset;
iptr2 += Offset;
end;
1:
b2.UnlockBits(bmpData1);
b1.UnlockBits(bmpData1);
end;
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
var
w,h,stride,padding,pixelFormatSize: integer;
ptr,start: System.IntPtr;
rect: System.Drawing.Rectangle;
bmpData: System.Drawing.Imaging.BitmapData;
begin
w := b.Width;
h := b.Height;
rect := new System.Drawing.Rectangle(0,0,w,h);
bmpData := b.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b.PixelFormat);
ptr := bmpData.Scan0;
b.UnlockBits(bmpData);
pixelFormatSize := Image.GetPixelFormatSize(b.PixelFormat) div 8;
start := (System.IntPtr)(integer(ptr) + w * pixelFormatSize * r.Y + r.X * pixelFormatSize);
stride := w * pixelFormatSize;
padding := stride mod 4;
if padding<>0 then
stride := stride + 4 - padding; //pad out to multiple of 4
Result := new Bitmap(r.Width,r.Height,stride,b.PixelFormat,start);
end;
procedure Swap(var x1,x2: integer);
var t: integer;
begin
t := x1;
x1 := x2;
x2 := t;
end;
// Graphics Primitives
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
begin
ColorLinePen.Color := c;
gr.DrawLine(ColorLinePen,x1,y1,x2,y2);
end;
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
begin
gr.DrawLine(Pen.NETPen,x1,y1,x2,y2);
end;
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
var sm: SmoothingMode;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
sm := gr.SmoothingMode;
gr.SmoothingMode := SmoothingMode.None;
if Brush.NETBrush<>nil then
gr.FillRectangle(Brush.NETBrush,x1,y1,x2-x1,y2-y1);
gr.SmoothingMode := sm;
end;
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
begin
FillRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawRectangle(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRectangle(x1,y1,x2-1,y2-1,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawEllipse(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.FillEllipse(Brush.NETBrush,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillEllipse(x1,y1,x2,y2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawEllipse(x1,y1,x2,y2,gr);
end;
procedure DrawCircle(x,y,r: integer; gr: Graphics);
begin
gr.DrawEllipse(Pen.NETPen,x-r,y-r,x+r,y+r);
end;
procedure FillCircle(x,y,r: integer; gr: Graphics);
begin
gr.FillEllipse(Brush.NETBrush,x-r,y-r,x+r,y+r);
end;
procedure Circle(x,y,r: integer; gr: Graphics);
begin
FillCircle(x,y,r,gr);
DrawCircle(x,y,r,gr);
end;
function CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h: integer): GraphicsPath;
var xx,yy: integer;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
xx := w div 2;
yy := h div 2;
Result := new GraphicsPath();
Result.AddLine(x1 + xx, y1, x2 - xx, y1);
Result.AddArc(x2 - w - 1, y1, w, h, 270, 90);
Result.AddLine(x2 - 1, y1 + yy, x2 - 1, y2 - yy);
Result.AddArc(x2 - w - 1, y2 - h - 1, w, h, 0, 90);
Result.AddLine(x2 - xx, y2 - 1, x1 + xx, y2 - 1);
Result.AddArc(x1, y2 - h - 1, w, h, 90, 90);
Result.AddLine(x1, y2 - yy, x1, y1 + yy);
Result.AddArc(x1, y1, w, h, 180, 90);
Result.CloseFigure();
end;
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.DrawPath(Pen.NETPen, path);
path.Dispose;
end;
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.FillPath(Brush.NETBrush, path);
path.Dispose;
end;
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRoundRect(x1,y1,x2,y2,w,h,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRoundRect(x1,y1,x2,y2,w,h,gr);
end;
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawArc(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawPie(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.FillPie(Brush.NETBrush,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPie(x,y,r,a1,a2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPie(x,y,r,a1,a2,gr);
end;
procedure DrawPolygon(a: array of Point; gr: Graphics);
begin
gr.DrawPolygon(Pen.NETPen,a);
end;
procedure FillPolygon(a: array of Point; gr: Graphics);
begin
gr.FillPolygon(Brush.NETBrush,a);
end;
procedure Polygon(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPolygon(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPolygon(a,gr);
end;
procedure Polyline(a: array of Point; gr: Graphics);
begin
gr.DrawLines(Pen.NETPen,a);
end;
procedure Curve(a: array of Point; gr: Graphics);
begin
gr.DrawCurve(Pen.NETPen,a);
end;
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
begin
gr.DrawClosedCurve(Pen.NETPen,a);
end;
procedure FillClosedCurve(a: array of Point; gr: Graphics);
begin
gr.FillClosedCurve(Brush.NETBrush,a);
end;
procedure ClosedCurve(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillClosedCurve(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawClosedCurve(a,gr);
end;
procedure TextOut(x,y: integer; s: string; gr: Graphics);
var sz: SizeF;
begin
sz := gr.MeasureString(s,Font.NETFont,0,sf);
if Brush.NETBrush <> nil then
FillRectangle(x,y,x+round(sz.Width),y+round(sz.Height)+1,gr);
gr.DrawString(s,Font.NETFont,CurrentTextBrush,x,y,sf);
end;
initialization
sf := new StringFormat(StringFormat.GenericTypographic);
sf.FormatFlags := StringFormatFlags.MeasureTrailingSpaces;
CurrentTextBrush := new SolidBrush(System.Drawing.Color.Black);
ColorLinePen := new System.Drawing.Pen(System.Drawing.Color.Black);
end.

File diff suppressed because it is too large Load diff

View file

@ -1,380 +0,0 @@
unit GraphABCHelper;
//#apptype windows
#reference 'System.Windows.Forms.dll'
#reference 'System.Drawing.dll'
#savepcu false
interface
uses System.Drawing;
type Color = System.Drawing.Color;
// Primitives
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure FillCircle(x,y,r: integer; gr: Graphics);
procedure DrawCircle(x,y,r: integer; gr: Graphics);
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
procedure Circle(x,y,r: integer; gr: Graphics);
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
procedure DrawPolygon(a: array of Point; gr: Graphics);
procedure FillPolygon(a: array of Point; gr: Graphics);
procedure Polygon(a: array of Point; gr: Graphics);
procedure Polyline(a: array of Point; gr: Graphics);
procedure Curve(a: array of Point; gr: Graphics);
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
procedure FillClosedCurve(a: array of Point; gr: Graphics);
procedure ClosedCurve(a: array of Point; gr: Graphics);
procedure TextOut(x,y: integer; s: string; gr: Graphics);
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
function ImageIntersect(b1,b2: Bitmap): boolean;
var
CurrentTextBrush: SolidBrush;
implementation
uses System, System.Drawing, System.Drawing.Drawing2D, GraphABC;
var
sf: StringFormat;
ColorLinePen: System.Drawing.Pen;
function ImageIntersect(b1,b2: Bitmap): boolean;
// Предполагается, что b1 и b2 - одного размера
type
RGB = record
r,g,b: byte;
end;
PRGB = ^uint32;
label 1;
var
ptr1,ptr2: pointer;
iptr1,iptr2: integer;
p1,p2: PRGB;
rect: System.Drawing.Rectangle;
bmpData1,bmpData2: System.Drawing.Imaging.BitmapData;
begin
rect := new System.Drawing.Rectangle(0,0,b1.Width,b1.Height);
bmpData1 := b1.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b1.PixelFormat);
ptr1 := bmpData1.Scan0.ToPointer;
iptr1 := integer(ptr1);
bmpData2 := b2.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b2.PixelFormat);
ptr2 := bmpData2.Scan0.ToPointer;
iptr2 := integer(ptr2);
var pixelFormatSize := Image.GetPixelFormatSize(b1.PixelFormat) div 8;
var Offset := bmpData1.stride - b1.Width * pixelFormatSize;
Result := False;
for var y:=0 to b1.Height-1 do
begin
for var x:=0 to b1.Width-1 do
begin
p1 := PRGB(pointer(iptr1));
p2 := PRGB(pointer(iptr2));
//writeln(p1^.R,' ',p1^.G,' ',p1^.B,' ',p2^.R,' ',p2^.G,' ',p2^.B);
// if ((p1^.R and p1^.G and p1^.B)<>$FF) and ((p2^.R and p2^.G and p2^.B)<>$FF) then
if (p1^<>$FFFFFFFF) and (p2^<>$FFFFFFFF) then
begin
Result := True;
goto 1;
end;
iptr1 += pixelFormatSize;
iptr2 += pixelFormatSize;
end;
iptr1 += Offset;
iptr2 += Offset;
end;
1:
b2.UnlockBits(bmpData1);
b1.UnlockBits(bmpData1);
end;
function GetView(b: Bitmap; r: System.Drawing.Rectangle): Bitmap;
var
w,h,stride,padding,pixelFormatSize: integer;
ptr,start: System.IntPtr;
rect: System.Drawing.Rectangle;
bmpData: System.Drawing.Imaging.BitmapData;
begin
w := b.Width;
h := b.Height;
rect := new System.Drawing.Rectangle(0,0,w,h);
bmpData := b.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, b.PixelFormat);
ptr := bmpData.Scan0;
b.UnlockBits(bmpData);
pixelFormatSize := Image.GetPixelFormatSize(b.PixelFormat) div 8;
start := (System.IntPtr)(integer(ptr) + w * pixelFormatSize * r.Y + r.X * pixelFormatSize);
stride := w * pixelFormatSize;
padding := stride mod 4;
if padding<>0 then
stride := stride + 4 - padding; //pad out to multiple of 4
Result := new Bitmap(r.Width,r.Height,stride,b.PixelFormat,start);
end;
procedure Swap(var x1,x2: integer);
var t: integer;
begin
t := x1;
x1 := x2;
x2 := t;
end;
// Graphics Primitives
procedure Line(x1,y1,x2,y2: integer; c: Color; gr: Graphics);
begin
ColorLinePen.Color := c;
gr.DrawLine(ColorLinePen,x1,y1,x2,y2);
end;
procedure Line(x1,y1,x2,y2: integer; gr: Graphics);
begin
gr.DrawLine(Pen.NETPen,x1,y1,x2,y2);
end;
procedure FillRectangle(x1,y1,x2,y2: integer; gr: Graphics);
var sm: SmoothingMode;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
sm := gr.SmoothingMode;
gr.SmoothingMode := SmoothingMode.None;
if Brush.NETBrush<>nil then
gr.FillRectangle(Brush.NETBrush,x1,y1,x2-x1,y2-y1);
gr.SmoothingMode := sm;
end;
procedure FillRect(x1,y1,x2,y2: integer; gr: Graphics);
begin
FillRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawRectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawRectangle(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Rectangle(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRectangle(x1,y1,x2-1,y2-1,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRectangle(x1,y1,x2,y2,gr);
end;
procedure DrawEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.DrawEllipse(Pen.NETPen,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure FillEllipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
gr.FillEllipse(Brush.NETBrush,x1,y1,x2-x1-1,y2-y1-1);
end;
procedure Ellipse(x1,y1,x2,y2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillEllipse(x1,y1,x2,y2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawEllipse(x1,y1,x2,y2,gr);
end;
procedure DrawCircle(x,y,r: integer; gr: Graphics);
begin
gr.DrawEllipse(Pen.NETPen,x-r,y-r,x+r,y+r);
end;
procedure FillCircle(x,y,r: integer; gr: Graphics);
begin
gr.FillEllipse(Brush.NETBrush,x-r,y-r,x+r,y+r);
end;
procedure Circle(x,y,r: integer; gr: Graphics);
begin
FillCircle(x,y,r,gr);
DrawCircle(x,y,r,gr);
end;
function CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h: integer): GraphicsPath;
var xx,yy: integer;
begin
if x1>x2 then
Swap(x1,x2);
if y1>y2 then
Swap(y1,y2);
xx := w div 2;
yy := h div 2;
Result := new GraphicsPath();
Result.AddLine(x1 + xx, y1, x2 - xx, y1);
Result.AddArc(x2 - w - 1, y1, w, h, 270, 90);
Result.AddLine(x2 - 1, y1 + yy, x2 - 1, y2 - yy);
Result.AddArc(x2 - w - 1, y2 - h - 1, w, h, 0, 90);
Result.AddLine(x2 - xx, y2 - 1, x1 + xx, y2 - 1);
Result.AddArc(x1, y2 - h - 1, w, h, 90, 90);
Result.AddLine(x1, y2 - yy, x1, y1 + yy);
Result.AddArc(x1, y1, w, h, 180, 90);
Result.CloseFigure();
end;
procedure DrawRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.DrawPath(Pen.NETPen, path);
path.Dispose;
end;
procedure FillRoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
var path: GraphicsPath;
begin
path := CreatePathForDrawRoundRect(x1,y1,x2,y2,w,h);
gr.FillPath(Brush.NETBrush, path);
path.Dispose;
end;
procedure RoundRect(x1,y1,x2,y2,w,h: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillRoundRect(x1,y1,x2,y2,w,h,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawRoundRect(x1,y1,x2,y2,w,h,gr);
end;
procedure Arc(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawArc(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure DrawPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.DrawPie(Pen.NETPen,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure FillPie(x,y,r,a1,a2: integer; gr: Graphics);
begin
a1:=360-a1;
a2:=360-a2;
if a2<a1 then
Swap(a1,a2);
gr.FillPie(Brush.NETBrush,x-r,y-r,2*r,2*r,a1,a2-a1);
end;
procedure Pie(x,y,r,a1,a2: integer; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPie(x,y,r,a1,a2,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPie(x,y,r,a1,a2,gr);
end;
procedure DrawPolygon(a: array of Point; gr: Graphics);
begin
gr.DrawPolygon(Pen.NETPen,a);
end;
procedure FillPolygon(a: array of Point; gr: Graphics);
begin
gr.FillPolygon(Brush.NETBrush,a);
end;
procedure Polygon(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillPolygon(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawPolygon(a,gr);
end;
procedure Polyline(a: array of Point; gr: Graphics);
begin
gr.DrawLines(Pen.NETPen,a);
end;
procedure Curve(a: array of Point; gr: Graphics);
begin
gr.DrawCurve(Pen.NETPen,a);
end;
procedure DrawClosedCurve(a: array of Point; gr: Graphics);
begin
gr.DrawClosedCurve(Pen.NETPen,a);
end;
procedure FillClosedCurve(a: array of Point; gr: Graphics);
begin
gr.FillClosedCurve(Brush.NETBrush,a);
end;
procedure ClosedCurve(a: array of Point; gr: Graphics);
begin
if Brush.NETBrush <> nil then
FillClosedCurve(a,gr);
if Pen.NETPen.DashStyle <> DashStyle.Custom then
DrawClosedCurve(a,gr);
end;
procedure TextOut(x,y: integer; s: string; gr: Graphics);
var sz: SizeF;
begin
sz := gr.MeasureString(s,Font.NETFont,0,sf);
if Brush.NETBrush <> nil then
FillRectangle(x,y,x+round(sz.Width),y+round(sz.Height)+1,gr);
gr.DrawString(s,Font.NETFont,CurrentTextBrush,x,y,sf);
end;
initialization
sf := new StringFormat(StringFormat.GenericTypographic);
sf.FormatFlags := StringFormatFlags.MeasureTrailingSpaces;
CurrentTextBrush := new SolidBrush(System.Drawing.Color.Black);
ColorLinePen := new System.Drawing.Pen(System.Drawing.Color.Black);
end.

View file

@ -1,11 +0,0 @@
cd ABCObjects
..\..\..\pabcnetc.exe ABCObjects.pas
cd ..
cd GraphABC
..\..\..\pabcnetc.exe GraphABC.pas
cd ..

Binary file not shown.

View file

@ -42,10 +42,13 @@ begin
Result := new LanguageTestsInfo(languageInformation.Name, languageInformation.FilesExtensions, languageInformation.CommentSymbol); Result := new LanguageTestsInfo(languageInformation.Name, languageInformation.FilesExtensions, languageInformation.CommentSymbol);
end; end;
function GetLibDir: string; function GetLibDir(languageName : string): string;
begin begin
var dir := Path.GetDirectoryName(GetEXEFileName()); var dir := Path.GetDirectoryName(GetEXEFileName());
Result := dir + PathSeparator + 'Lib'; if languageName <> 'PascalABC.NET' then
Result := dir + PathSeparator + 'Lib' + PathSeparator + languageName
else
Result := dir + PathSeparator + 'Lib';
end; end;
function GetFilesByExtensions(path: string; extensions: array of string; searchOption: SearchOption := System.IO.SearchOption.TopDirectoryOnly): array of string; function GetFilesByExtensions(path: string; extensions: array of string; searchOption: SearchOption := System.IO.SearchOption.TopDirectoryOnly): array of string;
@ -454,7 +457,7 @@ end;
procedure CopyLibFiles; procedure CopyLibFiles;
begin begin
var files := GetFilesByExtensions(GetLibDir(), CurrentLanguageInfo.languageExtensions); var files := GetFilesByExtensions(GetLibDir(CurrentLanguageInfo.languageName), CurrentLanguageInfo.languageExtensions);
foreach f: string in files do foreach f: string in files do
begin begin
&File.Copy(f, TestSuiteDir + PathSeparator + 'CompilationSamples' + PathSeparator + Path.GetFileName(f), true); &File.Copy(f, TestSuiteDir + PathSeparator + 'CompilationSamples' + PathSeparator + Path.GetFileName(f), true);
@ -482,7 +485,7 @@ end;
begin begin
//DeletePABCSystemPCU; //DeletePABCSystemPCU;
try try
Languages.Integration.LanguageIntegrator.LoadStandardLanguages(); Languages.Integration.LanguageIntegrator.LoadAllLanguages();
TestSuiteDir := System.Environment.CurrentDirectory; TestSuiteDir := System.Environment.CurrentDirectory;

View file

@ -6,6 +6,7 @@ using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Globalization; using System.Globalization;
using Languages.Facade;
namespace PascalABCCompiler namespace PascalABCCompiler
{ {
@ -370,17 +371,17 @@ namespace PascalABCCompiler
//GC.Collect(); //GC.Collect();
WriteColorText(Compiler.Banner + "\nCopyright (c) 2005-2026 by Ivan Bondarev, Stanislav Mikhalkovich\n", ConsoleColor.Green); WriteColorText(Compiler.Banner + "\nCopyright (c) 2005-2026 by Ivan Bondarev, Stanislav Mikhalkovich\n", ConsoleColor.Green);
Console.WriteLine("OK {0}ms", (DateTime.Now - ldt).TotalMilliseconds); Console.WriteLine("OK {0}ms", (DateTime.Now - ldt).TotalMilliseconds);
if (Compiler.SupportedSourceFiles.Length == 0) if (LanguageProvider.Instance.Languages.Count == 0)
WriteColorText(StringResourcesGet("ERROR_PARSERS_NOT_FOUND")+Environment.NewLine, ConsoleColor.Red); WriteColorText(StringResourcesGet("ERROR_PARSERS_NOT_FOUND")+Environment.NewLine, ConsoleColor.Red);
Compiler.InternalDebug.SkipPCUErrors = false; Compiler.InternalDebug.SkipPCUErrors = false;
} }
public static void ShowConnectedParsers() public static void ShowConnectedParsers()
{ {
if (Compiler.SupportedSourceFiles.Length > 0) if (LanguageProvider.Instance.Languages.Count > 0)
{ {
Console.Write(StringResourcesGet("CONNECTED_PARSERS")); Console.Write(StringResourcesGet("CONNECTED_PARSERS"));
foreach (PascalABCCompiler.SupportedSourceFile ssf in Compiler.SupportedSourceFiles) foreach (ILanguage lang in LanguageProvider.Instance.Languages)
Console.Write(ssf+"; "); Console.Write(FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions)+"; ");
Console.WriteLine(); Console.WriteLine();
} }
} }

View file

@ -28,16 +28,16 @@ namespace PascalABCCompiler
return StringResources.Get(StringsPrefix + Key); return StringResources.Get(StringsPrefix + Key);
} }
public static void ShowConnectedParsers() /*public static void ShowConnectedParsers()
{ {
if (Compiler.SupportedSourceFiles.Length > 0) if (LanguageProvider.Instance.Languages.Count > 0)
{ {
Console.Write(StringResourcesGet("CONNECTED_PARSERS")); Console.Write(StringResourcesGet("CONNECTED_PARSERS"));
foreach (PascalABCCompiler.SupportedSourceFile ssf in Compiler.SupportedSourceFiles) foreach (ILanguage lang in LanguageProvider.Instance.Languages)
Console.Write(ssf+"; "); Console.Write(FormatTools.LanguageAndExtensionsFormatted(lang.Name, lang.FilesExtensions)+"; ");
Console.WriteLine(); Console.WriteLine();
} }
} }*/
public static bool CheckAndSplitDirective(string directive, out string name, out string value) public static bool CheckAndSplitDirective(string directive, out string name, out string value)
{ {