Skip to content

Commit

Permalink
Merge pull request #1377 from EvilBeaver/feature/global-override-1354
Browse files Browse the repository at this point in the history
Волшебная аннотация переопределения стандартного метода
  • Loading branch information
EvilBeaver authored Nov 11, 2023
2 parents ef459d7 + 1e5fbbd commit e376e13
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 11 deletions.
15 changes: 15 additions & 0 deletions src/OneScript.Core/Compilation/Binding/BindingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ This Source Code Form is subject to the terms of the
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System.Linq;
using System.Reflection;
using OneScript.Contexts;
using OneScript.Language.SyntaxAnalysis.AstNodes;
using OneScript.Runtime.Binding;
using OneScript.Values;

Expand Down Expand Up @@ -40,5 +44,16 @@ public static IFieldSymbol ToSymbol(this BslFieldInfo info)
{
return new BslFieldSymbol { Field = info };
}

public static bool IsUniqueMethod(this SymbolTable table, MethodNode astNode)
{
var isKnown = table.TryFindMethodBinding(astNode.Signature.MethodName, out _);
if (!isKnown)
{
return true;
}

return astNode.Annotations.Any(a => BslOverrideAttribute.AcceptsIdentifier(a.Name));
}
}
}
23 changes: 23 additions & 0 deletions src/OneScript.Core/Compilation/Binding/BslOverrideAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*----------------------------------------------------------
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;
using OneScript.Localization;

namespace OneScript.Compilation.Binding
{
[AttributeUsage(AttributeTargets.Method)]
public class BslOverrideAttribute : Attribute
{
public static readonly BilingualString OverrideAttributeName = new BilingualString("Переопределить", "Override");

public static bool AcceptsIdentifier(string identifier)
{
return OverrideAttributeName.ContainsString(identifier);
}
}
}
23 changes: 22 additions & 1 deletion src/OneScript.Language/Localization/BilingualString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System;
using System.Globalization;

namespace OneScript.Localization
{
public class BilingualString
public class BilingualString : IEquatable<BilingualString>
{
private static readonly CultureInfo RussianCulture;

Expand Down Expand Up @@ -67,5 +68,25 @@ public static string Localize(string russian, string english)

return russian;
}

public bool Equals(BilingualString other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Russian == other.Russian && English == other.English;
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((BilingualString)obj);
}

public override int GetHashCode()
{
return HashCode.Combine(Russian, English);
}
}
}
24 changes: 24 additions & 0 deletions src/OneScript.Language/Localization/LocalizationExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*----------------------------------------------------------
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;

namespace OneScript.Localization
{
public static class LocalizationExtensions
{
public static bool ContainsString(this BilingualString bi, string sample)
{
return ContainsString(bi, sample, StringComparison.CurrentCultureIgnoreCase);
}

public static bool ContainsString(this BilingualString bi, string sample, StringComparison comparison)
{
return bi.Russian.Equals(sample, comparison) || bi.English.Equals(sample, comparison);
}
}
}
12 changes: 9 additions & 3 deletions src/OneScript.Native/Compiler/CompilerHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This Source Code Form is subject to the terms of the
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using OneScript.Compilation.Binding;
using OneScript.Contexts;
using OneScript.Language.LexicalAnalysis;
using OneScript.Language.SyntaxAnalysis.AstNodes;
Expand Down Expand Up @@ -49,10 +50,15 @@ public static object ClrValueFromLiteral(in Lexem lex)

public static IEnumerable<Attribute> GetAnnotations(IEnumerable<AnnotationNode> annotations)
{
// Возможно будут какие-то маппинги на системные атрибуты, не только на BslAnnotation
// поэтому возвращаем Attribute[] а не BslAnnotation[]
return annotations.Select<AnnotationNode, Attribute>(a =>
{
if (BslOverrideAttribute.AcceptsIdentifier(a.Name))
{
return new BslOverrideAttribute();
}

return annotations.Select(GetBslAnnotation).ToList();
return GetBslAnnotation(a);
}).ToList();
}

public static BslAnnotationAttribute GetBslAnnotation(AnnotationNode node)
Expand Down
2 changes: 1 addition & 1 deletion src/OneScript.Native/Compiler/ModuleCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void RegisterLocalMethods(BslSyntaxNode module)
foreach (var methodNode in methodsSection.Children.Cast<MethodNode>())
{
var signature = methodNode.Signature;
if (Symbols.TryFindMethodBinding(signature.MethodName, out _))
if (!Symbols.IsUniqueMethod(methodNode))
{
AddError(LocalizedErrors.DuplicateMethodDefinition(signature.MethodName), signature.Location);
continue;
Expand Down
19 changes: 13 additions & 6 deletions src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ protected override void VisitMethod(MethodNode methodNode)
methodInfo.SetRuntimeParameters(entryPoint, GetVariableNames(methodCtx));

SymbolBinding binding;
if (!_ctx.TryFindMethodBinding(signature.MethodName, out _))
if (_ctx.IsUniqueMethod(methodNode))
{
binding = _ctx.DefineMethod(methodInfo.ToSymbol());
}
Expand Down Expand Up @@ -1103,14 +1103,21 @@ private void VisitConstant(in Lexem constant)
AddCommand(OperationCode.PushConst, num);
}

private IEnumerable<BslAnnotationAttribute> GetAnnotationAttributes(AnnotatableNode node)
private IEnumerable<Attribute> GetAnnotationAttributes(AnnotatableNode node)
{
var mappedAnnotations = new List<BslAnnotationAttribute>();
var mappedAnnotations = new List<Attribute>();
foreach (var annotation in node.Annotations)
{
var anno = new BslAnnotationAttribute(annotation.Name);
anno.SetParameters(GetAnnotationParameters(annotation));
mappedAnnotations.Add(anno);
if (BslOverrideAttribute.AcceptsIdentifier(annotation.Name))
{
mappedAnnotations.Add(new BslOverrideAttribute());
}
else
{
var anno = new BslAnnotationAttribute(annotation.Name);
anno.SetParameters(GetAnnotationParameters(annotation));
mappedAnnotations.Add(anno);
}
}

return mappedAnnotations;
Expand Down
20 changes: 20 additions & 0 deletions tests/engine-behaviors.os
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
ВсеТесты.Добавить("ТестДолжен_ПроверитьПередачуПараметровПоСсылке");
ВсеТесты.Добавить("ТестДолжен_ПроверитьСравнениеНаБольшеМеньше");
ВсеТесты.Добавить("ТестДолжен_ПроверитьНевозможностьПереопределенияГлобальногоКонтекста");
ВсеТесты.Добавить("ТестДолжен_ПроверитьВозможностьПереопределенияГлобальногоКонтекста");

Возврат ВсеТесты;

Expand Down Expand Up @@ -709,3 +710,22 @@
юТест.ПроверитьКодСОшибкой("#native" + Символы.ПС + Код, "СтрНайти");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьВозможностьПереопределенияГлобальногоКонтекста() Экспорт

Код = "&Переопределить
|Функция СтрНайти(знач Стр1, знач Стр2)
| Возврат -1;
|КонецФункции
|
|Функция Проверить() Экспорт
| Возврат СтрНайти(""1"", ""1"");
|КонецФункции";

СкриптСтек = ЗагрузитьСценарийИзСтроки(Код);
СкриптНатив = ЗагрузитьСценарийИзСтроки("#native" + Символы.ПС + Код);

юТест.ПроверитьРавенство(-1, СкриптСтек.Проверить());
юТест.ПроверитьРавенство(-1, СкриптНатив.Проверить());

КонецПроцедуры

0 comments on commit e376e13

Please sign in to comment.