Skip to content

Commit 9a594fc

Browse files
author
Rajesh Jinaga
committed
Able to set value to indexer property
1 parent 952b8e8 commit 9a594fc

16 files changed

+697
-728
lines changed

src/Simpleflow/CodeGenerator/SimpleflowCodeVisitor.VisitFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private List<Expression> GetArgumentExpressions(SimpleflowParser.FunctionContext
8585

8686
private Expression CreateFunctionParameterExpression(ParameterInfo methodParameter, SimpleflowParser.FunctionParameterContext scriptArgument)
8787
{
88-
var parameterValueContext = scriptArgument.functionParameterValue().GetChild(0);
88+
var parameterValueContext = scriptArgument.expression().GetChild(0);
8989

9090
if (parameterValueContext is SimpleflowParser.ObjectIdentifierContext oic)
9191
{

src/Simpleflow/CodeGenerator/SimpleflowCodeVisitor.VisitObjectIdentifier.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ public override Expression VisitObjectIdentifier(SimpleflowParser.ObjectIdentifi
2323
}
2424

2525
// Get index object if specified
26-
var indexObjectExp = GetIndexObjectExpIfDefined(objectExp, context.identifierIndex()[0]);
26+
var indexObjectExp = GetIndexObjectExpIfDefined(objectExp, context.identifierIndex()[0].index());
2727

2828
// Traverse through and get final object
2929
return GetFinalPropertyValue(indexObjectExp, context.identifierIndex());
3030
}
3131

32-
private Expression GetIndexObjectExpIfDefined(Expression objectExp, SimpleflowParser.IdentifierIndexContext context)
32+
private Expression GetIndexObjectExpIfDefined(Expression objectExp, SimpleflowParser.IndexContext context)
3333
{
34-
if (context.index() != null)
34+
if (context != null)
3535
{
36-
var indexExpression = Visit(context.index().indexExpression().GetChild(0)); // represents index
36+
var indexExpression = Visit(context.indexExpression().GetChild(0)); // represents index
3737

3838
var indexProperty
3939
= objectExp
@@ -64,7 +64,7 @@ private Expression GetFinalPropertyValue(Expression propExp, SimpleflowParser.Id
6464
}
6565

6666
// Get indexed object
67-
propExp = GetIndexObjectExpIfDefined(propExp, property);
67+
propExp = GetIndexObjectExpIfDefined(propExp, property.index());
6868

6969
// Get property of indexed object
7070
propExp = Expression.Property(propExp, prop);
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright (c) navtech.io. All rights reserved.
2+
// See License in the project root for license information.
3+
4+
using System;
5+
using System.Linq;
6+
using System.Linq.Expressions;
7+
8+
using Simpleflow.Exceptions;
9+
using Simpleflow.Parser;
10+
11+
namespace Simpleflow.CodeGenerator
12+
{
13+
partial class SimpleflowCodeVisitor<TArg>
14+
{
15+
public override Expression VisitLetStmt(SimpleflowParser.LetStmtContext context)
16+
{
17+
if (context.exception != null)
18+
throw context.exception;
19+
20+
21+
var letIdentifierList = context.Identifier();
22+
var letIdentifier = context.IgnoreIdentifier() != null ? null : letIdentifierList[0].GetText();
23+
24+
// Validate variable name with reserved words
25+
if (SimpleflowKeywords.Keywords.Any(keyword => string.Equals(keyword, letIdentifier, StringComparison.Ordinal)))
26+
{
27+
throw new VariableNameViolationException(letIdentifier);
28+
}
29+
30+
return GetLetVariableExpression(context.expression(),
31+
letIdentifier,
32+
errorVariableName: context.IgnoreIdentifier() != null &&
33+
letIdentifierList.Length == 1
34+
? letIdentifierList[0].GetText()
35+
: letIdentifierList.Length == 2
36+
? letIdentifierList[1].GetText()
37+
: null);
38+
}
39+
40+
private Expression GetLetVariableExpression(SimpleflowParser.ExpressionContext context, string variableName, string errorVariableName)
41+
{
42+
if (context.jsonObj() != null)
43+
{
44+
if (variableName == null)
45+
{
46+
throw new SimpleflowException(Resources.Message.CannotIgnoreIdentifierForJsonObj);
47+
}
48+
49+
return new SmartJsonObjectParameterExpression(context, variableName);
50+
}
51+
var expression = Visit(context.GetChild(0));
52+
53+
// if there's a error variable not declared then return value, else catch it and return
54+
if (string.IsNullOrWhiteSpace(errorVariableName))
55+
{
56+
if (variableName == null) //variableName is null means Ignore variable
57+
{
58+
return expression;
59+
}
60+
else
61+
{
62+
return Expression.Assign(Expression.Variable(expression.Type, variableName), expression);
63+
}
64+
}
65+
else
66+
{
67+
// add try catch if there's error variable defined
68+
var tryExpression = AddTryCatchToExpression(expression);
69+
var varFortryExpression = Expression.Variable(tryExpression.Type);
70+
71+
// Add variables
72+
if (variableName != null)
73+
{
74+
return Expression.Block(
75+
Expression.Assign(varFortryExpression, tryExpression), // run expression with try catch and capture value
76+
Expression.Assign(Expression.Variable(expression.Type, variableName), Expression.Field(varFortryExpression, "Value")),
77+
Expression.Assign(Expression.Variable(typeof(Exception), errorVariableName), Expression.Field(varFortryExpression, "Error"))
78+
);
79+
}
80+
81+
// assign error only, not regular variable
82+
return Expression.Block(
83+
Expression.Assign(varFortryExpression, tryExpression), // run expression with try catch and capture value
84+
Expression.Assign(Expression.Variable(typeof(Exception), errorVariableName), Expression.Field(varFortryExpression, "Error"))
85+
);
86+
}
87+
}
88+
89+
90+
private TryExpression AddTryCatchToExpression(Expression rightsideExpression)
91+
{
92+
if (rightsideExpression.Type == typeof(void))
93+
{
94+
return AddTryCatchToExpressionForVoidValue(rightsideExpression);
95+
}
96+
97+
var varTupleConstructor = typeof(VarTuple<>)
98+
.MakeGenericType(rightsideExpression.Type)
99+
.GetConstructor(new Type[] { rightsideExpression.Type, typeof(Exception) });
100+
101+
ParameterExpression ex = ParameterExpression.Parameter(typeof(Exception));
102+
TryExpression tryCatchExpr =
103+
Expression.TryCatch(
104+
Expression.New(varTupleConstructor,
105+
rightsideExpression, // it may throw
106+
Expression.Constant(null, typeof(Exception))
107+
),
108+
Expression.Catch(
109+
ex,
110+
Expression.New(varTupleConstructor,
111+
Expression.Default(rightsideExpression.Type),
112+
ex)
113+
)
114+
);
115+
116+
return tryCatchExpr;
117+
}
118+
119+
private TryExpression AddTryCatchToExpressionForVoidValue(Expression rightsideExpression)
120+
{
121+
var varTupleConstructor = typeof(VarTuple).GetConstructor(new Type[] { typeof(Exception) });
122+
123+
ParameterExpression ex = ParameterExpression.Parameter(typeof(Exception));
124+
125+
TryExpression tryCatchExpr =
126+
Expression.TryCatch(
127+
Expression.Block(
128+
rightsideExpression, // it may throw
129+
Expression.New(varTupleConstructor,
130+
Expression.Constant(null, typeof(Exception))
131+
)
132+
),
133+
Expression.Catch(
134+
ex,
135+
Expression.New(varTupleConstructor, ex)
136+
)
137+
);
138+
139+
return tryCatchExpr;
140+
}
141+
}
142+
}

src/Simpleflow/CodeGenerator/SimpleflowCodeVisitor.VistitLetSet.cs renamed to src/Simpleflow/CodeGenerator/SimpleflowCodeVisitor.VistitSet.cs

Lines changed: 14 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Linq;
76
using System.Linq.Expressions;
87

98
using Simpleflow.Exceptions;
@@ -13,57 +12,38 @@ namespace Simpleflow.CodeGenerator
1312
{
1413
partial class SimpleflowCodeVisitor<TArg>
1514
{
16-
public override Expression VisitLetStmt(SimpleflowParser.LetStmtContext context)
17-
{
18-
if (context.exception != null)
19-
throw context.exception;
20-
21-
22-
var letIdentifierList = context.Identifier();
23-
var letIdentifier = context.IgnoreIdentifier() != null ? null : letIdentifierList[0].GetText();
24-
25-
// Validate variable name with reserved words
26-
if (SimpleflowKeywords.Keywords.Any(keyword => string.Equals(keyword, letIdentifier, StringComparison.Ordinal)))
27-
{
28-
throw new VariableNameViolationException(letIdentifier);
29-
}
30-
31-
return GetLetVariableExpression(context.expression(),
32-
letIdentifier,
33-
errorVariableName: context.IgnoreIdentifier() != null &&
34-
letIdentifierList.Length == 1
35-
? letIdentifierList[0].GetText()
36-
: letIdentifierList.Length == 2
37-
? letIdentifierList[1].GetText()
38-
: null);
39-
}
40-
4115
// Mutate statement
4216
public override Expression VisitSetStmt(SimpleflowParser.SetStmtContext context)
4317
{
4418
// Find variable and assign it
45-
var variableName = context.IgnoreIdentifier() != null
46-
? null
47-
: context.Identifier()[0].GetText();
19+
string variableName = context.IgnoreIdentifier() != null
20+
? null
21+
: context.Identifier()[0].GetText();
4822

4923
// Assume that SmartVariable has already created as part of function invocation if available
5024
Expression variableExpression = variableName != null
51-
? GetVariable(variableName) ?? GetSmartVariable(variableName)?.VariableExpression?.Left
52-
: null;
25+
? GetVariable(variableName) ?? GetSmartVariable(variableName)?.VariableExpression?.Left
26+
: null;
5327

5428
if (variableName != null && variableExpression == null)
5529
{
5630
throw new UndeclaredVariableException(variableName);
5731
}
5832

59-
var rightSideSetExpression = GetRightSideExpressionOfSetStmt(context, variableName, ref variableExpression);
33+
// Get indexed object if defined as left expression
34+
variableExpression = GetIndexObjectExpIfDefined(variableExpression, context.index());
35+
36+
// Get value expression as right one
37+
Expression valueExpression = GetValueExpressionOfSetStmt(context, variableName, ref variableExpression);
6038

6139
// return expression
62-
return GetSetStmtExpression(context, variableName, variableExpression, rightSideSetExpression);
40+
return GetSetStmtExpression(context, variableName, variableExpression, valueExpression);
6341

6442
}
6543

66-
private Expression GetRightSideExpressionOfSetStmt(SimpleflowParser.SetStmtContext context, string variableName, ref Expression variableExpression)
44+
private Expression GetValueExpressionOfSetStmt(SimpleflowParser.SetStmtContext context,
45+
string variableName, /* Pass variable name for discardable cheking */
46+
ref Expression variableExpression)
6747
{
6848
var expression = context.expression();
6949
Expression rightSideSetExpression;
@@ -155,108 +135,6 @@ private Expression AssignWithHandlingError(Expression variable, Expression right
155135
);
156136
}
157137

158-
private TryExpression AddTryCatchToExpression(Expression rightsideExpression)
159-
{
160-
if (rightsideExpression.Type == typeof(void))
161-
{
162-
return AddTryCatchToExpressionForVoidValue(rightsideExpression);
163-
}
164-
165-
var varTupleConstructor = typeof(VarTuple<>)
166-
.MakeGenericType(rightsideExpression.Type)
167-
.GetConstructor(new Type[] { rightsideExpression.Type, typeof(Exception) });
168-
169-
ParameterExpression ex = ParameterExpression.Parameter(typeof(Exception));
170-
TryExpression tryCatchExpr =
171-
Expression.TryCatch(
172-
Expression.New(varTupleConstructor,
173-
rightsideExpression, // it may throw
174-
Expression.Constant(null, typeof(Exception))
175-
),
176-
Expression.Catch(
177-
ex,
178-
Expression.New(varTupleConstructor,
179-
Expression.Default(rightsideExpression.Type),
180-
ex)
181-
)
182-
);
183-
184-
return tryCatchExpr;
185-
}
186-
187-
private TryExpression AddTryCatchToExpressionForVoidValue(Expression rightsideExpression)
188-
{
189-
var varTupleConstructor = typeof(VarTuple).GetConstructor(new Type[] { typeof(Exception) });
190-
191-
ParameterExpression ex = ParameterExpression.Parameter(typeof(Exception));
192-
193-
TryExpression tryCatchExpr =
194-
Expression.TryCatch(
195-
Expression.Block(
196-
rightsideExpression, // it may throw
197-
Expression.New(varTupleConstructor,
198-
Expression.Constant(null, typeof(Exception))
199-
)
200-
),
201-
Expression.Catch(
202-
ex,
203-
Expression.New(varTupleConstructor,ex)
204-
)
205-
);
206-
207-
return tryCatchExpr;
208-
}
209-
210-
211-
private Expression GetLetVariableExpression(SimpleflowParser.ExpressionContext context, string variableName, string errorVariableName)
212-
{
213-
if (context.jsonObj() != null)
214-
{
215-
if (variableName == null)
216-
{
217-
throw new SimpleflowException(Resources.Message.CannotIgnoreIdentifierForJsonObj);
218-
}
219-
220-
return new SmartJsonObjectParameterExpression(context, variableName);
221-
}
222-
var expression = Visit(context.GetChild(0));
223-
224-
// if there's a error variable not declared then return value, else catch it and return
225-
if (string.IsNullOrWhiteSpace(errorVariableName))
226-
{
227-
if (variableName == null) //variableName is null means Ignore variable
228-
{
229-
return expression;
230-
}
231-
else
232-
{
233-
return Expression.Assign(Expression.Variable(expression.Type, variableName), expression);
234-
}
235-
}
236-
else
237-
{
238-
// add try catch if there's error variable defined
239-
var tryExpression = AddTryCatchToExpression(expression);
240-
var varFortryExpression = Expression.Variable(tryExpression.Type);
241-
242-
// Add variables
243-
if (variableName != null)
244-
{
245-
return Expression.Block(
246-
Expression.Assign(varFortryExpression, tryExpression), // run expression with try catch and capture value
247-
Expression.Assign(Expression.Variable(expression.Type, variableName), Expression.Field(varFortryExpression, "Value")),
248-
Expression.Assign(Expression.Variable(typeof(Exception), errorVariableName), Expression.Field(varFortryExpression, "Error"))
249-
);
250-
}
251-
252-
// assign error only, not regular variable
253-
return Expression.Block(
254-
Expression.Assign(varFortryExpression, tryExpression), // run expression with try catch and capture value
255-
Expression.Assign(Expression.Variable(typeof(Exception), errorVariableName), Expression.Field(varFortryExpression, "Error"))
256-
);
257-
}
258-
}
259-
260138
private Expression VisitPartialSet(SimpleflowParser.SetStmtContext context, Expression variable)
261139
{
262140
var pairs = context.expression().jsonObj().pair();

src/Simpleflow/Parser/Grammar/SimpleflowLexer.g4

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) navtech.io. All rights reserved.
2+
// See License in the project root for license information.
3+
14
lexer grammar SimpleflowLexer;
25

36
channels { ERROR }

0 commit comments

Comments
 (0)