INode InitStaticVariable(string initFieldName, string variableName, Expression initializer, TypeDeclaration typeDeclaration) { const string helperMethodName = "InitStaticVariableHelper"; if (typeDeclaration != null) { if (!typeDeclaration.Children.OfType<MethodDeclaration>().Any(m => m.Name == helperMethodName)) { // add helper method var helperMethod = new MethodDeclaration { Name = helperMethodName, Modifier = Modifiers.Static, TypeReference = new TypeReference("System.Boolean", true), Parameters = { new ParameterDeclarationExpression(new TypeReference("Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag"), "flag") }, Body = new BlockStatement() }; BlockStatement trueBlock = new BlockStatement(); BlockStatement elseIfBlock = new BlockStatement(); BlockStatement falseBlock = new BlockStatement(); helperMethod.Body.AddStatement( new IfElseStatement(ExpressionBuilder.Identifier("flag").Member("State").Operator(BinaryOperatorType.Equality, new PrimitiveExpression(0))) { TrueStatement = { trueBlock }, ElseIfSections = { new ElseIfSection(ExpressionBuilder.Identifier("flag").Member("State").Operator(BinaryOperatorType.Equality, new PrimitiveExpression(2)), elseIfBlock) }, FalseStatement = { falseBlock } }); trueBlock.Assign(ExpressionBuilder.Identifier("flag").Member("State"), new PrimitiveExpression(2)); trueBlock.Return(new PrimitiveExpression(true)); elseIfBlock.Throw(new TypeReference("Microsoft.VisualBasic.CompilerServices.IncompleteInitialization").New()); falseBlock.Return(new PrimitiveExpression(false)); typeDeclaration.AddChild(helperMethod); } } BlockStatement tryBlock = new BlockStatement(); BlockStatement ifTrueBlock = new BlockStatement(); tryBlock.AddStatement(new IfElseStatement(ExpressionBuilder.Identifier(helperMethodName).Call(ExpressionBuilder.Identifier(initFieldName)), ifTrueBlock)); ifTrueBlock.Assign(ExpressionBuilder.Identifier(variableName), initializer); BlockStatement finallyBlock = new BlockStatement(); finallyBlock.Assign(ExpressionBuilder.Identifier(initFieldName).Member("State"), new PrimitiveExpression(1)); BlockStatement lockBlock = new BlockStatement(); lockBlock.AddStatement(new TryCatchStatement(tryBlock, null, finallyBlock)); return new LockStatement(ExpressionBuilder.Identifier(initFieldName), lockBlock); }
void ReplaceAllFunctionAssignments(BlockStatement block, string functionName, TypeReference typeReference) { ReturnStatementForFunctionAssignment visitor = new ReturnStatementForFunctionAssignment(functionName); block.AcceptVisitor(visitor, null); if (visitor.expressionsToReplace.Count == 1 && !visitor.hasExit && IsAssignmentTo(block.Children.Last(), functionName)) { Expression returnValue = GetAssignmentFromStatement(block.Children.Last()).Right; block.Children.RemoveAt(block.Children.Count - 1); block.Return(returnValue); } else { if (visitor.expressionsToReplace.Count > 0) { foreach (var expr in visitor.expressionsToReplace) { expr.Identifier = FunctionReturnValueName; } Expression init; init = ExpressionBuilder.CreateDefaultValueForType(typeReference); block.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, typeReference))); block.Children[0].Parent = block; block.Return(new IdentifierExpression(FunctionReturnValueName)); } } }