private void addStart(List <StatementSyntax> start, ExpressionSyntax expr, bool leftOperand, string callbackName) { var success = Templates .StartCallback .Get <ExpressionSyntax>( _class.Name, callbackName, leftOperand ? Roslyn.@true : Roslyn.@null, leftOperand ? Roslyn.@null : Roslyn.@true, Roslyn.@null); var failure = Templates .StartCallback .Get <ExpressionSyntax>( _class.Name, callbackName, leftOperand ? Roslyn.@false : Roslyn.@null, leftOperand ? Roslyn.@null : Roslyn.@false, Templates.FailureParameter); start .Add(CSharp.ExpressionStatement(Templates .StartExpression .Get <ExpressionSyntax>(expr, success, failure))); }
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 SyntaxNode ExpressionStatement(RParser.ExpressionStatementContext exprStatement, Func <ParserRuleContext, Scope, SyntaxNode> transform, Scope scope) { var expr = transform(exprStatement.expr(), scope); Debug.Assert(expr != null); if (expr is ExpressionSyntax) { return(CSharp.ExpressionStatement(expr as ExpressionSyntax)); } return((StatementSyntax)expr); }
private StatementSyntax LinkExternalInvocation(InvocationExpressionSyntax invocation, InvocationExpressionSyntax success, InvocationExpressionSyntax failure) { var queueStatement = null as StatementSyntax; if (_class.isQueueInvocation(invocation, true, success, out queueStatement)) { return(queueStatement); } Debug.Assert(invocation.Expression is MemberAccessExpressionSyntax); Debug.Assert(!invocation.Expression .DescendantNodes() .OfType <InvocationExpressionSyntax>() .Any()); //td: errors var symbol = _model.GetSymbolInfo(invocation.Expression).Symbol; if (symbol != null) { if (isConcurrent(symbol)) { return(CSharp.ExpressionStatement( invocation .WithArgumentList(invocation .ArgumentList .AddArguments( CSharp.Argument(Templates.CancelationArgument), CSharp.Argument(Templates .SuccessFunction .Get <ExpressionSyntax>(success)), CSharp.Argument(Templates .FailureFunction .Get <ExpressionSyntax>(failure)))))); } if (isTask(symbol)) { return(Templates.TaskInvocation .Get <StatementSyntax>(invocation, success, failure)); } } return(Templates .NonConcurrentInvocation .Get <StatementSyntax>(invocation, success, failure)); }
private bool isFunctionalCall(InvocationExpressionSyntax invocation, out StatementSyntax functional) { functional = null; var containingClass = invocation .Ancestors() .OfType <ClassDeclarationSyntax>() .FirstOrDefault(); if (containingClass == null) { return(false); } var parentContainer = containingClass.Parent as ClassDeclarationSyntax; if (parentContainer == null || parentContainer.Identifier.ToString() != "Functions") { return(false); } var concurrentClassName = invocation.Expression.ToString() + "__concurrent"; var concurrentClass = parentContainer .Members .OfType <ClassDeclarationSyntax>() .SingleOrDefault(@class => @class.Identifier.ToString() == concurrentClassName); var newInvocation = default(InvocationExpressionSyntax); if (concurrentClass != null) { newInvocation = Templates.ConcurrentFunctionStatement .Get <InvocationExpressionSyntax>( concurrentClass.Identifier, (invocation.Expression as IdentifierNameSyntax) .Identifier); } else { newInvocation = Templates.FunctionStatement .Get <InvocationExpressionSyntax>(invocation.Expression); } functional = CSharp.ExpressionStatement(newInvocation); return(true); }
private StatementSyntax LinkThisInvocation(InvocationExpressionSyntax invocation, InvocationExpressionSyntax success, InvocationExpressionSyntax failure) { Debug.Assert(invocation.Expression is IdentifierNameSyntax); //internal calls StatementSyntax result; if (syntaxOperation(invocation, success, failure, out result)) { return(result); } else { var identifier = (invocation.Expression as IdentifierNameSyntax) .ToString(); var signal = _class.GetSignal(identifier); var functional = default(StatementSyntax); if (signal != null) { var expr = invocation .WithExpression(CSharp.IdentifierName("__concurrent" + identifier)) .WithArgumentList(invocation .ArgumentList .AddArguments( CSharp.Argument( Templates.CancelationArgument), CSharp.Argument(WrapInLambda(success) .AddParameterListParameters(CSharp.Parameter(CSharp.ParseToken( "__res")))), CSharp.Argument(WrapInLambda(failure) .AddParameterListParameters(CSharp.Parameter(CSharp.ParseToken( "__ex")))))); return(CSharp.ExpressionStatement(Templates .Advance .Get <ExpressionSyntax>(expr))); } else if (isFunctionalCall(invocation, out functional)) { return(functional); } return(CSharp.ExpressionStatement(invocation)); } }
private static BlockSyntax parseBlock(RParser.ExprContext expr, Func <ParserRuleContext, Scope, SyntaxNode> transform, Scope scope) { var node = transform(expr, scope); if (expr is RParser.CompoundContext) { return((BlockSyntax)node); } if (node is ExpressionSyntax) { node = CSharp.ExpressionStatement(node as ExpressionSyntax); } return(CSharp .Block() .WithStatements(CSharp.List(new StatementSyntax[] { (StatementSyntax)node }))); }
private StatementSyntax LinkOperand(ExpressionSyntax operand, InvocationExpressionSyntax success, InvocationExpressionSyntax failure, Dictionary <string, TypeSyntax> assignments) { if (operand is InvocationExpressionSyntax) { return(LinkProcessInvocation(operand as InvocationExpressionSyntax, success, failure)); } if (operand is IdentifierNameSyntax) { return(LinkSignal(operand as IdentifierNameSyntax, success, failure)); } if (operand is AssignmentExpressionSyntax) { return(LinkAssignment(operand as AssignmentExpressionSyntax, success, failure, assignments)); } if (operand is ParenthesizedExpressionSyntax) { return(LinkOperand((operand as ParenthesizedExpressionSyntax).Expression, success, failure, assignments)); } if (operand is LiteralExpressionSyntax) { var literal = operand as LiteralExpressionSyntax; switch (literal.Kind()) { case SyntaxKind.TrueLiteralExpression: case SyntaxKind.FalseLiteralExpression: return(CSharp.ExpressionStatement(success .ReplaceNodes(success .DescendantNodes() .OfType <LiteralExpressionSyntax>() .Where(l => l.Kind() == SyntaxKind.TrueLiteralExpression || l.Kind() == SyntaxKind.FalseLiteralExpression), (on, nn) => literal))); } } throw new NotImplementedException(); //td: }
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--; } }
private ParenthesizedLambdaExpressionSyntax WrapInLambda(IEnumerable <ExpressionSyntax> expressions) { return(CSharp.ParenthesizedLambdaExpression( CSharp.Block(expressions .Select(e => CSharp.ExpressionStatement(e))))); }
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) { var bodyStatement = (successFunc.Body as StatementSyntax) ?? CSharp.ExpressionStatement((ExpressionSyntax)successFunc.Body); 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[] { bodyStatement }) .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))); }