Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ private List<Expression> GetArgumentExpressions(SimpleflowParser.FunctionContext
var actualMethodParameters = methodInfo.GetParameters();
var arguments = context.functionArguments().functionArgument();
var argumentsExpressions = new List<Expression>();

if (arguments == null)
{
return argumentsExpressions;
}

CheckInvalidParameters(actualMethodParameters, arguments);
CheckInvalidParameters(actualMethodParameters, arguments, context.FunctionName().GetText());
CheckRepeatedParameters(arguments);

foreach (var methodParameter in actualMethodParameters)
Expand Down Expand Up @@ -113,14 +113,16 @@ where g.Count() > 1
}
}

private void CheckInvalidParameters(ParameterInfo[] actualMethodParameters, SimpleflowParser.FunctionArgumentContext[] parameters)
private void CheckInvalidParameters(ParameterInfo[] actualMethodParameters,
SimpleflowParser.FunctionArgumentContext[] parameters,
string functionName)
{
foreach (var parameter in parameters)
{
var paramterName = parameter.Identifier().GetText();
if (!actualMethodParameters.Any(p => string.Equals(p.Name, paramterName, System.StringComparison.OrdinalIgnoreCase)))
{
throw new InvalidFunctionParameterNameException(paramterName);
throw new InvalidFunctionParameterNameException(paramterName, functionName);
}
}
}
Expand All @@ -141,12 +143,14 @@ private Expression VisitObjectIdentiferAsPerTargetType(SimpleflowParser.ObjectId

private Expression CreateSmartVariableIfObjectIdentiferNotDefined(Type targetType, string name)
{
// Variable names are not case sensitive
// Variable name is not case sensitive
var smartVar = GetSmartVariable(name);

if (smartVar == null)
{
throw new InvalidFunctionParameterNameException(name);
// Since smart variable (JSON) can only be used with function argument,
// so here we need to throw function related exception
throw new InvalidFunctionParameterNameException($"Invalid parameter or variable '{name}'");
}

// Return if already created
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private Expression GetFinalPropertyValue(Expression propExp, SimpleflowParser.Id

if (field == null)
{
throw new InvalidPropertyException($"Invalid property or field '{propName}'");
throw new InvalidPropertyException(propName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public override Expression VisitRuleStmt(SimpleflowParser.RuleStmtContext contex

if (childResult != null)
{
statements.Add(SetRuntimeState(c));
statements.Add(childResult);
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/Simpleflow/CodeGenerator/SimpleflowCodeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using Antlr4.Runtime.Tree;

using Simpleflow.Parser;
using Simpleflow.Exceptions;
Expand Down Expand Up @@ -85,6 +86,9 @@ private void ProcessEachStatement(SimpleflowParser.ProgramContext context, List<

if (childResult != null)
{
// Set runtime state for debugging Simpleflow code
statementExpressions.Add( SetRuntimeState(c) );

/* if current rule is variable statement then store the left expression
as variable identifier in variable collection */
if (c.GetType() == typeof(SimpleflowParser.LetStmtContext))
Expand Down Expand Up @@ -230,6 +234,7 @@ private void ReplaceVirtualSmartVariablesWithReal(List<Expression> statementExpr
}
}


/* Create basic set of variables to access in script */
private List<Expression> CreateDefaultVariablesAndAssign()
{
Expand All @@ -246,5 +251,16 @@ private List<Expression> CreateDefaultVariablesAndAssign()
};
}

private Expression SetRuntimeState(IParseTree node)
{
var codeLineNumber = ((Antlr4.Runtime.CommonToken)((Antlr4.Runtime.ParserRuleContext)node).Start).Line;

var property = typeof(RuntimeContext)
.GetProperty("LineNumber", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

var propertyExpression = Expression.Property(ScriptHelperContextParam, property);
return Expression.Assign(propertyExpression, Expression.Constant(codeLineNumber));
}

}
}
13 changes: 11 additions & 2 deletions src/Simpleflow/Exceptions/InvalidFunctionParameterNameException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,20 @@ namespace Simpleflow.Exceptions
/// </summary>
public class InvalidFunctionParameterNameException : SimpleflowException
{

/// <summary>
///
/// </summary>
/// <param name="message"></param>
public InvalidFunctionParameterNameException(string message) : base(message) { }

/// <summary>
/// Initializes a new instance of the <see cref="InvalidFunctionException"/> class with
/// a specified variable name.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public InvalidFunctionParameterNameException(string message) : base(message) { }
/// <param name="parameterName">The message that describes the error.</param>
/// <param name="functionName"></param>
public InvalidFunctionParameterNameException(string parameterName, string functionName)
: base($"Function '{functionName}' does not have parameter '{parameterName}'") { }
}
}
4 changes: 2 additions & 2 deletions src/Simpleflow/Exceptions/InvalidPropertyException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class InvalidPropertyException : SimpleflowException
/// Initializes a new instance of the <see cref="InvalidPropertyException"/> class with
/// a specified variable name.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public InvalidPropertyException(string message): base(message)
/// <param name="propertyName">The message that describes the error.</param>
public InvalidPropertyException(string propertyName): base($"Invalid property or field '{propertyName}'")
{

}
Expand Down
10 changes: 10 additions & 0 deletions src/Simpleflow/Exceptions/SimpleflowException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,15 @@ public SimpleflowException(string message): base(message)
{

}

/// <summary>
///
/// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
public SimpleflowException(string message, Exception innerException) : base(message, innerException)
{

}
}
}
36 changes: 36 additions & 0 deletions src/Simpleflow/Exceptions/SimpleflowRuntimeException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) navtech.io. All rights reserved.
// See License in the project root for license information.

using System;

namespace Simpleflow.Exceptions
{
/// <summary>
///
/// </summary>
public class SimpleflowRuntimeException : SimpleflowException
{
/// <summary>
///
/// </summary>
/// <param name="message"></param>
/// <param name="lineNumber"></param>
/// <param name="statement"></param>
/// <param name="innerException"></param>
public SimpleflowRuntimeException(string message, int lineNumber, string statement, Exception innerException) : base(message, innerException)
{
LineNumber = lineNumber;
Statement = statement;
}

/// <summary>
/// Gets line number where error has occurred
/// </summary>
public int LineNumber { get; }

/// <summary>
/// Gets statement where error has occurred
/// </summary>
public string Statement { get; }
}
}
2 changes: 2 additions & 0 deletions src/Simpleflow/RuntimeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ internal RuntimeContext(FlowOutput flowOutput, CancellationToken token)
/// Gets cancellation token
/// </summary>
public CancellationToken CancellationToken => _token;

internal int LineNumber { get;set; }
}
}

