Skip to content

Commit 90cb7e7

Browse files
authored
Merge pull request EvilBeaver#1576 from EvilBeaver/feature/deep-annotations
Аннотация как значение параметра Аннотации
2 parents a5adff6 + 89cdeef commit 90cb7e7

File tree

15 files changed

+298
-80
lines changed

15 files changed

+298
-80
lines changed

src/OneScript.Core/Commons/Utils.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,20 @@ public static void ForEach<T>(this IEnumerable<T> input, Action<T> action)
3535
action(data);
3636
}
3737
}
38-
38+
public static string NameAndValuePresentation(string name, object value)
39+
{
40+
var list = new List<string>();
41+
if (!string.IsNullOrEmpty(name))
42+
{
43+
list.Add(name);
44+
}
45+
if (value != null)
46+
{
47+
list.Add(value.ToString());
48+
}
49+
return string.Join("=", list);
50+
}
51+
3952
public static bool IsMonoRuntime => Type.GetType("Mono.Runtime") != null;
4053

4154
}

src/OneScript.Core/Contexts/BslAnnotationAttribute.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ This Source Code Form is subject to the terms of the
55
at http://mozilla.org/MPL/2.0/.
66
----------------------------------------------------------*/
77

8+
using OneScript.Commons;
9+
using OneScript.Values;
810
using System;
911
using System.Collections.Generic;
10-
using OneScript.Values;
1112

1213
namespace OneScript.Contexts
1314
{
@@ -37,7 +38,7 @@ public void SetParameters(IEnumerable<BslAnnotationParameter> parameters)
3738

3839
public class BslAnnotationParameter
3940
{
40-
public BslAnnotationParameter(string name, BslPrimitiveValue value)
41+
public BslAnnotationParameter(string name, BslPrimitiveValue value = null)
4142
{
4243
Name = name;
4344
Value = value;
@@ -47,6 +48,10 @@ public BslAnnotationParameter(string name, BslPrimitiveValue value)
4748

4849
public BslPrimitiveValue Value { get; }
4950

50-
public int ConstantValueIndex { get; set; } = -1;
51+
public override string ToString()
52+
{
53+
return Utils.NameAndValuePresentation(Name, Value);
54+
}
55+
5156
}
5257
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
8+
using System;
9+
using OneScript.Contexts;
10+
using OneScript.Exceptions;
11+
using OneScript.Localization;
12+
using OneScript.Types;
13+
using System.Collections.Generic;
14+
using System.Text;
15+
16+
namespace OneScript.Values
17+
{
18+
public sealed class BslAnnotationValue : BslPrimitiveValue
19+
{
20+
public BslAnnotationValue(string name) {
21+
Name = name;
22+
}
23+
24+
public string Name { get; }
25+
26+
public List<BslAnnotationParameter> Parameters { get; } = new List<BslAnnotationParameter>();
27+
28+
29+
public override int CompareTo(BslValue other) {
30+
var msg = new BilingualString("Сравнение на больше/меньше для данного типа не поддерживается",
31+
"Comparison for less/greater is not supported for this type");
32+
33+
throw new RuntimeException(msg);
34+
}
35+
36+
public override bool Equals(BslValue other) {
37+
return ReferenceEquals(this, other);
38+
}
39+
40+
public override string ToString()
41+
{
42+
var sb = new StringBuilder("&");
43+
sb.Append(Name);
44+
if (Parameters.Count != 0)
45+
{
46+
var prefix = "(";
47+
foreach (var parameter in Parameters)
48+
{
49+
sb.Append(prefix);
50+
sb.Append(parameter);
51+
prefix = ",";
52+
}
53+
sb.Append(")");
54+
}
55+
return sb.ToString();
56+
}
57+
}
58+
}

src/OneScript.Language/SyntaxAnalysis/AstNodes/AnnotationParameterNode.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,29 @@ public AnnotationParameterNode() : base(NodeKind.AnnotationParameter)
1717

1818
protected override void OnChildAdded(BslSyntaxNode child)
1919
{
20-
var node = (TerminalNode) child;
21-
if (child.Kind == NodeKind.AnnotationParameterName)
20+
if (child.Kind == NodeKind.Annotation)
2221
{
23-
Name = node.Lexem.Content;
22+
AnnotationNode = (AnnotationNode)child;
2423
}
25-
if (child.Kind == NodeKind.AnnotationParameterValue)
24+
else
2625
{
27-
Value = node.Lexem;
26+
var node = (TerminalNode)child;
27+
if (child.Kind == NodeKind.AnnotationParameterName)
28+
{
29+
Name = node.Lexem.Content;
30+
}
31+
if (child.Kind == NodeKind.AnnotationParameterValue)
32+
{
33+
Value = node.Lexem;
34+
}
2835
}
2936
}
3037

3138
public string Name { get; private set; }
3239

3340
public Lexem Value { get; private set; }
41+
42+
public AnnotationNode AnnotationNode { get; private set; }
43+
3444
}
3545
}

