Skip to content

Commit b5070ff

Browse files
committed
#207 - refactor ExpressionInstructionProvider and add unit tests for WithExpression handling
1 parent c8b62f6 commit b5070ff

File tree

4 files changed

+105
-11
lines changed

4 files changed

+105
-11
lines changed

src/Application/HydraScript.Application.CodeGeneration/Visitors/ExpressionInstructionProvider.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ public AddressedInstructions Visit(ObjectLiteral visitable)
8080
var result = new AddressedInstructions { createObject };
8181

8282
var propInstructions = visitable.AsValueEnumerable()
83-
.SelectMany(property => property.Accept(This));
84-
foreach (var propInstruction in propInstructions)
85-
result.Add(propInstruction);
83+
.SelectMany(property => property.Accept(This))
84+
.ToList();
85+
result.AddRange(propInstructions);
8686

8787
return result;
8888
}
@@ -162,19 +162,24 @@ public AddressedInstructions Visit(CastAsExpression visitable)
162162

163163
public AddressedInstructions Visit(WithExpression visitable)
164164
{
165-
if (visitable is { Expression: PrimaryExpression, ComputedCopiedProperties.Count: 0 })
166-
return [];
167-
168165
var objectId = visitable.ObjectLiteral.Id;
169166
var createObject = new CreateObject(objectId);
170167

171168
var result = new AddressedInstructions { createObject };
172169

170+
if (visitable is { Expression: ObjectLiteral left, ObjectLiteral: {} right })
171+
{
172+
result.AddRange(left.AsValueEnumerable().Concat(right)
173+
.SelectMany(property => property.Accept(This))
174+
.ToList());
175+
return result;
176+
}
177+
173178
var propInstructions = visitable.ObjectLiteral
174179
.AsValueEnumerable()
175-
.SelectMany(property => property.Accept(This));
176-
foreach (var propInstruction in propInstructions)
177-
result.Add(propInstruction);
180+
.SelectMany(property => property.Accept(This))
181+
.ToList();
182+
result.AddRange(propInstructions);
178183

179184
if (visitable.ComputedCopiedProperties.Count is 0)
180185
return result;

src/Domain/HydraScript.Domain.BackEnd/AddressedInstructions.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private void AddWithAddress(IExecutableInstruction instruction, IAddress newAddr
4646
last?.Value.Next = newAddress;
4747

4848
var newNode = _addresses.AddLast(newAddress);
49-
49+
5050
_addressToNode.Add(newAddress, newNode);
5151
_instructions.Add(newNode, instruction);
5252
}
@@ -59,11 +59,19 @@ public void AddRange(AddressedInstructions instructions)
5959
}
6060
}
6161

62+
public void AddRange(IReadOnlyList<IExecutableInstruction> instructions)
63+
{
64+
for (var i = 0; i < instructions.Count; i++)
65+
{
66+
Add(instructions[i]);
67+
}
68+
}
69+
6270
public void Remove(IExecutableInstruction instruction)
6371
{
6472
var address = instruction.Address;
6573
var nodeToRemove = _addressToNode[address];
66-
74+
6775
var prev = nodeToRemove.Previous;
6876
prev?.Value.Next = nodeToRemove.Next?.Value!;
6977

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using HydraScript.Application.CodeGeneration.Impl;
2+
using HydraScript.Application.CodeGeneration.Visitors;
3+
using HydraScript.Domain.BackEnd;
4+
using HydraScript.Domain.FrontEnd.Parser;
5+
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Expressions;
6+
7+
namespace HydraScript.UnitTests.Application;
8+
9+
public class ExpressionInstructionProviderTests(ITestOutputHelper testOutputHelper)
10+
{
11+
private readonly ExpressionInstructionProvider _expressionInstructionProvider = new(new ValueDtoConverter());
12+
13+
[Theory, ClassData(typeof(WithExpressionData))]
14+
public void Visit_WithExpression_ExpectedInstructions(
15+
IAbstractSyntaxTree ast,
16+
AddressedInstructions expected)
17+
{
18+
var withExpression = ast.Root.GetAllNodes().OfType<WithExpression>().Single();
19+
var result = _expressionInstructionProvider.Visit(withExpression);
20+
result.ToString().Should().Be(expected.ToString());
21+
testOutputHelper.WriteLine(expected.ToString());
22+
}
23+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using HydraScript.Domain.BackEnd;
2+
using HydraScript.Domain.BackEnd.Impl.Instructions.WithAssignment.ComplexData.Create;
3+
using HydraScript.Domain.BackEnd.Impl.Instructions.WithAssignment.ComplexData.Write;
4+
using HydraScript.Domain.BackEnd.Impl.Values;
5+
using HydraScript.Domain.FrontEnd.Parser;
6+
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast;
7+
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Declarations;
8+
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Expressions;
9+
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Expressions.ComplexLiterals;
10+
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Expressions.PrimaryExpressions;
11+
12+
namespace HydraScript.UnitTests.Application;
13+
14+
public sealed class WithExpressionData : TheoryData<IAbstractSyntaxTree, AddressedInstructions>
15+
{
16+
public WithExpressionData()
17+
{
18+
// let obj = {x: 1;} with {}
19+
Add(
20+
new AbstractSyntaxTree(
21+
new AssignmentExpression(
22+
new MemberExpression(new IdentifierReference("obj")),
23+
new WithExpression(
24+
new ObjectLiteral([
25+
new Property(
26+
new IdentifierReference("x"),
27+
new Literal(new TypeIdentValue(new IdentifierReference("number")), 1,
28+
"(1, 15)-(1, 16)"))
29+
]),
30+
new ObjectLiteral([])))),
31+
[
32+
new CreateObject("obj"),
33+
new DotAssignment("obj", new Constant("x"), new Constant(1))
34+
]);
35+
36+
// let copyFrom = {x: 0;}
37+
// let obj = copyFrom with {x: 1;}
38+
Add(
39+
new AbstractSyntaxTree(
40+
new AssignmentExpression(
41+
new MemberExpression(new IdentifierReference("obj")),
42+
new WithExpression(
43+
new IdentifierReference("copyFrom"),
44+
new ObjectLiteral([
45+
new Property(
46+
new IdentifierReference("x"),
47+
new Literal(new TypeIdentValue(new IdentifierReference("number")), 1,
48+
"(1, 15)-(1, 16)"))
49+
]))
50+
{
51+
ComputedCopiedProperties = []
52+
})),
53+
[
54+
new CreateObject("obj"),
55+
new DotAssignment("obj", new Constant("x"), new Constant(1))
56+
]);
57+
}
58+
}

0 commit comments

Comments
 (0)