// just the declaration with the initialization
        public override void VisitVariableDeclarator(VariableDeclaratorSyntax variableDeclaratorSyntax)
        {
            base.VisitVariableDeclarator(variableDeclaratorSyntax);
            var identifier    = variableDeclaratorSyntax.Identifier;
            var semanticModel = _context.GetSemanticModelFor(variableDeclaratorSyntax);
            var symbol        = semanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);

            var vars = _variables.Peek();
            VariableIdentity variableIdentity = null;

            if (variableDeclaratorSyntax.Initializer != null &&
                variableDeclaratorSyntax.Initializer is EqualsValueClauseSyntax equalsValueClauseSyntax)
            {
                var right         = equalsValueClauseSyntax.Value;
                var rightVariable = semanticModel.GetSymbolInfo(right).Symbol;

                if (rightVariable != null &&
                    vars.TryGetValue(rightVariable.Name, out VariableIdentity value))
                {
                    variableIdentity = VariableIdentity.FromAlias(value, symbol);
                }
            }

            if (variableIdentity == null)
            {
                variableIdentity = new VariableIdentity(symbol);
            }

            vars[symbol.Name] = variableIdentity;
        }
 /// <summary>
 /// 变量表达式
 /// </summary>
 /// <param name="variableId"></param>
 /// <param name="fieldName"></param>
 /// <param name="isMethod"></param>
 /// <param name="needCacheData"></param>
 internal VariableExpression(VariableIdentity variableId, string fieldName, bool isMethod, bool needCacheData)
 {
     this.VariableId = variableId;
     this.FieldName = fieldName;
     this.IsMethod = isMethod;
     this.NeedCacheData = needCacheData;
 }
        public override void VisitAssignmentExpression(AssignmentExpressionSyntax assignmentExpressionSyntax)
        {
            base.VisitAssignmentExpression(assignmentExpressionSyntax);

            var semanticModel = _context.GetSemanticModelFor(assignmentExpressionSyntax);

            var vars = _variables.Peek();

            var symbol = semanticModel.GetSymbolInfo(assignmentExpressionSyntax.Left).Symbol;
            VariableIdentity variableIdentity = null;

            if (assignmentExpressionSyntax.Right != null && assignmentExpressionSyntax.Right is IdentifierNameSyntax identifierNameSyntax)
            {
                var rightVariable = semanticModel.GetSymbolInfo(identifierNameSyntax).Symbol;

                if (rightVariable != null && vars.TryGetValue(rightVariable.Name, out VariableIdentity value))
                {
                    variableIdentity = VariableIdentity.FromAlias(value, symbol);
                }
            }

            if (variableIdentity == null)
            {
                variableIdentity = new VariableIdentity(symbol);
            }

            vars[symbol.Name] = variableIdentity;
        }
            public static VariableIdentity FromAlias(VariableIdentity other, ISymbol symbol)
            {
                var instance = new VariableIdentity();

                instance.Id     = other.Id;
                instance.Symbol = symbol;
                return(instance);
            }
        public override void VisitInvocationExpression(InvocationExpressionSyntax invocationExpressionSyntax)
        {
            base.VisitInvocationExpression(invocationExpressionSyntax);
            var semanticModel = _context.GetSemanticModelFor(invocationExpressionSyntax);
            var method        = semanticModel.GetSymbolInfo(invocationExpressionSyntax).Symbol;

            var containingType = method.ContainingType;

            if (IsTaggedType(containingType))
            {
                var fullName           = $"{method.ContainingNamespace}.{containingType.Name}.{method.Name}";
                VariableIdentity varid = null;

                var argument = invocationExpressionSyntax.ArgumentList.Arguments.FirstOrDefault();
                if (argument != null)
                {
                    var argumentSymbol = semanticModel.GetSymbolInfo(argument.Expression).Symbol;
                    var variableName   = argumentSymbol.Name;
                    var vars           = _variables.Peek();
                    vars.TryGetValue(variableName, out varid);
                }

                _methodSequence.Add(new MethodOnVariable(fullName, varid?.Id ?? 0));
            }

            foreach (var declaringSyntax in method.DeclaringSyntaxReferences)
            {
                var declarationSyntax = (MethodDeclarationSyntax)declaringSyntax.GetSyntax();

                var argumentSymbols = new List <ISymbol>();
                foreach (var argument in invocationExpressionSyntax.ArgumentList.Arguments)
                {
                    var argumentSymbol = semanticModel.GetSymbolInfo(argument.Expression).Symbol;
                    if (argumentSymbol != null)
                    {
                        argumentSymbols.Add(argumentSymbol);
                    }
                }

                StartInternal(declarationSyntax, argumentSymbols.ToList());
            }
        }
