Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The problem of checking expression statements #50

Open
DNetORM opened this issue Apr 18, 2024 · 7 comments
Open

The problem of checking expression statements #50

DNetORM opened this issue Apr 18, 2024 · 7 comments
Labels

Comments

@DNetORM
Copy link

DNetORM commented Apr 18, 2024

When I wrote some code expressions, I wanted to check the syntax, such as whether the properties and methods were correct. I think using type reflection can check, but I wrote an incorrect property and did not prompt me for any errors. Why do I need this feature? Because I have defined some types of variables that may not have been assigned values, even though I have written code expressions, using Eval() function to check in real time will definitely result in errors. So, I wonder if you can implement pre checking for some code expressions, just to check if the syntax is correct. I think it should be possible in theory, but I don't know how to do it

var varContext = new Dictionary<string, object>();
varContext["dt"] = datatable;

Expression expr = lambdaParser.Parse("dt.Rows1[0]");
var exprParams = LambdaParser.GetExpressionParameters(expr);

dt is a System.DataTable type variable,Rows1 is an incorrect property,But it didn't give me any exceptions,i need some checks,how to do?

@VitaliyMF
Copy link
Contributor

LambdaParser.Parse parses an expression into .NET Expression, and you don't get any errors if it is syntactically correct.

dt is a System.DataTable type variable,Rows1 is an incorrect property,But it didn't give me any exceptions,i need some checks,how to do?

It is possible to determine that "Rows1" is incorrect property only when your expression is evaluated (for the concrete evaluation context with contains concrete "dt" instance), and you'll get an error when you'll call "Eval" for this expression and the evaluation context.

@DNetORM
Copy link
Author

DNetORM commented Apr 18, 2024

Is it possible to do this? Provide a dictionary that stores types with the same key values, and then perform syntax checks based on this dictionary, such as varTypeContext

var varContext = new Dictionary<string, object>();
varContext["dt"] = datatable;

var varTypeContext = new Dictionary<string, object>();
varTypeContext ["dt"] = "System.DataTable";

bool res = lambdaParser.CheckExpression("dt.Rows1[0]");

@DNetORM
Copy link
Author

DNetORM commented Apr 18, 2024

I am developing a simple workflow engine and need to define some variables in advance. These variables may have mutual usage relationships, but when defining variables, I do not know the specific values of the variables. I just want to check the syntax of the expression because some variables will only be instantiated at runtime, so I cannot use eval() at this stage

@VitaliyMF
Copy link
Contributor

Is it possible to do this? Provide a dictionary that stores types with the same key values, and then perform syntax checks based on this dictionary, such as varTypeContext
bool res = lambdaParser.CheckExpression("dt.Rows1[0]");

Internal behavior of "CheckExpression" is equivalent to

var res = true;
try {
  lambdaParser.Eval("dt.Rows1[0]", varContext);
} catch (Exception ex) {
  res = false;
}

(note that it is not possible to check an expression for run-time errors without the evaluation context and performing actual evaluation).

Also, if an expression has conditions, this kind of check can verify only correctness for the concrete evaluation context. It is not possible to verify an expression for runtime errors in another way (in the same way as you cannot check for JS runtime errors just by parsing JS code).

I don't see a real need in this API inside LambdaParser because handling of errors may be rather application-specific.

@VitaliyMF
Copy link
Contributor

but when defining variables, I do not know the specific values of the variables. I just want to check the syntax of the expression because some variables will only be instantiated at runtime, so I cannot use eval() at this stage

This means that you can validate expression's syntax with Parse method, but you'll not able to detect runtime errors that depend on the concrete evaluation context. An expression "dt.Rows1[0]" can be valid in one case (if "dt" variable is set and it has "Rows1" property) and can cause an error in anther case. Without evaluation with concrete "dt" value, you cannot validate that (this is a conceptual limitation, not technical).

@DNetORM
Copy link
Author

DNetORM commented Apr 18, 2024

I have changed my approach and used Rosslyn CSharpCompilation to check for syntax issues in compilation. Since Rosslyn can do it, technically your project should also be able to implement it. I think it's just whether you're willing to think about improving it or not

@VitaliyMF
Copy link
Contributor

VitaliyMF commented Apr 18, 2024

Since Rosslyn can do it, technically your project should also be able to implement it.

You're wrong with this assumption. NReco.LambdaParser was specially designed for dynamic typing, it implements special mechanism to support this capability: you are not obligated explicitly define variables and their (.net) types, and this means that all methods/properties are resolved in the run-time (via reflection). A side effect of dynamic typing is that you cannot validate types just by parsing the expression, this is conceptual difference from Roslyn (or any other parsing of strictly-typed expressions).

You may check LambdaParser code to realize that it is not possible to handle type-related errors (like calling wrong method or property) simply because when you have "dt" variable (ParameterExpression) it has System.Object type and parser simply don't have information about its real type - it is known only in the run-time, when an expression is evaluated for the concrete variables context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants