public override void WriteTo(CCodeWriterBase c) { c.Separate(); c.TextSpan(string.Format("// adapter: {0}", Method)); c.NewLine(); foreach (var statement in this.typeDefs) { statement.WriteTo(c); } var namedTypeSymbol = (INamedTypeSymbol)this.type; if (namedTypeSymbol.IsGenericType) { c.WriteTemplateDeclaration(namedTypeSymbol); c.NewLine(); } c.WriteMethodReturn(Method, true); c.WriteMethodNamespace(namedTypeSymbol); c.WriteMethodName(Method, false, interfaceWrapperMethodSpecialCase: true); c.WriteMethodParameters(Method, true, MethodBodyOpt != null); if (MethodBodyOpt == null) { c.EndStatement(); } else { MethodBodyOpt.WriteTo(c); } }
internal override void WriteTo(CCodeWriterBase c) { c.DecrementIndent(); foreach (var label in this.Labels) { if (label.Value != null) { var skipCaseForNullableWhenNull = this.SwitchType.IsValueType && label.Value.IsNull; if (!skipCaseForNullableWhenNull) { c.TextSpan("case"); c.WhiteSpace(); if (label.Value != null) { new Literal { Value = label.Value, Type = label.Type }.WriteTo(c); } else { label.WriteTo(c); } c.TextSpan(":"); } else { label.GenerateLabel = this.IsNullableType; } } else { c.TextSpan("default:"); if (this.IsNullableType) { label.GenerateLabel = true; } } c.NewLine(); if (label.GenerateLabel) { label.WriteTo(c); c.TextSpan(":"); c.NewLine(); } } c.IncrementIndent(); NoParenthesis = true; base.WriteTo(c); }
internal override void WriteTo(CCodeWriterBase c) { c.DecrementIndent(); foreach (var label in this.Labels) { if (label.Value != null) { var skipCaseForNullableWhenNull = this.SwitchType.IsValueType && label.Value.IsNull; if (!skipCaseForNullableWhenNull) { c.TextSpan("case"); c.WhiteSpace(); if (this.SwitchType.TypeKind == TypeKind.Enum) { c.TextSpan("("); c.WriteType(this.SwitchType, containingNamespace: MethodOwner?.ContainingNamespace); c.TextSpan(")"); } c.TextSpan(label.ToString()); c.TextSpan(":"); } else { label.GenerateLabel = this.IsNullableType; } } else { c.TextSpan("default:"); if (this.IsNullableType) { label.GenerateLabel = true; } } c.NewLine(); if (label.GenerateLabel) { label.WriteTo(c); c.TextSpan(":"); c.NewLine(); } } c.IncrementIndent(); NoParenthesis = true; base.WriteTo(c); }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("if"); c.WhiteSpace(); c.TextSpan("("); if (!this.JumpIfTrue) { c.TextSpan("!"); c.WriteWrappedExpressionIfNeeded(this.Condition); } else { this.Condition.WriteTo(c); } c.TextSpan(")"); c.NewLine(); c.OpenBlock(); new GotoStatement { Label = this.Label }.WriteTo(c); c.EndBlock(); c.Separate(); }
public override void WriteTo(CCodeWriterBase c) { c.TextSpan("class"); c.WhiteSpace(); this.Name(c); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("public"); c.WhiteSpace(); c.TextSpan("__methods_table"); c.NewLine(); c.OpenBlock(); c.DecrementIndent(); c.TextSpanNewLine("public:"); c.IncrementIndent(); foreach (var declaration in Declarations) { declaration.WriteTo(c); } c.EndBlockWithoutNewLine(); }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("[&]()"); c.NewLine(); c.OpenBlock(); foreach (var statement in this.Locals) { statement.WriteTo(c); } foreach (var expression in this.SideEffects) { expression.WriteTo(c); c.EndStatement(); } c.TextSpan("return"); c.WhiteSpace(); this.Value.WriteTo(c); c.EndStatement(); c.EndBlockWithoutNewLine(); c.TextSpan("()"); }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("for"); c.WhiteSpace(); c.TextSpan("("); PrintStatementAsExpression(c, this.InitializationOpt); c.TextSpan(";"); c.WhiteSpace(); if (this.ConditionOpt != null) { this.ConditionOpt.WriteTo(c); } c.TextSpan(";"); c.WhiteSpace(); PrintStatementAsExpression(c, this.IncrementingOpt); c.TextSpan(")"); c.NewLine(); base.WriteTo(c); }
internal override void WriteTo(CCodeWriterBase c) { if (this.locals.Count > 0) { c.OpenBlock(); foreach (var statement in this.locals) { statement.WriteTo(c); } } c.TextSpan("for"); c.WhiteSpace(); c.TextSpan("("); var block = this.Initialization as Block; if (block != null) { var any = false; foreach (var initializationItem in block.Statements) { if (any) { c.TextSpan(","); c.WhiteSpace(); } PrintStatementAsExpression(c, initializationItem); any = true; } } else { PrintStatementAsExpression(c, this.Initialization); } c.TextSpan(";"); c.WhiteSpace(); this.Condition.WriteTo(c); c.TextSpan(";"); c.WhiteSpace(); PrintStatementAsExpression(c, this.Incrementing); c.TextSpan(")"); c.NewLine(); base.WriteTo(c); if (this.locals.Count > 0) { c.EndBlock(); } }
internal override void WriteTo(CCodeWriterBase c) { CCodeWriterBase.SetLocalObjectIDGenerator(); // get actual statements var statements = Statements; if (statements.Count == 1 && statements.First().Kind == Kinds.BlockStatement) { var blockStatement = statements.First() as BlockStatement; if (blockStatement != null) { var block = blockStatement.Statements as Block; if (block != null) { statements = block.Statements; } } } var extraLocalDecls = this.SanitizeCode(statements); var skip = 0; ////if (this.MethodSymbol.MethodKind == MethodKind.Constructor) ////{ //// skip = ConstructorInitializer(c, statements); ////} c.NewLine(); c.OpenBlock(); foreach (var localDecl in extraLocalDecls) { var loadState = localDecl.Suppressed; localDecl.Suppressed = false; localDecl.WriteTo(c); localDecl.Suppressed = loadState; } if (MethodSymbol.MethodKind == MethodKind.StaticConstructor) { c.TextSpanNewLine("_cctor_being_called = true;"); } foreach (var statement in statements.Skip(skip)) { if (MethodSymbol.MethodKind == MethodKind.StaticConstructor && statement.Kind == Kinds.ReturnStatement) { c.TextSpanNewLine("_cctor_called = true;"); c.TextSpanNewLine("_cctor_being_called = false;"); } statement.WriteTo(c); } c.EndBlock(); }
internal override void WriteTo(CCodeWriterBase c) { if (this.FinallyBlockOpt != null) { var block = this.FinallyBlockOpt as Block; if (block != null) { block.SuppressNewLineAtEnd = true; } c.OpenBlock(); c.TextSpan("Finally"); c.WhiteSpace(); c.TextSpan("__finally_block"); c.TextSpan("("); new LambdaExpression() { Statements = block }.WriteTo(c); c.TextSpan(");"); c.NewLine(); } if (this.catchBlocks.Any()) { c.TextSpan("try"); } c.NewLine(); c.WriteBlockOrStatementsAsBlock(this.TryBlock); foreach (var catchBlock in this.catchBlocks) { catchBlock.WriteTo(c); } if (this.FinallyBlockOpt != null) { c.EndBlock(); } c.Separate(); }
internal override void WriteTo(CCodeWriterBase c) { c.SaveAndSet0Indent(); this.Label.WriteTo(c); c.TextSpan(":"); c.RestoreIndent(); c.NewLine(); c.RequireEmptyStatement(); }
/// <summary> /// </summary> /// <param name="c"> /// </param> /// <param name="newNonStaticMethod"> /// </param> /// <param name="nonStaticType"> /// </param> private static void WriteNewMethod(CCodeWriterBase c, IMethodSymbol newNonStaticMethod, NamedTypeImpl nonStaticType) { c.WriteMethodDeclaration(newNonStaticMethod, true, true); c.NewLine(); c.OpenBlock(); var objectCreationExpression = new ObjectCreationExpression { Type = nonStaticType, NewOperator = true }; foreach (var parameter in newNonStaticMethod.Parameters) { Expression parameterExpression = new Parameter { ParameterSymbol = parameter }; if (parameter.Name == "m") { parameterExpression = new Cast { Operand = parameterExpression, MapPointerCast = true, MapPointerCastTypeParameter1 = new Access { AccessType = Access.AccessTypes.DoubleColon, ReceiverOpt = new TypeExpression { Type = nonStaticType, TypeNameRequred = true }, Expression = new Parameter { ParameterSymbol = new ParameterImpl { Name = "_Memptr" } } }, MapPointerCastTypeParameter2 = new TypeExpression { Type = new TypeImpl { TypeKind = TypeKind.TypeParameter, Name = "_Memptr" } }, }; } objectCreationExpression.Arguments.Add(parameterExpression); } new ReturnStatement { ExpressionOpt = objectCreationExpression }.WriteTo(c); c.EndBlockWithoutNewLine(); c.EndStatement(); }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("while"); c.WhiteSpace(); c.TextSpan("("); this.Condition.WriteTo(c); c.TextSpan(")"); c.NewLine(); base.WriteTo(c); }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("if"); c.WhiteSpace(); c.TextSpan("("); this.Condition.WriteTo(c); c.TextSpan(")"); c.NewLine(); c.WriteBlockOrStatementsAsBlock(this.IfStatements); if (this.ElseStatementsOpt != null) { c.TextSpan("else"); c.NewLine(); c.WriteBlockOrStatementsAsBlock(this.ElseStatementsOpt); } c.Separate(); // No normal ending of Statement as we do not need extra ; }
public override void WriteTo(CCodeWriterBase c) { c.TextSpan("class"); c.WhiteSpace(); this.Name(c); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("public"); c.WhiteSpace(); c.WriteTypeFullName(this.@interface); c.NewLine(); c.OpenBlock(); c.DecrementIndent(); c.TextSpanNewLine("public:"); c.IncrementIndent(); // write default constructor this.Name(c); c.TextSpan("("); c.WriteType(Type, false, true, true); c.WhiteSpace(); c.TextSpan("class_"); c.TextSpan(")"); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("_class{class_}"); c.WhiteSpace(); c.TextSpanNewLine("{}"); // add new method var namedTypeSymbol = (INamedTypeSymbol)Type; // not needed as we use global normal allocator ////new CCodeNewOperatorDeclaration(@interface).WriteTo(c); new CCodeObjectCastOperatorDefinition(namedTypeSymbol).WriteTo(c); foreach (var declaration in Declarations) { declaration.WriteTo(c); } c.EndBlockWithoutNewLine(); }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("do"); c.NewLine(); NoSeparation = true; base.WriteTo(c); c.TextSpan("while"); c.WhiteSpace(); c.TextSpan("("); this.Condition.WriteTo(c); c.TextSpan(")"); c.EndStatement(); }
internal override void WriteTo(CCodeWriterBase c) { CCodeWriterBase.SetLocalObjectIDGenerator(); // get actual statements var statements = Statements; if (statements.Count == 1 && statements.First().Kind == Kinds.BlockStatement) { var blockStatement = statements.First() as BlockStatement; if (blockStatement != null) { var block = blockStatement.Statements as Block; if (block != null) { statements = block.Statements; } } } this.SanitizeCaseLabelsAndSetReturnTypes(statements); var skip = 0; ////if (this.MethodSymbol.MethodKind == MethodKind.Constructor) ////{ //// skip = ConstructorInitializer(c, statements); ////} c.NewLine(); c.OpenBlock(); if (this.MethodSymbol.MethodKind == MethodKind.StaticConstructor) { c.TextSpanNewLine("_cctor_called = true;"); } foreach (var statement in statements.Skip(skip)) { statement.WriteTo(c); } c.EndBlock(); }
internal override void WriteTo(CCodeWriterBase c) { if (this.locals.Count > 0) { c.OpenBlock(); foreach (var statement in this.locals) { statement.WriteTo(c); } } c.TextSpan("for"); c.WhiteSpace(); c.TextSpan("("); PrintStatementAsExpression(c, this.InitializationOpt); c.TextSpan(";"); c.WhiteSpace(); if (this.ConditionOpt != null) { this.ConditionOpt.WriteTo(c); } c.TextSpan(";"); c.WhiteSpace(); PrintStatementAsExpression(c, this.IncrementingOpt); c.TextSpan(")"); c.NewLine(); base.WriteTo(c); if (this.locals.Count > 0) { c.EndBlock(); } }
public override void WriteTo(CCodeWriterBase c) { c.TextSpan("class"); c.WhiteSpace(); this.Name(c); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("public"); c.WhiteSpace(); c.WriteTypeFullName(this.@interface); c.NewLine(); c.OpenBlock(); c.DecrementIndent(); c.TextSpanNewLine("public:"); c.IncrementIndent(); // write default constructor this.Name(c); c.TextSpan("("); c.WriteType(Type, false, true, true); c.WhiteSpace(); c.TextSpan("class_"); c.TextSpan(")"); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("_class{class_}"); c.WhiteSpace(); c.TextSpanNewLine("{}"); foreach (var declaration in Declarations) { declaration.WriteTo(c); } c.EndBlockWithoutNewLine(); }
public override void WriteTo(CCodeWriterBase c) { c.TextSpan(string.Format("// adapter: {0}", Method)); c.NewLine(); foreach (var statement in this.typeDefs) { statement.WriteTo(c); } c.WriteMethodReturn(Method, true); c.WriteMethodName(Method, allowKeywords: false, interfaceWrapperMethodSpecialCase: true); c.WriteMethodParameters(Method, true, MethodBodyOpt != null); if (MethodBodyOpt == null) { c.EndStatement(); } else { MethodBodyOpt.WriteTo(c); } }
internal override void WriteTo(CCodeWriterBase c) { c.TextSpan("catch"); c.WhiteSpace(); c.TextSpan("("); if (this.ExceptionTypeOpt != null) { c.WriteType(this.ExceptionTypeOpt); if (this.ExceptionSourceOpt != null) { c.WhiteSpace(); this.ExceptionSourceOpt.WriteTo(c); } } else { c.TextSpan("..."); } c.TextSpan(")"); c.NewLine(); c.WriteBlockOrStatementsAsBlock(Statements); }
internal override void WriteTo(CCodeWriterBase c) { Local localCase = null; if (this.stringEquality != null) { c.OpenBlock(); var localImpl = new LocalImpl { Name = "__SwitchExpression", Type = this.expression.Type }; var local = new Local { LocalSymbol = localImpl }; var localImplCase = new LocalImpl { Name = "__SwitchCase", Type = new TypeImpl { SpecialType = SpecialType.System_Int32 } }; localCase = new Local { LocalSymbol = localImplCase }; new VariableDeclaration { Local = localCase }.WriteTo(c); new VariableDeclaration { Local = local }.WriteTo(c); // first if IfStatement first = null; IfStatement last = null; var caseIndex = 0; foreach (var switchSection in this.switchCases) { foreach (var label in switchSection.Labels) { if (label.Value == null) { // default case; continue; } caseIndex++; // compare var callEqual = new Call() { Method = this.stringEquality }; callEqual.Arguments.Add(local); callEqual.Arguments.Add(new Literal { Value = label.Value }); // set value var setExpr = new ExpressionStatement { Expression = new AssignmentOperator { Left = localCase, Right = new Literal { Value = ConstantValue.Create(caseIndex) } } }; var ifStatement = new IfStatement { Condition = new BinaryOperator { OperatorKind = BinaryOperatorKind.Equal, Left = new Literal { Value = ConstantValue.Create(0) }, Right = callEqual }, IfStatements = setExpr }; first = first ?? ifStatement; if (last != null) { last.ElseStatementsOpt = ifStatement; } last = ifStatement; // remap case value label.Value = ConstantValue.Create(caseIndex); } } if (first != null) { first.WriteTo(c); } c.Separate(); } foreach (var statement in this.statements) { statement.WriteTo(c); } c.TextSpan("switch"); c.WhiteSpace(); c.TextSpan("("); if (this.stringEquality != null) { localCase.WriteTo(c); } else { this.expression.WriteTo(c); } c.TextSpan(")"); c.NewLine(); c.OpenBlock(); foreach (var switchSection in this.switchCases) { switchSection.WriteTo(c); } c.EndBlock(); if (this.stringEquality != null) { c.EndBlock(); } c.Separate(); }
internal override void WriteTo(CCodeWriterBase c) { CCodeWriterBase.SetLocalObjectIDGenerator(); // get actual statements var statements = Statements; if (statements.Count == 1 && statements.First().Kind == Kinds.BlockStatement) { var blockStatement = statements.First() as BlockStatement; if (blockStatement != null) { var block = blockStatement.Statements as Block; if (block != null) { statements = block.Statements; } } } var extraLocalDecls = this.SanitizeCode(statements); var skip = 0; ////if (this.MethodSymbol.MethodKind == MethodKind.Constructor) ////{ //// skip = ConstructorInitializer(c, statements); ////} c.NewLine(); c.OpenBlock(); foreach (var localDecl in extraLocalDecls) { var loadState = localDecl.Suppressed; localDecl.Suppressed = false; localDecl.WriteTo(c); localDecl.Suppressed = loadState; } if (MethodSymbol.MethodKind == MethodKind.StaticConstructor) { c.TextSpanNewLine("_cctor_being_called = true;"); } #region Virtual Generic methods support if (MethodSymbol.MethodKind == MethodKind.Constructor) { foreach (var typeParameter in MethodSymbol.ContainingType.GetTemplateParameters().Where(t => t.HasConstructorConstraint)) { c.TextSpanNewLine(string.Format("this->construct_{0} = construct_{0};", typeParameter.Name)); } } #endregion foreach (var statement in statements.Skip(skip)) { if (MethodSymbol.MethodKind == MethodKind.StaticConstructor && statement.Kind == Kinds.ReturnStatement) { c.TextSpanNewLine("_cctor_called = true;"); c.TextSpanNewLine("_cctor_being_called = false;"); } statement.WriteTo(c); } c.EndBlock(); }
/// <summary> /// </summary> /// <param name="c"> /// </param> public override void WriteTo(CCodeWriterBase c) { // non-static var nonStaticType = this.GetDelegateType(); if (nonStaticType.IsGenericType) { c.WriteTemplateDeclaration(nonStaticType); } c.TextSpan("class"); c.WhiteSpace(); c.WriteTypeName(nonStaticType); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("public"); c.WhiteSpace(); c.WriteTypeFullName(Type); c.NewLine(); c.OpenBlock(); c.DecrementIndent(); c.TextSpanNewLine("public:"); c.IncrementIndent(); // typedef c.TextSpanNewLine("typedef typename std::remove_pointer<_T>::type _Ty;"); c.TextSpan("typedef "); c.WriteType(this.invoke.ReturnType); c.WhiteSpace(); c.TextSpan("(_Ty::* _Memptr)"); c.WriteMethodParameters(this.invoke, true, false); c.TextSpanNewLine(";"); // fields c.TextSpanNewLine("_Ty* _t;"); c.TextSpanNewLine("_Memptr _memptr;"); // write default constructor c.WriteTypeName(nonStaticType); c.TextSpanNewLine("(_Ty* t, _Memptr memptr) : _t(t), _memptr(memptr) { CoreLib::System::Delegate::_target = object_cast(t); CoreLib::System::Delegate::_methodPtr = __init<CoreLib::System::IntPtr>(map_pointer_cast<void*, _Memptr>(memptr)); }"); // write invoke this.CreateInvokeMethod().WriteTo(c); // write clonse this.CreateCloneMethod().WriteTo(c); foreach (var declaration in Declarations) { declaration.WriteTo(c); } c.EndBlockWithoutNewLine(); c.EndStatement(); var newNonStaticMethod = this.GetNewMethod(); WriteNewMethod(c, newNonStaticMethod, nonStaticType); // static var staticType = this.GetDelegateType(true); if (staticType.IsGenericType) { c.WriteTemplateDeclaration(staticType); } c.TextSpan("class"); c.WhiteSpace(); c.WriteTypeName(staticType); c.WhiteSpace(); c.TextSpan(":"); c.WhiteSpace(); c.TextSpan("public"); c.WhiteSpace(); c.WriteTypeFullName(Type); c.NewLine(); c.OpenBlock(); c.DecrementIndent(); c.TextSpanNewLine("public:"); c.IncrementIndent(); // typedef c.TextSpan("typedef "); c.WriteType(this.invoke.ReturnType); c.WhiteSpace(); c.TextSpan("(* _Memptr)"); c.WriteMethodParameters(this.invoke, true, false); c.TextSpanNewLine(";"); // fields c.TextSpanNewLine("_Memptr _memptr;"); // write default constructor c.WriteTypeName(staticType); c.TextSpanNewLine("(_Memptr memptr) : _memptr(memptr) { CoreLib::System::Delegate::_methodPtr = __init<CoreLib::System::IntPtr>(map_pointer_cast<void*, _Memptr>(memptr)); }"); // write invoke this.CreateInvokeMethod(true).WriteTo(c); // write clonse this.CreateCloneMethod(true).WriteTo(c); foreach (var declaration in Declarations) { declaration.WriteTo(c); } c.EndBlockWithoutNewLine(); c.EndStatement(); var newStaticMethod = this.GetNewMethod(true); WriteNewMethod(c, newStaticMethod, staticType); }
internal override void WriteTo(CCodeWriterBase c) { Local localCase = null; if (this.stringEquality != null) { c.OpenBlock(); var localImpl = new LocalImpl { Name = "__SwitchExpression", Type = this.expression.Type }; var local = new Local { LocalSymbol = localImpl }; var localImplCase = new LocalImpl { Name = "__SwitchCase", Type = new TypeImpl { SpecialType = SpecialType.System_Int32 } }; localCase = new Local { LocalSymbol = localImplCase }; new VariableDeclaration { Statements = { new ExpressionStatement { Expression = new AssignmentOperator { TypeDeclaration = true, Type = new TypeImpl { SpecialType = SpecialType.System_Int32 }, Left = localCase, Right = new Literal{ Value = ConstantValue.Create(0) } } } } }.WriteTo(c); new VariableDeclaration { Statements = { new ExpressionStatement { Expression = new AssignmentOperator { TypeDeclaration = true, Type = new TypeImpl { SpecialType = SpecialType.System_String }, Left = local, Right = this.expression } } } }.WriteTo(c); // first if IfStatement first = null; IfStatement last = null; var caseIndex = 0; foreach (var switchSection in this.switchCases) { foreach (var label in switchSection.Labels) { if (label.Value == null) { // default case; continue; } caseIndex++; // compare var callEqual = new Call() { Method = this.stringEquality }; callEqual.Arguments.Add(local); callEqual.Arguments.Add(new Literal { Value = label.Value }); // set value var setExpr = new ExpressionStatement { Expression = new AssignmentOperator { Left = localCase, Right = new Literal { Value = ConstantValue.Create(caseIndex) } } }; var ifStatement = new IfStatement { Condition = callEqual, IfStatements = setExpr }; first = first ?? ifStatement; if (last != null) { last.ElseStatementsOpt = ifStatement; } last = ifStatement; // remap case value label.Value = ConstantValue.Create(caseIndex); } } if (first != null) { first.WriteTo(c); } c.Separate(); } foreach (var statement in this.statements) { statement.WriteTo(c); } var generateDefaultLabel = this.isNullableType; if (this.isNullableType) { var nullCase = this.switchCases.FirstOrDefault(sc => sc.Labels.Any(l => l.Value != null && l.Value.IsNull)); if (nullCase != null) { generateDefaultLabel = false; } var nullCaseOrDefault = nullCase ?? this.switchCases.FirstOrDefault(sc => sc.Labels.Any(l => l.Value == null)); if (nullCaseOrDefault != null) { var effectiveExpression = this.expression; var callExpression = this.expression as Call; if (callExpression != null) { effectiveExpression = new UnaryOperator { OperatorKind = UnaryOperatorKind.LogicalNegation, Operand = new Call { ReceiverOpt = callExpression.ReceiverOpt, Method = new MethodImpl { Name = "get_HasValue", Parameters = ImmutableArray <IParameterSymbol> .Empty } } }; } // we need to insert nullable goto; var ifStatement = new IfStatement { Condition = effectiveExpression, IfStatements = new GotoStatement { Label = nullCaseOrDefault.Labels.First(l => l.Value == null || l.Value.IsNull) } }; ifStatement.WriteTo(c); } } c.TextSpan("switch"); c.WhiteSpace(); c.TextSpan("("); if (this.stringEquality != null) { localCase.WriteTo(c); } else { this.expression.WriteTo(c); } c.TextSpan(")"); c.NewLine(); c.OpenBlock(); foreach (var switchSection in this.switchCases) { if (!generateDefaultLabel && switchSection.Labels.Any(l => l.Value == null)) { switchSection.IsNullableType = false; } switchSection.WriteTo(c); } c.EndBlock(); if (this.stringEquality != null) { c.EndBlock(); } c.Separate(); }