示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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()
            });
        }
示例#6
0
        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);
        }
示例#7
0
        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));
            }
        }
示例#8
0
        /// <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);
        }
示例#9
0
        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);
        }
示例#11
0
        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));
            }
        }
示例#12
0
        /// <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);
        }
示例#13
0
        // 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));
            }
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }