public void GenerateInto(Scope scope) { var hasReturn = SyntaxUtil.HasReturnStatement(Body); if (scope.IsInStatementContext) { if (hasReturn == false) { SyntaxUtil.CreateReturnStatement(this.returnType, Body, scope.StatementContext.TryCreateResultStatement); } foreach (var b in Body) { scope.StatementContext.AddStatement(b); } } else { if (hasReturn == false) { SyntaxUtil.CreateReturnStatement(this.returnType, Body, (ExpressionSyntax e, out StatementSyntax s) => { s = SyntaxFactory.ReturnStatement(e) .WithAdditionalAnnotations(ScriptGenAnnotations.ResultStatement); return(true); }); } scope.Context.AddExpression( SyntaxUtil.CreateImmediatelyInvokedFunction(returnType, Body)); } }
private SyntaxNode ProcessNamespace(SyntaxNode syntaxRoot) { var firstNamespace = syntaxRoot.DescendantNodesAndSelf().OfType <NamespaceDeclarationSyntax>().FirstOrDefault(); if (firstNamespace == null) { return(syntaxRoot); } var list = firstNamespace.GetLeadingTrivia(); if (list.Count == 0) { var newLine = SyntaxUtil.GetBestNewLineTrivia(firstNamespace); list = list.Add(newLine); return(syntaxRoot.ReplaceNode(firstNamespace, firstNamespace.WithLeadingTrivia(list))); } else if (list.Count == 1 && list[0].IsKind(SyntaxKind.EndOfLineTrivia)) { // The namespace node is typically preceeded by a using node. In thate case the trivia will // be split between the two nodes. If the namespace already has a newline leading trivia then // there is at least a single blank between the nodes as the using will have a trailing new // line as well (in case of a single on it will be on the using). return(syntaxRoot); } else { return(ProcessCore(syntaxRoot, firstNamespace)); } }
private static SyntaxToken FixCloseBraceLeadingTrivia(SyntaxToken token) { if (!token.HasLeadingTrivia) { return(token); } var triviaList = token.LeadingTrivia; if (triviaList.All(x => x.IsKind(SyntaxKind.WhitespaceTrivia) || x.IsKind(SyntaxKind.EndOfLineTrivia))) { // Simplest case. It's all new lines and white space. if (EndsWithSimpleNewLine(token.GetPreviousToken().TrailingTrivia)) { triviaList = SyntaxTriviaList.Empty; } else { // new line and we are done. triviaList = SyntaxFactory.TriviaList(SyntaxUtil.GetBestNewLineTrivia(token)); } } else { triviaList = RemoveNewLinesFromTop(triviaList); triviaList = RemoveNewLinesFromBottom(triviaList); } return(token.WithLeadingTrivia(triviaList)); }
public FieldGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, MemberNameRepository nameRepo) : base(node) { this.OwnDataType = node.DataType; if (node.NodeString == 0) { accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType)); } else { var stringVal = SyntaxUtil.GetScriptString(scenario, node); if (stringVal == "none") { accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType)); } else { if (nameRepo.TryGetName(stringVal, node.DataType.ToString(), node.NodeData_H16, out var finalName)) { accessor = SyntaxFactory.IdentifierName(finalName); } else { accessor = SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(stringVal)); } } } accessor = accessor.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType)); }
/// <summary> /// Get the new leading trivia list that will add the double blank line that we are looking /// for. /// </summary> private bool TryGetNewLeadingTrivia(SyntaxNode node, out SyntaxTriviaList newTriviaList) { var newLineTrivia = SyntaxUtil.GetBestNewLineTrivia(node); var list = node.GetLeadingTrivia(); var index = list.Count - 1; MoveBackwardsPastWhitespace(list, ref index); if (index < 0 || !list[index].IsAnyEndOfLine()) { // There is no newline before the using at all. Add a double newline to // get the blank we are looking for newTriviaList = list.InsertRange(index + 1, new[] { newLineTrivia, newLineTrivia }); return(true); } var wasDirective = list[index].IsDirective; index--; // Move past any directives that are above the token. The newline needs to // be above them. while (index >= 0 && list[index].IsDirective) { index--; } if (wasDirective) { // There was a directive above the using and index now points directly before // that. This token must be a new line. if (index < 0 || !list[index].IsKind(SyntaxKind.EndOfLineTrivia)) { newTriviaList = list.Insert(index + 1, newLineTrivia); return(true); } index--; } // In the logical line above the using. Need to see <blank><eol> in order for the // using to be correct var insertIndex = index + 1; MoveBackwardsPastWhitespace(list, ref index); if (index < 0 || !list[index].IsAnyEndOfLine()) { // If this is the first item in the file then there is no need for a double // blank line. if (index >= 0 || node.FullSpan.Start != 0) { newTriviaList = list.Insert(insertIndex, newLineTrivia); return(true); } } // The using is well formed so there is no work to be done. newTriviaList = SyntaxTriviaList.Empty; return(false); }
public VariableAccessContext(ScenarioTag tag, ScenarioTag.ScriptSyntaxNode node) : base(node) { this.OwnDataType = node.DataType; access = SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName( SyntaxUtil.SanitizeIdentifier( SyntaxUtil.GetScriptString(tag, node)))) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType)); }
public ScriptInvocationContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node) : base(node) { var method = scenario.ScriptMethods[node.OperationId]; invocation = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName( SyntaxUtil.SanitizeIdentifier(method.Description)))) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(method.ReturnType)); }
public TagGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node) : base(node) { this.OwnDataType = node.DataType; invocation = InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("Engine"), GenericName(Identifier(nameof(IScriptEngine.GetTag))) .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList( SyntaxUtil.ScriptTypeSyntax(this.OwnDataType.Value)))))) .AddArgumentListArguments( Argument(SyntaxUtil.LiteralExpression(SyntaxUtil.GetScriptString(scenario, node))), Argument(SyntaxUtil.LiteralExpression(node.NodeData_32))) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType)); }
public LiteralContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, Scope containing) : base(node) { this.OwnDataType = node.DataType; var dest = node.DataType; if (SyntaxUtil.NumericLiteralTypes.Contains(node.DataType) && containing.Context is BinaryOperatorContext bin && SyntaxUtil.NumericLiteralTypes.Contains(bin.OwnDataType.Value)) { dest = bin.OwnDataType.Value; } this.literal = SyntaxUtil.LiteralExpression(scenario, node, dest); }
public MethodCallContext AddArgument(ExpressionSyntax argument) { arguments.Add(SyntaxFactory.Argument(argument)); if (SyntaxUtil.TryGetTypeOfExpression(argument, out var t)) { argumentTypes.Add(t); } else { throw new System.Exception("Couldn't determine argument type"); } return(this); }
SyntaxNode AddNewLineToEndOfFileTokenLeadingTriviaIfNecessary(SyntaxNode syntaxRoot, SyntaxToken endofFileToken) { if (endofFileToken.LeadingTrivia.Last().IsKind(SyntaxKind.EndOfLineTrivia)) { return(syntaxRoot); } var newLine = SyntaxUtil.GetBestNewLineTriviaRecursive(endofFileToken.Parent); var newLastToken = endofFileToken.WithTrailingTrivia(endofFileToken.TrailingTrivia.Concat(new[] { newLine })); return(syntaxRoot.ReplaceToken(endofFileToken, newLastToken)); return(syntaxRoot); }
/// <summary> /// Remove all extra new lines from the begining of a close brace token. This is only called in /// the case at least one new line is present hence we don't have to worry about the single line /// case. /// </summary> private static SyntaxTriviaList RemoveNewLinesFromBottom(SyntaxTriviaList triviaList) { var index = triviaList.Count - 1; var searching = true; while (index >= 0 && searching) { var current = triviaList[index]; switch (current.Kind()) { case SyntaxKind.WhitespaceTrivia: case SyntaxKind.EndOfLineTrivia: index--; break; default: searching = false; break; } } // Nothing to adjust, the removal of new lines from the top of the list will handle all of the // important cases. if (index < 0) { return(triviaList); } var list = new List <SyntaxTrivia>(triviaList.Count); for (int i = 0; i <= index; i++) { list.Add(triviaList[i]); } // A directive has an implicit new line after it. if (!list[index].IsDirective) { list.Add(SyntaxUtil.GetBestNewLineTrivia(triviaList)); } if (triviaList.Last().IsKind(SyntaxKind.WhitespaceTrivia)) { list.Add(triviaList.Last()); } return(SyntaxFactory.TriviaList(list)); }
public UnknownContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node) : base(node) { this.OwnDataType = node.DataType; string unknownDescription = ""; if (node.NodeString > 0 && node.NodeString < scenario.ScriptStrings.Length && scenario.ScriptStrings[node.NodeString - 1] == 0) { unknownDescription = SyntaxUtil.GetScriptString(scenario, node); } unknownDescription += $" -{node.NodeType}<{node.DataType}>"; invocation = SyntaxFactory.InvocationExpression( SyntaxFactory.IdentifierName("UNKNOWN"), SyntaxFactory.ArgumentList( SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Argument(SyntaxUtil.LiteralExpression(unknownDescription))))); }
public SyntaxNode Process(SyntaxNode syntaxRoot, string languageName) { bool needsNewLine; var endOfFileToken = syntaxRoot.GetLastToken(true, true, true, true); if (!endOfFileToken.IsKind(SyntaxKind.EndOfFileToken)) { throw new InvalidOperationException("Expected last token to be EndOfFileToken, was actually: " + endOfFileToken.Kind()); } if (endOfFileToken.HasLeadingTrivia) { return(AddNewLineToEndOfFileTokenLeadingTriviaIfNecessary(syntaxRoot, endOfFileToken)); } var lastToken = syntaxRoot.GetLastToken(); if (!lastToken.HasTrailingTrivia) { needsNewLine = true; } else { var lastTrivia = lastToken.TrailingTrivia.Last(); if (lastTrivia.IsKind(SyntaxKind.EndOfLineTrivia)) { needsNewLine = false; } else { needsNewLine = true; } } if (needsNewLine) { var newLine = SyntaxUtil.GetBestNewLineTriviaRecursive(lastToken.Parent); var newLastToken = lastToken.WithTrailingTrivia(lastToken.TrailingTrivia.Concat(new[] { newLine })); return(syntaxRoot.ReplaceToken(lastToken, newLastToken)); } return(syntaxRoot); }
public void GenerateInto(Scope scope) { Debug.Assert(operands.Count >= 2, "Not enough operands for binary expression"); var ops = new Queue <ExpressionSyntax>(); foreach (var op in operands) { ops.Enqueue(op); } var left = ops.Dequeue(); ScriptDataType?topType = this.OwnDataType; while (ops.Any()) { var right = ops.Dequeue(); var binExp = SyntaxFactory.BinaryExpression(operatorSyntaxKind, left, right); if (numericPromotionOperators.Contains(this.operatorSyntaxKind) && SyntaxUtil.TryGetTypeOfExpression(left, out var leftType) && SyntaxUtil.TryGetTypeOfExpression(right, out var rightType)) { var promoted = SyntaxUtil.BinaryNumericPromotion(leftType, rightType); binExp = binExp.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(promoted)); topType = promoted; } left = binExp; } if (topType.HasValue && topType.Value != scope.Type) { left = SyntaxUtil.CreateCast(topType.Value, scope.Type, SyntaxFactory.ParenthesizedExpression(left)); } scope.Context.AddExpression(left); }
/// <summary> /// Don't allow consecutive newlines at the top of the comments / pragma before a close /// brace token. /// </summary> private static SyntaxTriviaList RemoveNewLinesFromTop(SyntaxTriviaList triviaList) { // This rule only needs to run if there is a new line at the top. if (!IsSimpleNewLine(triviaList, 0)) { return(triviaList); } var list = new List <SyntaxTrivia>(triviaList.Count); list.Add(SyntaxUtil.GetBestNewLineTrivia(triviaList)); var index = MovePastSimpleNewLines(triviaList, 0); while (index < triviaList.Count) { list.Add(triviaList[index]); index++; } return(SyntaxFactory.TriviaList(list)); }
public IStatementContext AddStatement(StatementSyntax statement) { if (statement is ExpressionStatementSyntax exp) { subexpressions.Add(exp.Expression); } else { var returnType = ScriptDataType.Void; var annotations = statement.GetAnnotations(ScriptGenAnnotations.TypeAnnotationKind); if (annotations.Any()) { returnType = (ScriptDataType)int.Parse(annotations.First().Data); } subexpressions.Add(SyntaxUtil.CreateImmediatelyInvokedFunction(returnType, new[] { statement })); } return(this); }
/// <summary> /// Get the new leading trivia list that will add the double blank line that we are looking /// for. /// </summary> private SyntaxTriviaList GetNewLeadingTrivia(SyntaxNode node) { var list = node.GetLeadingTrivia(); var searchIndex = 0; var newLineTrivia = SyntaxUtil.GetBestNewLineTrivia(node); var prev = node.FindPreviousNodeInParent(); if (prev == null) { if (node.Span.Start == 0) { // First item in the file. Do nothing for this case. return(list); } } else { // If there is no new line in the trailing trivia of the previous node then need to add // one to put this node on the next line. if (prev.GetTrailingTrivia().Count == 0 || !prev.GetTrailingTrivia().Last().IsAnyEndOfLine()) { list = list.Insert(0, newLineTrivia); searchIndex = 1; } } // Ensure there are blank above #pragma directives here. This is an attempt to maintain compatibility // with the original design of this rule which had special spacing rules for #pragma. No reason // was given for the special casing, only tests. if (searchIndex < list.Count && list[0].IsKind(SyntaxKind.PragmaWarningDirectiveTrivia) && list[0].FullSpan.Start != 0) { list = list.Insert(searchIndex, newLineTrivia); searchIndex++; } EnsureHasBlankLineAtEnd(ref list, searchIndex, newLineTrivia); return(list); }
public EntityGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, MemberNameRepository nameRepo) : base(node) { this.OwnDataType = node.DataType; if (node.NodeString == 0) { accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType)); } else { var stringVal = SyntaxUtil.GetScriptString(scenario, node); if (stringVal == "none") { accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType)); } else { if (nameRepo.TryGetName(stringVal, nameof(ScenarioTag.EntityReference), node.NodeData_H16, out var finalName)) { accessor = SyntaxFactory.IdentifierName(finalName); } else { accessor = SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(stringVal)); } if (node.DataType != ScriptDataType.EntityIdentifier) { accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, accessor, SyntaxFactory.IdentifierName(nameof(ScenarioEntity <object> .Entity))); } } } accessor = accessor.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType)); }
public void GenerateInto(Scope scope) { var invocationExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("Engine"), SyntaxFactory.IdentifierName(this.MethodName)); ExpressionSyntax invocation = SyntaxFactory.InvocationExpression(invocationExpression) .WithArgumentList(SyntaxFactory.ArgumentList( SyntaxFactory.SeparatedList(this.arguments))) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType)); var tempArgs = new List <Type>(); foreach (var t in argumentTypes) { if (t.HasValue && SyntaxUtil.TryGetTypeFromScriptType(t.Value, out var T)) { tempArgs.Add(T); } else { break; } } if (tempArgs.Count == argumentTypes.Count) { // Do full overload match var method = typeof(IScriptEngine).GetMethod(this.MethodName, BindingFlags.Public | BindingFlags.Instance, null, tempArgs.ToArray(), null); if (method != null) { SyntaxUtil.AwaitIfNeeded(method, ref invocation, out var materializedReturnType); if (SyntaxUtil.TryGetScriptTypeFromType(materializedReturnType, out var fromType)) { // Insert cast to destination invocation = SyntaxUtil.CreateCast(fromType, this.ReturnType, invocation) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType)); } } } else { // Fallback to name only lookup var scriptEngineMethods = typeof(IScriptEngine).GetMethods().Where(m => m.Name == this.MethodName); if (scriptEngineMethods.Any()) { //var hasOverload = scriptEngineMethods.Any(m => m.ReturnType == destinationType); //if (hasOverload == false) { var method = scriptEngineMethods.First(); SyntaxUtil.AwaitIfNeeded(method, ref invocation, out var materializedReturnType); if (SyntaxUtil.TryGetScriptTypeFromType(materializedReturnType, out var fromType) && fromType != this.ReturnType) { // Insert cast to destination invocation = SyntaxUtil.CreateCast(fromType, this.ReturnType, invocation) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType)); } } } } scope.Context.AddExpression(invocation); }
public AiGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, MemberNameRepository nameRepo) : base(node) { this.OwnDataType = node.DataType; if (node.NodeString == 0) { accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType)); } else { var stringVal = SyntaxUtil.GetScriptString(scenario, node); var slashIndex = stringVal.IndexOf('/'); if (slashIndex > 0) { Debug.Assert(node.NodeData_B0 == 192); // It's a squad member accessor var squadName = stringVal.Substring(0, slashIndex); var memberName = stringVal.Substring(slashIndex + 1); if (nameRepo.TryGetName(squadName, node.DataType.ToString(), node.NodeData_B1, out var finalSquad) && nameRepo.NestedRepos.TryGetValue(finalSquad, out var nestedRepo) && nestedRepo.TryGetName(memberName, node.DataType.ToString(), node.NodeData_H16, out var finalProp)) { accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(finalSquad)), SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(finalProp))); } else { accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(squadName)), SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(memberName))); } } else { // Ambiguous reference to either a squad or squad group...? if (nameRepo.TryGetName(stringVal, node.DataType.ToString(), node.NodeData_H16, out var finalSquad)) { if (nameRepo.NestedRepos.TryGetValue(finalSquad, out var nestedRepo)) { accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(finalSquad)), SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier("Squad"))); } else { accessor = SyntaxFactory.IdentifierName(finalSquad); } } else { accessor = SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(stringVal)); } } } accessor = accessor.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType)); }
public void GenerateInto(Scope scope) { Debug.Assert(scope == this.containingScope, "Generating into an unexpected scope"); Debug.Assert(this.condition != null, "Condition expression was not provided"); Debug.Assert(whenTrueStatements.Any(), "WhenTrue was not provided"); var generatedStatements = new List <StatementSyntax>(); if (this.producesValue) { var resultType = SyntaxUtil.ScriptTypeSyntax(this.containingScope.Type); // Ensure that if a value must be produced, we have an else with default value if (whenFalseStatements.Any() == false) { whenFalseStatements.Add(ExpressionStatement(DefaultExpression(resultType))); } if (this.shouldHoist) { var initialization = DefaultExpression(resultType); generatedStatements.Add(LocalDeclarationStatement(VariableDeclaration(resultType) .WithVariables(SingletonSeparatedList( VariableDeclarator(resultVariable.Identifier) .WithInitializer( EqualsValueClause(initialization))))) .WithAdditionalAnnotations(ScriptGenAnnotations.HoistedResultVar)); if (HasResultVarAssignment(whenTrueStatements) == false) { InsertResultVarAssignment(whenTrueStatements); } if (whenFalseStatements.Any() && HasResultVarAssignment(whenFalseStatements) == false) { InsertResultVarAssignment(whenFalseStatements); } } else { if (SyntaxUtil.HasReturnStatement(whenTrueStatements) == false) { SyntaxUtil.CreateReturnStatement(this.containingScope.Type, whenTrueStatements, (ExpressionSyntax e, out StatementSyntax s) => { s = ReturnStatement(e).WithAdditionalAnnotations(ScriptGenAnnotations.ResultStatement); return(true); }); } if (SyntaxUtil.HasReturnStatement(whenFalseStatements) == false) { SyntaxUtil.CreateReturnStatement(this.containingScope.Type, whenFalseStatements, (ExpressionSyntax e, out StatementSyntax s) => { s = ReturnStatement(e).WithAdditionalAnnotations(ScriptGenAnnotations.ResultStatement); return(true); }); } } } var trueBlock = Block(whenTrueStatements); var unreachable = this.condition.IsEquivalentTo(SyntaxUtil.LiteralExpression(true)); if (unreachable == false && whenFalseStatements.Any()) { StatementSyntax falseBlock = Block(whenFalseStatements); // Collapse if/else if/... if (whenFalseStatements.Count == 1 && whenFalseStatements[0] is IfStatementSyntax ifStatement) { falseBlock = ifStatement; } generatedStatements.Add( IfStatement(condition, trueBlock, ElseClause(falseBlock)) .WithLeadingTrivia(SyntaxFactory.Whitespace(Environment.NewLine)) .WithAdditionalAnnotations(ScriptGenAnnotations.IfStatement)); } else { generatedStatements.Add( IfStatement(condition, trueBlock) .WithLeadingTrivia(SyntaxFactory.Whitespace(Environment.NewLine)) .WithAdditionalAnnotations(ScriptGenAnnotations.IfStatement)); } if (this.shouldHoist == false && this.producesValue) { var last = generatedStatements.Last(); generatedStatements.Remove(last); generatedStatements.Add(last.WithAdditionalAnnotations(ScriptGenAnnotations.ResultStatement)); } if (scope.IsInStatementContext || this.shouldHoist) { // Insert statements into appropriate statement context foreach (var statement in generatedStatements) { scope.StatementContext.AddStatement(statement); } if (this.shouldHoist) { // Insert result var into place scope.Context.AddExpression(this.resultVariable); } } else { // Insert IIFE into place scope.Context.AddExpression(SyntaxUtil.CreateImmediatelyInvokedFunction(scope.Type, generatedStatements)); } }