public AnalyzerResult AnalyzeTemplate(string templateName) { if (!templateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{LGErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } // Using a stack to track the evaluation trace evaluationTargetStack.Push(new EvaluationTarget(templateName, null)); // we don't exclude parameters any more // because given we don't track down for templates have parameters // the only scenario that we are still analyzing an parameterized template is // this template is root template to analyze, in this we also don't have exclude parameters var dependencies = Visit(templateMap[templateName].ParseTree); evaluationTargetStack.Pop(); return(dependencies); }
public object ConstructScope(string inputTemplateName, List <object> args) { var templateName = ParseTemplateName(inputTemplateName).pureTemplateName; if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } var parameters = TemplateMap[templateName].Parameters; var currentScope = CurrentTarget().Scope; if (args.Count == 0) { // no args to construct, inherit from current scope return(currentScope); } var newScope = parameters.Zip(args, (k, v) => new { k, v }) .ToDictionary(x => x.k, x => x.v); var memory = currentScope as CustomizedMemory; if (memory == null) { throw new Exception(LGErrors.InvalidMemory); } // inherit current memory's global scope return(new CustomizedMemory(memory.GlobalMemory, new SimpleObjectMemory(newScope))); }
private List <Diagnostic> CheckExpression(string exp, ParserRuleContext context, string prefix = "") { var result = new List <Diagnostic>(); if (!exp.EndsWith("}")) { result.Add(BuildLGDiagnostic(LGErrors.NoCloseBracket, context: context)); } else { exp = exp.TrimExpression(); try { ExpressionParser.Parse(exp); } catch (Exception e) { var errorMsg = prefix + LGErrors.ExpressionParseError(exp) + e.Message; result.Add(BuildLGDiagnostic(errorMsg, context: context)); return(result); } } return(result); }
/// <summary> /// Expand the results of a template with given name and scope. /// </summary> /// <param name="templateName">Given template name.</param> /// <param name="scope">Given scope.</param> /// <returns>All possiable results.</returns> public List <string> ExpandTemplate(string templateName, object scope) { if (!(scope is CustomizedMemory)) { scope = new CustomizedMemory(SimpleObjectMemory.Wrap(scope)); } if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{LGErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } // Using a stack to track the evaluation trace evaluationTargetStack.Push(new EvaluationTarget(templateName, scope)); var result = Visit(TemplateMap[templateName].ParseTree); evaluationTargetStack.Pop(); return(result); }
private List <string> EvalExpression(string exp) { exp = exp.TrimExpression(); var(result, error) = EvalByExpressionEngine(exp, CurrentTarget().Scope); if (error != null) { throw new Exception(LGErrors.ErrorExpression(exp, error)); } if (result == null) { throw new Exception(LGErrors.NullExpression(exp)); } if (result is IList && result.GetType().IsGenericType&& result.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List <>))) { return((List <string>)result); } return(new List <string>() { result.ToString() }); }
public override List <Diagnostic> VisitTemplateDefinition([NotNull] LGFileParser.TemplateDefinitionContext context) { var result = new List <Diagnostic>(); var templateNameLine = context.templateNameLine(); var errorTemplateName = templateNameLine.errorTemplateName(); if (errorTemplateName != null) { result.Add(BuildLGDiagnostic(LGErrors.InvalidTemplateName, context: errorTemplateName)); } else { var templateName = context.templateNameLine().templateName().GetText(); if (visitedTemplateNames.Contains(templateName)) { result.Add(BuildLGDiagnostic(LGErrors.DuplicatedTemplateInSameTemplate(templateName), context: templateNameLine)); } else { visitedTemplateNames.Add(templateName); foreach (var reference in lgFile.References) { var sameTemplates = reference.Templates.Where(u => u.Name == templateName); foreach (var sameTemplate in sameTemplates) { result.Add(BuildLGDiagnostic(LGErrors.DuplicatedTemplateInDiffTemplate(sameTemplate.Name, sameTemplate.Source), context: templateNameLine)); } } if (result.Count > 0) { return(result); } else { if (context.templateBody() == null) { result.Add(BuildLGDiagnostic(LGErrors.NoTemplateBody(templateName), DiagnosticSeverity.Warning, context.templateNameLine())); } else { result.AddRange(Visit(context.templateBody())); } } } } return(result); }
private void CheckTemplateReference(string templateName, IEnumerable <Expression> children) { if (!this.TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } var expectedArgsCount = this.TemplateMap[templateName].Parameters.Count(); var actualArgsCount = children.Count(); if (actualArgsCount != 0 && expectedArgsCount != actualArgsCount) { throw new Exception(LGErrors.ArgumentMismatch(templateName, expectedArgsCount, actualArgsCount)); } }
/// <summary> /// Evaluate a template with given name and scope. /// </summary> /// <param name="inputTemplateName">template name.</param> /// <param name="scope">scope.</param> /// <returns>Evaluate result.</returns> public object EvaluateTemplate(string inputTemplateName, object scope) { if (!(scope is CustomizedMemory)) { scope = new CustomizedMemory(SimpleObjectMemory.Wrap(scope)); } (var reExecute, var templateName) = ParseTemplateName(inputTemplateName); if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{LGErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } var templateTarget = new EvaluationTarget(templateName, scope); var currentEvaluateId = templateTarget.GetId(); EvaluationTarget previousEvaluateTarget = null; if (evaluationTargetStack.Count != 0) { previousEvaluateTarget = evaluationTargetStack.Peek(); if (!reExecute && previousEvaluateTarget.EvaluatedChildren.ContainsKey(currentEvaluateId)) { return(previousEvaluateTarget.EvaluatedChildren[currentEvaluateId]); } } // Using a stack to track the evaluation trace evaluationTargetStack.Push(templateTarget); var result = Visit(TemplateMap[templateName].ParseTree); if (previousEvaluateTarget != null) { previousEvaluateTarget.EvaluatedChildren[currentEvaluateId] = result; } evaluationTargetStack.Pop(); return(result); }
private List <string> EvalExpression(string exp, ParserRuleContext context, string errorPrefix = "") { exp = exp.TrimExpression(); var(result, error) = EvalByExpressionEngine(exp, CurrentTarget().Scope); if (error != null || (result == null && strictMode)) { var errorMsg = string.Empty; var childErrorMsg = string.Empty; if (error != null) { childErrorMsg += error; } else if (result == null) { childErrorMsg += LGErrors.NullExpression(exp); } if (context != null) { errorMsg += LGErrors.ErrorExpression(context.GetText(), CurrentTarget().TemplateName, errorPrefix); } if (evaluationTargetStack.Count > 0) { evaluationTargetStack.Pop(); } throw new Exception(childErrorMsg + errorMsg); } else if (result == null && !strictMode) { result = "null"; } if (result is IList && result.GetType().IsGenericType&& result.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List <>))) { return((List <string>)result); } return(new List <string>() { result.ToString() }); }
private object EvalExpression(string exp) { exp = exp.TrimExpression(); var(result, error) = EvalByExpressionEngine(exp, CurrentTarget().Scope); if (error != null) { throw new Exception(LGErrors.ErrorExpression(exp, error)); } if (result == null) { throw new Exception(LGErrors.NullExpression(exp)); } return(result); }
private void ValidTemplateReference(Expression expression) { var templateName = expression.Type; if (!this.TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } var expectedArgsCount = this.TemplateMap[templateName].Parameters.Count(); var actualArgsCount = expression.Children.Length; if (expectedArgsCount != actualArgsCount) { throw new Exception(LGErrors.ArgumentMismatch(templateName, expectedArgsCount, actualArgsCount)); } }
/// <summary> /// Add a new template and return LG File. /// </summary> /// <param name="templateName">new template name.</param> /// <param name="parameters">new params.</param> /// <param name="templateBody">new template body.</param> /// <returns>updated LG file.</returns> public LGFile AddTemplate(string templateName, List <string> parameters, string templateBody) { var template = Templates.FirstOrDefault(u => u.Name == templateName); if (template != null) { throw new Exception(LGErrors.TemplateExist(templateName)); } var templateNameLine = BuildTemplateNameLine(templateName, parameters); var newTemplateBody = ConvertTemplateBody(templateBody); var newContent = $"{Content.TrimEnd()}\r\n\r\n{templateNameLine}\r\n{newTemplateBody}\r\n"; Initialize(LGParser.ParseText(newContent, Id, ImportResolver)); return(this); }
// Validator for template(...) private void ValidateTemplateFunction(Expression expression) { ExpressionFunctions.ValidateAtLeastOne(expression); var children0 = expression.Children[0]; if (children0.ReturnType != ReturnType.Object && children0.ReturnType != ReturnType.String) { throw new Exception(LGErrors.ErrorTemplateNameformat(children0.ToString())); } // Validate more if the name is string constant if (children0.Type == ExpressionType.Constant) { var templateName = (children0 as Constant).Value.ToString(); CheckTemplateReference(templateName, expression.Children.Skip(1)); } }
private bool EvalExpressionInCondition(string exp, ParserRuleContext context = null, string errorPrefix = "") { exp = exp.TrimExpression(); var(result, error) = EvalByExpressionEngine(exp, CurrentTarget().Scope); if (strictMode && (error != null || result == null)) { var errorMsg = string.Empty; var childErrorMsg = string.Empty; if (error != null) { childErrorMsg += error; } else if (result == null) { childErrorMsg += LGErrors.NullExpression(exp); } if (context != null) { errorMsg += LGErrors.ErrorExpression(context.GetText(), CurrentTarget().TemplateName, errorPrefix); } if (evaluationTargetStack.Count > 0) { evaluationTargetStack.Pop(); } throw new Exception(childErrorMsg + errorMsg); } else if (error != null || result == null || (result is bool r1 && r1 == false) || (result is int r2 && r2 == 0)) { return(false); } return(true); }
private object EvalExpression(string exp, ParserRuleContext context = null, string errorPrefix = "") { exp = exp.TrimExpression(); var(result, error) = EvalByExpressionEngine(exp, CurrentTarget().Scope); if (error != null || (result == null && strictMode)) { var errorMsg = string.Empty; var childErrorMsg = string.Empty; if (error != null) { childErrorMsg += error; } else if (result == null) { childErrorMsg += LGErrors.NullExpression(exp); } if (context != null) { errorMsg += LGErrors.ErrorExpression(context.GetText(), CurrentTarget().TemplateName, errorPrefix); } if (evaluationTargetStack.Count > 0) { evaluationTargetStack.Pop(); } throw new Exception(childErrorMsg + errorMsg); } else if (result == null && !strictMode) { result = "null"; } return(result); }