Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/OneScript.Core/Contexts/BslParameterInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ internal BslParameterInfo()
AttrsImpl = ParameterAttributes.In;
ClassImpl = typeof(BslValue);
}

public static BslParameterInfo Create() => new BslParameterInfo();

#region Attributes Infrastructure

Expand Down Expand Up @@ -99,6 +101,22 @@ internal void SetDefaultValue(BslPrimitiveValue val)
AttrsImpl |= ParameterAttributes.HasDefault | ParameterAttributes.Optional;
}

public void SetDefaultValueIndex(int index)
{
ConstantValueIndex = index;
AttrsImpl |= ParameterAttributes.HasDefault | ParameterAttributes.Optional;
}

public void SetByValue(bool byVal)
{
ExplicitByVal = byVal;
}

public void SetPosition(int position)
{
PositionImpl = position;
}

internal void SetOwner(MemberInfo parent)
{
MemberImpl = parent;
Expand Down
2 changes: 2 additions & 0 deletions src/OneScript.Core/Contexts/BslScriptFieldInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ internal BslScriptFieldInfo(string name)
_name = name;
}

public static BslScriptFieldInfo Create(string name = null) => new BslScriptFieldInfo(name);

public override Type DeclaringType => _declaringType;
public override string Name => _name;
public override Type ReflectedType => _declaringType;
Expand Down
6 changes: 3 additions & 3 deletions src/OneScript.Core/Contexts/Internal/IBuildableMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This Source Code Form is subject to the terms of the

