public override SyntaxNode VisitArgument(ArgumentSyntax node) { var invocationSyntax = node.Parent.Parent as InvocationExpressionSyntax; if(invocationSyntax == null) return base.VisitArgument(node); var memberAccessExpressionSyntax = invocationSyntax.Expression as MemberAccessExpressionSyntax; if(memberAccessExpressionSyntax == null) return base.VisitArgument(node); var methodNameSyntax = memberAccessExpressionSyntax.Name as SimpleNameSyntax; var method = model.GetSymbolInfo(methodNameSyntax).Symbol as IMethodSymbol; if(method == null) return base.VisitArgument(node); var argList = (ArgumentListSyntax)node.Parent; //TODO check that parameter name preserved if specified, otherwise order can be broken var argIndex = argList.Arguments.IndexOf(node); var parameterSymbol = method.Parameters[argIndex]; //TODO when there is params argument in method index may be well out of range var lambda = node.Expression as LambdaExpressionSyntax; if(parameterSymbol.HasAttribute<MetaRewriteLambdaParamAttribute>(model.Compilation) && lambda != null) { //TODO error if value is not lambda return node.WithExpression(VisitLambdaExpression(lambda)); } if(parameterSymbol.HasAttribute<MetaRewriteParamAttribute>(model.Compilation)) return node.WithExpression(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(node.Expression.ToFullString()))); return base.VisitArgument(node); }
/// <summary> /// Lifts the expression represented by <paramref name="argument" />, if necessary. /// </summary> public override SyntaxNode VisitArgument(ArgumentSyntax argument) { if (argument.Parent.Parent is ElementAccessExpressionSyntax) return base.VisitArgument(argument); var requiresLifting = argument.HasAttribute<LiftExpressionAttribute>(SemanticModel); argument = (ArgumentSyntax)base.VisitArgument(argument); if (!requiresLifting) return argument; var expression = SyntaxBuilder.Lambda(Enumerable.Empty<ParameterSyntax>(), argument.Expression).WithTrivia(argument); return argument.WithExpression(expression); }
/// <summary> /// Normalizes the <paramref name="argument" />. /// </summary> public override SyntaxNode VisitArgument(ArgumentSyntax argument) { // Special case for array accesses, as Roslyn doesn't return a symbol for the argument if (argument.Parent.Parent is ElementAccessExpressionSyntax) { var arrayExpression = ((ElementAccessExpressionSyntax)argument.Parent.Parent).Expression; if (SemanticModel.GetTypeInfo(arrayExpression).Type.TypeKind == TypeKind.Array) return base.VisitArgument(argument); } var parameterSymbol = argument.GetParameterSymbol(SemanticModel); if (parameterSymbol.RefKind != RefKind.None) return base.VisitArgument(argument); var parameterType = DetermineType(parameterSymbol.Type); if (parameterType == ExpressionType.Other) return base.VisitArgument(argument); return argument.WithExpression(ReplaceImplicitConversion(parameterType, argument.Expression)); }
/// <summary> /// Normalizes the <paramref name="argument" />. /// </summary> public override SyntaxNode VisitArgument(ArgumentSyntax argument) { // Special case for array accesses, as Roslyn doesn't return a symbol for the argument if (argument.Parent.Parent is ElementAccessExpressionSyntax) { var arrayExpression = ((ElementAccessExpressionSyntax)argument.Parent.Parent).Expression; var kind = SemanticModel.GetTypeInfo(arrayExpression).Type.TypeKind; if (kind == TypeKind.Array || kind == TypeKind.Pointer) return base.VisitArgument(argument); } var parameterSymbol = argument.GetParameterSymbol(SemanticModel); if (parameterSymbol.RefKind != RefKind.None) return base.VisitArgument(argument); var arraySymbol = parameterSymbol.Type as IArrayTypeSymbol; var isParamsFormula = arraySymbol != null && parameterSymbol.IsParams && IsFormulaType(arraySymbol.ElementType); if (!isParamsFormula && !IsFormulaType(parameterSymbol.Type)) return base.VisitArgument(argument); return argument.WithExpression(ReplaceImplicitConversion(argument.Expression)); }