private static ExpressionNode ParseAgainstModel(Type modelType, string expression, ExpressionScope expressionScope, IMemberLocator memberLocator, SourceLocation location)
{
var dotIndex = expression.IndexOf('.');
if (dotIndex >= 0)
{
var subModel = ParseAgainstModel(modelType, expression.Substring(0, dotIndex), expressionScope, memberLocator, location.SetLength(dotIndex));
return SyntaxTreeExpression.SubModel(
subModel,
ParseAgainstModel(subModel.ResultType, expression.Substring(dotIndex + 1), ExpressionScope.CurrentModelOnStack, memberLocator, location.MoveIndex(dotIndex + 1)),
location
);
}
if (expression.EndsWith("()"))
{
var func = memberLocator.FindMethod(modelType, expression.Substring(0, expression.Length - 2));
if (func != null) return SyntaxTreeExpression.Function(modelType, func.Name, location, expressionScope);
}
var prop = memberLocator.FindProperty(modelType, expression);
if (prop != null)
return SyntaxTreeExpression.Property(modelType, prop.Name, location, expressionScope);
var field = memberLocator.FindField(modelType, expression);
if (field != null)
return SyntaxTreeExpression.Field(modelType, field.Name, location, expressionScope);
if (IsLateBoundAcceptingType(modelType))
return SyntaxTreeExpression.LateBound(expression, location, memberLocator, false, expressionScope);
throw new VeilParserException(
$"Unable to parse model expression '{expression}' againt model '{modelType.Name}'", location);
}