17 changes: 15 additions & 2 deletions src/Simpleflow/Services/ExecutionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See License in the project root for license information.

using System;
using Simpleflow.Exceptions;

namespace Simpleflow.Services
{
Expand Down Expand Up @@ -35,10 +36,22 @@ public void Run<TArg>(FlowContext<TArg> context, NextPipelineService<TArg> next)
// Add trace for debugging
context.Trace?.CreateNewTracePoint(nameof(ExecutionService));

var scriptHelperContext = new RuntimeContext(context.Output,
var scriptContext = new RuntimeContext(context.Output,
context.Options?.CancellationToken ?? default);

context.Internals.CompiledScript?.Invoke(context.Argument, context.Output, scriptHelperContext);
try
{
context.Internals.CompiledScript?.Invoke(context.Argument, context.Output, scriptContext);
}
catch(Exception ex)
{
// Get statement where error has occurred
var lines = context.Script?.Split('\n') ?? new string[] { };
var code = lines.Length >= scriptContext.LineNumber && scriptContext.LineNumber > 0 ? lines[scriptContext.LineNumber-1] : context.Script;

// throw
throw new SimpleflowRuntimeException(ex.Message, scriptContext.LineNumber, code, ex);
}

next?.Invoke(context);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Simpleflow/Simpleflow.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFrameworks>net48;netcoreapp3.1;net6.0;</TargetFrameworks>
<PackageIcon>PackageIcon.png</PackageIcon>
<VersionPrefix>1.0.12</VersionPrefix>
<VersionSuffix>beta2</VersionSuffix>
<VersionSuffix></VersionSuffix>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

Expand Down
42 changes: 40 additions & 2 deletions src/Simpleflow/Simpleflow.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions test/Simpleflow.Tests/Helpers/TestsHelper.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@

using System;

namespace Simpleflow.Tests.Helpers
{
internal static class TestsHelper
{
public static bool IsWindows => System.Runtime.InteropServices.RuntimeInformation.OSDescription.Contains("Windows");

public static string Timezone => IsWindows ? "Eastern Standard Time" : "America/New_York";

public static Exception Try(Action callback)
{
try
{
callback();
}
catch(Exception ex)
{
return ex;
}
return null;
}

}
}
Loading