Example #6
0
 /// <summary>
 /// 添加标签属性时的触发函数.用于设置自身的某些属性值
 /// </summary>
 /// <param name="name"></param>
 /// <param name="item"></param>
 protected override void OnAddingAttribute(string name, Attribute item)
 {
     switch (name)
     {
         case "index":
             this.Index = ParserHelper.CreateVariableIdentity(this.OwnerTemplate, item.Text);
             break;
     }
 }
 /// <summary>
 /// 变量表达式
 /// </summary>
 /// <param name="variableId"></param>
 /// <param name="needCacheData"></param>
 internal VariableExpression(VariableIdentity variableId, bool needCacheData) 
     : this(variableId, null, false, needCacheData)
 { }
        /// <summary>
        /// 构建变量标签元素
        /// </summary>
        /// <param name="ownerTemplate">宿主模板</param>
        /// <param name="container">标签的容器</param>
        /// <param name="match"></param>
        internal static VariableTag CreateVariableTag(Template ownerTemplate, Tag container, Match match)
        {
            string prefix;
            Variable variable = CreateVariable(ownerTemplate, match, out prefix);
            VariableIdentity variableId = new VariableIdentity(ownerTemplate, variable, prefix);

            //变量标签元素则需要缓存表达式的值
            VariableExpression varExp = CreateVariableExpression(variableId, match, true);

            VariableTag tag = new VariableTag(ownerTemplate, varExp);
            //解析属性列表
            ParseElementAttributes(tag, match);
            container.AppendChild(tag);

            return tag;
        }
        /// <summary>
        /// 从变量表达式文本(如:name.age)中构建变量表达式
        /// </summary>
        /// <param name="ownerTemplate"></param>
        /// <param name="expressionText"></param>
        /// <param name="needCacheData"></param>
        /// <returns></returns>
        internal static VariableExpression CreateVariableExpression(Template ownerTemplate, string expressionText, bool needCacheData)
        {
            if (string.IsNullOrEmpty(expressionText)) return null;

            Match match = ParserRegex.VarExpRegex.Match(expressionText);
            if (match.Success)
            {
                string prefix;
                Variable variable = CreateVariable(ownerTemplate, match, out prefix);
                VariableIdentity variableId = new VariableIdentity(ownerTemplate, variable, prefix);

                return CreateVariableExpression(variableId, match, needCacheData);
            }
            else
            {
                //非变量表达式
                throw new ParserException(string.Format("变量表达式\"{0}\"的定义格式错误", expressionText));
            }
        }
Example #10
0
        /// <summary>
        /// 构建变量的字段列表
        /// </summary>
        /// <param name="variableId"></param>
        /// <param name="match"></param>
        /// <param name="needCacheData"></param>
        /// <returns></returns>
        internal static VariableExpression CreateVariableExpression(VariableIdentity variableId, Match match, bool needCacheData)
        {
            //解析变量字段列表
            VariableExpression field = new VariableExpression(variableId, needCacheData);
            CaptureCollection fields = match.Groups["field"].Captures;
            CaptureCollection methods = match.Groups["method"].Captures;
            VariableExpression item = field;
            for (var i = 0; i < fields.Count; i++)
            {
                string fieldName = fields[i].Value;
                VariableExpression exp = new VariableExpression(item, fieldName, !string.IsNullOrEmpty(methods[i].Value));
                item = exp;
            }

            return field;
        }