public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { var awaitExpr = null as ExpressionSyntax; var extraStatement = null as StatementSyntax; if (node.Declaration.Variables.Count == 1) { var variable = node .Declaration .Variables[0]; var value = variable ?.Initializer ?.Value; if (node.Declaration.Type.ToString() == "await") { //case: await signal; awaitExpr = CSharp.IdentifierName(variable.Identifier); } else if (value != null && value is AwaitExpressionSyntax) { //case: var a = await b(); extraStatement = CSharp .LocalDeclarationStatement(CSharp.VariableDeclaration( node.Declaration.Type, CSharp.SeparatedList(new[] { CSharp.VariableDeclarator(variable.Identifier) }))); awaitExpr = CSharp.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, CSharp.IdentifierName(variable.Identifier), (value as AwaitExpressionSyntax) .Expression); } } if (awaitExpr != null) { var result = VisitExpressionStatement(Templates .AwaitExpr .Get <ExpressionStatementSyntax>(awaitExpr)) as StatementSyntax; if (extraStatement != null) { var block = Roslyn.TrackNode(CSharp.Block( extraStatement, result)); var document = _scope.GetDocument(); document.change(node.Parent, Roslyn.ExplodeBlock(block)); return(block); } return(result); } return(base.VisitLocalDeclarationStatement(node)); }
private StatementSyntax LinkAssignment(AssignmentExpressionSyntax assignment, InvocationExpressionSyntax success, InvocationExpressionSyntax failure, Dictionary <string, TypeSyntax> assignments) { var leftString = assignment.Left.ToString(); var leftType = Roslyn.SymbolTypeSyntax(_model, assignment.Left); Debug.Assert(assignment.Left is IdentifierNameSyntax); Debug.Assert(!assignments.ContainsKey(leftString)); Debug.Assert(leftType != null); //td: error assignments[leftString] = leftType; var emptyAssignments = new Dictionary <string, TypeSyntax>(); var right = LinkOperand(assignment.Right, success, failure, emptyAssignments); Debug.Assert(right != null); Debug.Assert(!emptyAssignments.Any()); //there are 2 scenarios, first, the right operand was a concurrent expression //in which case it would have a success function var successFunc = right .DescendantNodes() .OfType <ParenthesizedLambdaExpressionSyntax>() .Where(fn => fn .ParameterList .Parameters .Any(p => p.Identifier.ToString() == "__res")) .SingleOrDefault(); if (successFunc != null) { return(right.ReplaceNode(successFunc, successFunc .WithBody(CSharp.Block(new[] { Templates .ExpressionAssigment .Get <StatementSyntax>(assignment.Left, leftType) } .Union(successFunc.Body is BlockSyntax ? (successFunc.Body as BlockSyntax) .Statements .AsEnumerable() : new[] { successFunc.Body as StatementSyntax }) .ToArray())))); } //else, we need to substitute the actual Right expr by //an assignment. var rightString = assignment.Right.ToString(); return(right.ReplaceNodes(right. DescendantNodes() .OfType <ExpressionSyntax>() .Where(node => node.ToString().Equals(rightString)), (on, nn) => CSharp.AssignmentExpression( assignment.Kind(), Templates .ExpressionProperty .Get <ExpressionSyntax>(assignment.Left), nn))); }
private static StatementSyntax InjectionAssignment(MemberDeclarationSyntax member) { var type = null as TypeSyntax; var identifier = MemberIdentifier(member, out type); return(CSharp.ExpressionStatement(CSharp.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, CSharp.IdentifierName(identifier), CSharp.IdentifierName("__" + identifier.ToString())))); }
private static ExpressionSyntax Assignment(ParserRuleContext node) { if (node.ChildCount == 1) { return(Expression(node.GetRuleContext <ParserRuleContext>(0))); } Debug.Assert(node.ChildCount == 3); var left = visitNode(node.GetRuleContext <ParserRuleContext>(0)); var right = visitNode(node.GetRuleContext <ParserRuleContext>(2)); SyntaxKind kind; var op = GetBinaryOperator(node.children[1].GetText(), out kind); return(CSharp.AssignmentExpression(kind, left, op, right)); }
private SyntaxNode Parse(BinaryExpressionSyntax expression, SyntaxToken actor) { var exprClassName = uniqueId("__expr"); _operators = new List <Operator>(); var startStatements = new List <StatementSyntax>(); var root = build(expression, null, false, startStatements); if (!_operators.Any()) { return(expression); } var members = new List <MemberDeclarationSyntax>(); foreach (var op in _operators) { if (op.Eval != null) { members.Add(op.Eval); } if (op.LeftValue != null) { members.Add(op.LeftValue); } if (op.RightValue != null) { members.Add(op.RightValue); } if (op.StartName != null && op.StartName.Any()) { members.Add(Templates .OperatorStartField .Get <MemberDeclarationSyntax>(op.StartName, exprClassName)); } } var exprClass = Templates .ExpressionClass .Get <ClassDeclarationSyntax>(exprClassName) .WithMembers(CSharp.List( members)); _class.AddType(exprClass); var startFunc = StartFunction(startStatements, exprClassName, false); var result = Templates .ExpressionInstantiation .Get <StatementSyntax>(exprClassName, startFunc, actor); return(result.ReplaceNodes(result.DescendantNodes() .OfType <InitializerExpressionSyntax>(), (on, nn) => nn .AddExpressions(_operators .Where(op => !string.IsNullOrEmpty(op.StartName)) .Select(op => (ExpressionSyntax)CSharp.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, CSharp.IdentifierName(op.StartName), StartFunction(op.Start, exprClassName, true))) .ToArray()))); }
public override SyntaxNode VisitTryStatement(TryStatementSyntax node) { _trysInStack++; try { var newNode = (TryStatementSyntax)base.VisitTryStatement(node); if (_tryConcurrent) { var variableName = "__try" + _trysInStack; _tryVariables.Add(variableName); //we can only split on expressions directly on the try level //i.e. no try { if () { EXPRESSION }} if (_trysInStack > 1 && !(newNode.Parent.Parent is TryStatementSyntax)) { Debug.Assert(false); //td: error return(newNode); } var statements = new List <StatementSyntax>(newNode.Block.Statements); var newStatements = new List <StatementSyntax>(); var currentIndex = 0; while (currentIndex < statements.Count) { var oldIndex = currentIndex; for (int i = oldIndex; i < statements.Count; i++, currentIndex++) { var statement = statements[i]; if (statement is YieldStatementSyntax) { newStatements.Add(newNode .WithBlock(CSharp.Block( statements .Skip(oldIndex) .Take(currentIndex - oldIndex - 1)))); //variable and return yield //td: assert newStatements.Add(statements[currentIndex - 1]); newStatements.Add(statements[currentIndex++]); break; } //must make variables available to later code, unless it precedes a yield var yieldNext = statements.Count > i + 1 && statements[i + 1] is YieldStatementSyntax; if (statement is LocalDeclarationStatementSyntax && !yieldNext) { var decl = statement as LocalDeclarationStatementSyntax; var varType = decl.Declaration.Type; if (varType == null || varType.Kind() == SyntaxKind.TypeVarKeyword) { varType = Roslyn.SymbolTypeSyntax(_model, decl .Declaration .Variables[0] .Initializer .Value); } Debug.Assert(varType != null, "Untyped local variable on try fix"); var assignmentStatements = new List <StatementSyntax>(); newStatements.Add(decl .WithDeclaration(decl.Declaration .WithType(varType) .WithVariables(CSharp.SeparatedList( decl .Declaration .Variables .Select(v => { assignmentStatements.Add(CSharp.ExpressionStatement( CSharp.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, CSharp.IdentifierName(v.Identifier), v.Initializer.Value))); return(v.WithInitializer(v .Initializer .WithValue(Templates .DefaultValue .Get <ExpressionSyntax>(varType)))); }))))); //once moved the variables "up" scope //we must keep the assignments Debug.Assert(assignmentStatements.Any()); statements.RemoveAt(i); statements.InsertRange(i, assignmentStatements); } } } Debug.Assert(newStatements.Any()); return(LinkTryStatements(newStatements, variableName)); } return(newNode); } finally { _trysInStack--; } }