// 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()); } }
/// <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)); } }
/// <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; }