namespace OneScript.Contexts.Internal
{
internal interface IBuildableMember
public interface IBuildableMember
{
void SetDeclaringType(Type type);
void SetName(string name);
Expand All @@ -21,12 +21,12 @@ internal interface IBuildableMember
void SetDispatchIndex(int index);
}

internal interface IBuildableMethod : IBuildableMember
public interface IBuildableMethod : IBuildableMember
{
void SetParameters(IEnumerable<BslParameterInfo> parameters);
}

internal interface IBuildableProperty : IBuildableMember
public interface IBuildableProperty : IBuildableMember
{
void CanRead(bool canRead);
void CanWrite(bool canWrite);
Expand Down
8 changes: 7 additions & 1 deletion src/OneScript.Language/Sources/SourceCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ public class SourceCode : ISourceCodeIndexer

private string _code = null;

internal SourceCode(string sourceName, ICodeSource source, string ownerPackageId = null)
internal SourceCode(string sourceName, ICodeSource source, string ownerPackageId = null, bool isCompiled = false)
{
_source = source;
Name = sourceName;
OwnerPackageId = ownerPackageId;
IsCompiled = isCompiled;
}

public SourceCodeIterator CreateIterator()
Expand All @@ -41,6 +42,11 @@ public SourceCodeIterator CreateIterator()
/// Идентификатор пакета-владельца. null если модуль не принадлежит библиотеке.
/// </summary>
public string OwnerPackageId { get; }

/// <summary>
/// Признак того, что модуль загружен из скомпилированного кода (.osc, .oslib)
/// </summary>
public bool IsCompiled { get; }

public string GetSourceCode()
{
Expand Down
12 changes: 11 additions & 1 deletion src/OneScript.Language/Sources/SourceCodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class SourceCodeBuilder
private ICodeSource _source;
private string _moduleName;
private string _ownerPackageId;
private bool _isCompiled;

private SourceCodeBuilder()
{
Expand All @@ -41,6 +42,15 @@ public SourceCodeBuilder WithOwnerPackage(string packageId)
_ownerPackageId = packageId;
return this;
}

/// <summary>
/// Помечает исходный код как загруженный из скомпилированного файла.
/// </summary>
public SourceCodeBuilder AsCompiled()
{
_isCompiled = true;
return this;
}

public SourceCode Build()
{
Expand All @@ -50,7 +60,7 @@ public SourceCode Build()
if (_moduleName == default)
_moduleName = _source.Location;

return new SourceCode(_moduleName, _source, _ownerPackageId);
return new SourceCode(_moduleName, _source, _ownerPackageId, _isCompiled);
}

public static SourceCodeBuilder Create() => new SourceCodeBuilder();
Expand Down
82 changes: 80 additions & 2 deletions src/ScriptEngine.HostedScript/FileSystemDependencyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ This Source Code Form is subject to the terms of the
using OneScript.Execution;
using OneScript.Localization;
using OneScript.Sources;
using ScriptEngine.Compiler.Packaged;

namespace ScriptEngine.HostedScript
{
public class FileSystemDependencyResolver : IDependencyResolver
{
public const string PREDEFINED_LOADER_FILE = "package-loader.os";
public const string COMPILED_LIBRARY_EXTENSION = ".oslib";

private readonly List<Library> _libs = new List<Library>();
private LibraryLoader _defaultLoader;
private object _defaultLoaderLocker = new object();
Expand Down Expand Up @@ -94,17 +97,31 @@ public PackageInfo Resolve(SourceCode module, string libraryName, IBslProcess pr

private PackageInfo LoadByName(string libraryName, IBslProcess process)
{
// Сначала ищем скомпилированную библиотеку (.oslib)
foreach (var path in SearchDirectories)
{
if(!Directory.Exists(path))
if (!Directory.Exists(path))
continue;

var oslibPath = Path.Combine(path, libraryName + COMPILED_LIBRARY_EXTENSION);
if (File.Exists(oslibPath))
{
return LoadCompiledLibrary(oslibPath, process);
}

var libraryPath = Path.Combine(path, libraryName);
var loadAttempt = LoadByPath(libraryPath, process);
var loadAttempt = LoadByPath(libraryPath, process);
if (loadAttempt != null)
return loadAttempt;
}

// Проверяем в корневой папке
var rootOslibPath = Path.Combine(LibraryRoot, libraryName + COMPILED_LIBRARY_EXTENSION);
if (File.Exists(rootOslibPath))
{
return LoadCompiledLibrary(rootOslibPath, process);
}

var rootPath = Path.Combine(LibraryRoot, libraryName);
return LoadByPath(rootPath, process);
}
Expand All @@ -130,6 +147,13 @@ private PackageInfo LoadByRelativePath(SourceCode module, string libraryPath, IB
realPath = libraryPath;
}

// Сначала проверяем скомпилированную библиотеку (.oslib)
var oslibPath = realPath + COMPILED_LIBRARY_EXTENSION;
if (File.Exists(oslibPath))
{
return LoadCompiledLibrary(oslibPath, process);
}

return LoadByPath(realPath, process);
}

Expand Down Expand Up @@ -277,6 +301,60 @@ private static string GetLibraryId(string libraryPath)
{
return Path.GetFullPath(libraryPath);
}

private PackageInfo LoadCompiledLibrary(string oslibPath, IBslProcess process)
{
var id = GetLibraryId(oslibPath);
var existedLib = _libs.FirstOrDefault(x => x.id == id);
if (existedLib != null)
{
if (existedLib.state == ProcessingState.Discovered)
{
string libStack = ListToStringStack(_libs, id);
throw new DependencyResolveException(
new BilingualString(
$"Ошибка загрузки библиотеки {id}. Обнаружены циклические зависимости.\n",
$"Error loading library {id}. Circular dependencies found.\n") + libStack);
}

return existedLib.loadingResult;
}

var newLib = new Library { id = id, state = ProcessingState.Discovered };
int newLibIndex = _libs.Count;

try
{
_libs.Add(newLib);

var loader = new Compiler.Packaged.LibraryLoader(Engine);
var loadedLib = loader.LoadFromFile(oslibPath, process);

// Сначала загружаем зависимости
foreach (var dep in loadedLib.Dependencies)
{
var depPackage = LoadByName(dep, process);
if (depPackage == null)
{
throw new DependencyResolveException(
new BilingualString(
$"Не найдена зависимость '{dep}' для библиотеки '{loadedLib.Name}'",
$"Dependency '{dep}' not found for library '{loadedLib.Name}'"));
}
}

var package = new PackageInfo(oslibPath, loadedLib.Name);
newLib.state = ProcessingState.Processed;
newLib.loadingResult = package;

return package;
}
catch (Exception)
{
_libs.RemoveAt(newLibIndex);
throw;
}
}

private static bool PathHasInvalidChars(string path)
{
Expand Down
34 changes: 34 additions & 0 deletions src/ScriptEngine.HostedScript/LibraryLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,5 +287,39 @@ public static void TraceLoadLibrary(string message)
SystemLogger.Write("LRE: " + message);
}
}

/// <summary>
/// Загружает библиотеку и возвращает информацию о ней с скомпилированными модулями.
/// Используется для сборки .oslib файлов.
/// </summary>
public ExternalLibraryInfo LoadLibraryWithInfo(string libraryPath, IBslProcess process)
{
var package = new PackageInfo(libraryPath, Path.GetFileName(libraryPath));
var library = new ExternalLibraryInfo(package);
_librariesInProgress.Push(new LibraryLoadingContext(library));
try
{
bool success;
if (!_customized)
{
success = DefaultProcessing(libraryPath, process);
}
else
{
success = CustomizedProcessing(libraryPath, process);
}

if (!success)
return null;

CompileDelayedModules(library, process);

return library;
}
finally
{
_librariesInProgress.Pop();
}
}
}
}
38 changes: 38 additions & 0 deletions src/ScriptEngine/Compiler/Packaged/AnnotationDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System.Collections.Generic;
using MessagePack;

namespace ScriptEngine.Compiler.Packaged
{
/// <summary>
/// DTO для сериализации аннотации
/// </summary>
[MessagePackObject]
public class AnnotationDto
{
[Key(0)]
public string Name { get; set; }

[Key(1)]
public List<AnnotationParameterDto> Parameters { get; set; }
}

/// <summary>
/// DTO для сериализации параметра аннотации
/// </summary>
[MessagePackObject]
public class AnnotationParameterDto
{
[Key(0)]
public string Name { get; set; }

[Key(1)]
public string Value { get; set; }
}
}
Loading