src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -541,13 +541,18 @@ private void BuildAnnotations()
541541
{
542542
while (_lastExtractedLexem.Type == LexemType.Annotation)
543543
{
544-
var node = new AnnotationNode(NodeKind.Annotation, _lastExtractedLexem);
544+
var node = BuildAnnotationDefinition();
545545
_annotations.Add(node);
546-
NextLexem();
547-
BuildAnnotationParameters(node);
548546
}
549547
}
550-
548+
private AnnotationNode BuildAnnotationDefinition() {
549+
var node = new AnnotationNode(NodeKind.Annotation, _lastExtractedLexem);
550+
NextLexem();
551+
BuildAnnotationParameters(node);
552+
return node;
553+
}
554+
555+
551556
private void BuildAnnotationParameters(AnnotationNode annotation)
552557
{
553558
if (_lastExtractedLexem.Token != Token.OpenPar)
@@ -599,11 +604,16 @@ private void BuildAnnotationParameter(AnnotationNode annotation)
599604

600605
private bool BuildAnnotationParamValue(AnnotationParameterNode annotationParam)
601606
{
607+
if (_lastExtractedLexem.Type == LexemType.Annotation) {
608+
var annotation = BuildAnnotationDefinition();
609+
annotationParam.AddChild(annotation);
610+
return true;
611+
}
602612
return BuildDefaultParameterValue(annotationParam, NodeKind.AnnotationParameterValue);
603613
}
604-
614+
605615
#endregion
606-
616+
607617
private void BuildCodeBatch(params Token[] endTokens)
608618
{
609619
PushStructureToken(endTokens);

src/OneScript.Native/Compiler/CompilerHelpers.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ private static IEnumerable<BslAnnotationParameter> GetAnnotationParameters(Annot
9090
private static BslAnnotationParameter MakeAnnotationParameter(AnnotationParameterNode param)
9191
{
9292
BslAnnotationParameter result;
93+
if (param.AnnotationNode != null)
94+
{
95+
var runtimeValue = new BslAnnotationValue(param.AnnotationNode.Name);
96+
foreach (var child in param.AnnotationNode.Children)
97+
{
98+
runtimeValue.Parameters.Add(MakeAnnotationParameter((AnnotationParameterNode)child));
99+
}
100+
result = new BslAnnotationParameter(param.Name, runtimeValue);
101+
}
102+
else
93103
if (param.Value.Type != LexemType.NotALexem)
94104
{
95105
var runtimeValue = ValueFromLiteral(param.Value);

src/OneScript.StandardLibrary/Reflector.cs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -163,27 +163,41 @@ private static ValueTable CreateAnnotationTable(BslAnnotationAttribute[] annotat
163163
{
164164
annotationRow.Set(annotationNameColumn, ValueFactory.Create(annotation.Name));
165165
}
166-
var parametersTable = new ValueTable();
167-
var parameterNameColumn = parametersTable.Columns.Add("Имя");
168-
var parameterValueColumn = parametersTable.Columns.Add("Значение");
169-
166+
var parametersTable = FillAnnotationParameters(annotation.Parameters);
170167
annotationRow.Set(annotationParamsColumn, parametersTable);
171-
if (annotation.Parameters.Any())
172-
{
168+
}
173169

174-
foreach (var annotationParameter in annotation.Parameters)
175-
{
176-
var parameterRow = parametersTable.Add();
177-
if (annotationParameter.Name != null)
178-
{
179-
parameterRow.Set(parameterNameColumn, ValueFactory.Create(annotationParameter.Name));
180-
}
181-
parameterRow.Set(parameterValueColumn, annotationParameter.Value);
182-
}
170+
return annotationsTable;
171+
}
172+
173+
private static ValueTable FillAnnotationParameters(IEnumerable<BslAnnotationParameter> parameters)
174+
{
175+
var parametersTable = new ValueTable();
176+
var parameterNameColumn = parametersTable.Columns.Add("Имя");
177+
var parameterValueColumn = parametersTable.Columns.Add("Значение");
178+
179+
foreach (var annotationParameter in parameters)
180+
{
181+
var parameterRow = parametersTable.Add();
182+
if (annotationParameter.Name != null)
183+
{
184+
parameterRow.Set(parameterNameColumn, ValueFactory.Create(annotationParameter.Name));
185+
}
186+
if (annotationParameter.Value is BslAnnotationValue annotationValue)
187+
{
188+
var expandedValue = EmptyAnnotationsTable();
189+
var row = expandedValue.Add();
190+
row.Set(expandedValue.Columns.FindColumnByName("Имя"), ValueFactory.Create(annotationValue.Name));
191+
row.Set(expandedValue.Columns.FindColumnByName("Параметры"), FillAnnotationParameters(annotationValue.Parameters));
192+
parameterRow.Set(parameterValueColumn, row);
193+
}
194+
else
195+
{
196+
parameterRow.Set(parameterValueColumn, annotationParameter.Value);
183197
}
184198
}
185199

186-
return annotationsTable;
200+
return parametersTable;
187201
}
188202

189203
private static bool MethodExistsForType(BslTypeValue type, string methodName)

src/ScriptEngine/Compiler/StackMachineCodeGenerator.cs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This Source Code Form is subject to the terms of the
1212
using System.Linq;
1313
using System.Reflection;
1414
using System.Runtime.CompilerServices;
15+
using System.Text;
1516
using OneScript.Compilation;
1617
using OneScript.Compilation.Binding;
1718
using OneScript.Contexts;
@@ -1237,23 +1238,35 @@ private IEnumerable<BslAnnotationParameter> GetAnnotationParameters(AnnotationNo
12371238

12381239
private BslAnnotationParameter MakeAnnotationParameter(AnnotationParameterNode param)
12391240
{
1240-
BslAnnotationParameter result;
1241+
var runtimeValue = MakeAnnotationParameterValueConstant(param);
1242+
return new BslAnnotationParameter(param.Name, runtimeValue);
1243+
}
1244+
1245+
private BslPrimitiveValue MakeAnnotationParameterValueConstant(AnnotationParameterNode param)
1246+
{
1247+
if (param.AnnotationNode != null)
1248+
{
1249+
var runtimeValue = new BslAnnotationValue(param.AnnotationNode.Name);
1250+
foreach (var child in param.AnnotationNode.Children)
1251+
{
1252+
var parameter = (AnnotationParameterNode)child;
1253+
var parameterValue = MakeAnnotationParameterValueConstant(parameter);
1254+
runtimeValue.Parameters.Add(new BslAnnotationParameter(parameter.Name, parameterValue));
1255+
}
1256+
return runtimeValue;
1257+
}
1258+
else
12411259
if (param.Value.Type != LexemType.NotALexem)
12421260
{
12431261
var constDef = CreateConstDefinition(param.Value);
12441262
var constNumber = GetConstNumber(constDef);
12451263
var runtimeValue = _module.Constants[constNumber];
1246-
result = new BslAnnotationParameter(param.Name, runtimeValue)
1247-
{
1248-
ConstantValueIndex = constNumber
1249-
};
1264+
return runtimeValue;
12501265
}
12511266
else
12521267
{
1253-
result = new BslAnnotationParameter(param.Name, null);
1268+
return null;
12541269
}
1255-
1256-
return result;
12571270
}
12581271

12591272
private IEnumerable<BslAnnotationAttribute> GetAnnotations(AnnotatableNode parent)
@@ -1302,7 +1315,7 @@ private static ConstDefinition CreateConstDefinition(in Lexem lex)
13021315
};
13031316
return cDef;
13041317
}
1305-
1318+
13061319
private int GetConstNumber(in ConstDefinition cDef)
13071320
{
13081321
var idx = _constMap.IndexOf(cDef);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
using System;
8+
9+
namespace ScriptEngine.Machine
10+
{
11+
public struct AnnotationDefinition
12+
{
13+
public string Name;
14+
public AnnotationParameter[] Parameters;
15+
public readonly int ParamCount => Parameters?.Length ?? 0;
16+
}
17+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
using OneScript.Commons;
8+
9+
namespace ScriptEngine.Machine
10+
{
11+
public struct AnnotationParameter
12+
{
13+
public string Name;
14+
15+
public IValue RuntimeValue;
16+
17+
public override readonly string ToString()
18+
{
19+
return Utils.NameAndValuePresentation(Name, RuntimeValue);
20+
}
21+
22+
}
23+
}

0 commit comments

Comments
 (0)