IOperationClassWriter.cs (119)
73WriteLine("{");
80WriteLine("}");
140WriteLine("#region Interfaces");
146WriteLine("#endregion");
180WriteLine("// Licensed to the .NET Foundation under one or more agreements.");
181WriteLine("// The .NET Foundation licenses this file to you under the MIT license.");
182WriteLine("// See the LICENSE file in the project root for more information.");
183WriteLine("// < auto-generated />");
184WriteLine("#nullable enable");
190WriteLine($"using {nsName};");
195WriteLine($"namespace Microsoft.CodeAnalysis{(namespaceSuffix is null ? "" : $".{namespaceSuffix}")}");
209WriteLine($"{(node.IsInternal ? "internal" : "public")} interface {node.Name} : {node.Base}");
244WriteLine($"/// <{el.LocalName}>");
255WriteLine($"/// {line.Substring(indentation)}");
264WriteLine($"/// </{el.LocalName}>");
269WriteLine("/// <remarks>");
271WriteLine("/// </remarks>");
279WriteLine("/// <para>This node is associated with the following operation kinds:</para>");
280WriteLine("/// <list type=\"bullet\">");
283WriteLine($"/// <item><description><see cref=\"OperationKind.{kind}\"/></description></item>");
285WriteLine("/// </list>");
288WriteLine("/// <para>This interface is reserved for implementation by its associated APIs. We reserve the right to");
289WriteLine("/// change it in the future.</para>");
299WriteLine($"{modifiers}{prop.Type} {prop.Name} {{ get; }}");
304WriteLine("/// <summary>");
305WriteLine("/// All of the kinds of operations, including statements and expressions.");
306WriteLine("/// </summary>");
307WriteLine("public enum OperationKind");
310WriteLine("/// <summary>Indicates an <see cref=\"IOperation\"/> for a construct that is not implemented yet.</summary>");
311WriteLine("None = 0x0,");
341WriteLine($"// Unused: {i:x}");
374WriteLine($"/// <summary>Indicates an <see cref=\"{operationName}\"/>.{(extraText is object ? $" {extraText}" : "")}</summary>");
378WriteLine("[EditorBrowsable(EditorBrowsableState.Never)]");
383WriteLine($"[Obsolete({obsoleteMessage}, error: {obsoleteError})]");
386WriteLine($"{kind} = 0x{value:x},");
392WriteLine("#region Implementations");
401WriteLine("#endregion");
464WriteLine($"public override ITypeSymbol? Type {(node.HasType ? "{ get; }" : "=> null;")}");
466WriteLine($"internal override ConstantValue? OperationConstantValue {(hasConstantValue ? "{ get; }" : "=> null;")}");
470WriteLine("public override OperationKind Kind { get; }");
475WriteLine($"public override OperationKind Kind => OperationKind.{kind};");
485WriteLine($"internal {extensibility} partial class {@class} : {baseType}, {@interface}");
530WriteLine(")");
556WriteLine(" { }");
570WriteLine($"{prop.Name}Convertible = {prop.Name.ToCamelCase()};");
577WriteLine($"{prop.Name} = {initializer};");
583WriteLine("OperationConstantValue = constantValue;");
588WriteLine("Type = type;");
593WriteLine("Kind = kind;");
606WriteLine($"internal IConvertibleConversion {prop.Name}Convertible {{ get; }}");
607WriteLine($"public CommonConversion {prop.Name} => {prop.Name}Convertible.ToCommonConversion();");
630WriteLine(";");
638WriteLine($"public {propExtensibility}{prop.Type} {prop.Name} {{ get; }}");
644WriteLine($"public override void Accept(OperationVisitor visitor) => visitor.{visitorName}(this);");
645WriteLine($"public override TResult? Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument) where TResult : default => visitor.{visitorName}(this, argument);");
669WriteLine(" 0;");
673WriteLine("");
684WriteLine(" +");
697WriteLine(";");
730WriteLine("internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));");
731WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);");
732WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);");
737WriteLine("internal override IOperation GetCurrent(int slot, int index)");
739WriteLine("=> slot switch");
750WriteLine($"index < {prop.Name}.Length");
752WriteLine($"=> {prop.Name}[index],");
757WriteLine($"{prop.Name} != null");
759WriteLine($"=> {prop.Name},");
764WriteLine("_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),");
766WriteLine("};");
772WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)");
774WriteLine("switch (previousSlot)");
801WriteLine($"case {previousSlot}:");
807WriteLine($"if (!{prop.Name}.IsEmpty) return (true, {slot}, 0);");
811WriteLine($"if ({prop.Name} != null) return (true, {slot}, 0);");
814WriteLine($"else goto case {slot};");
820WriteLine($"case {slot} when previousIndex + 1 < {prop.Name}.Length:");
822WriteLine($"return (true, {slot}, previousIndex + 1);");
832WriteLine($"case {lastSlot}:");
833WriteLine($"case {slot}:");
835WriteLine($"return (false, {slot}, 0);");
838WriteLine("default:");
840WriteLine("throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));");
848WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)");
850WriteLine("switch (previousSlot)");
877WriteLine($"case {previousSlot}:");
883WriteLine($"if (!{prop.Name}.IsEmpty) return (true, {slot}, {prop.Name}.Length - 1);");
887WriteLine($"if ({prop.Name} != null) return (true, {slot}, 0);");
890WriteLine($"else goto case {slot};");
896WriteLine($"case {slot} when previousIndex > 0:");
898WriteLine($"return (true, {slot}, previousIndex - 1);");
907WriteLine("case 0:");
908WriteLine("case -1:");
910WriteLine($"return (false, -1, 0);");
913WriteLine("default:");
915WriteLine("throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));");
931WriteLine("#region Cloner");
933WriteLine(@"internal sealed partial class OperationCloner : OperationVisitor<object?, IOperation>");
936WriteLine("private static readonly OperationCloner s_instance = new OperationCloner();");
937WriteLine("/// <summary>Deep clone given IOperation</summary>");
938WriteLine("public static T CloneOperation<T>(T operation) where T : IOperation => s_instance.Visit(operation);");
939WriteLine("public OperationCloner() { }");
940WriteLine(@"[return: NotNullIfNotNull(""node"")]");
941WriteLine("private T? Visit<T>(T? node) where T : IOperation? => (T?)Visit(node, argument: null);");
942WriteLine("public override IOperation DefaultVisit(IOperation operation, object? argument) => throw ExceptionUtilities.Unreachable();");
943WriteLine("private ImmutableArray<T> VisitArray<T>(ImmutableArray<T> nodes) where T : IOperation => nodes.SelectAsArray((n, @this) => @this.Visit(n), this)!;");
944WriteLine("private ImmutableArray<(ISymbol, T)> VisitArray<T>(ImmutableArray<(ISymbol, T)> nodes) where T : IOperation => nodes.SelectAsArray((n, @this) => (n.Item1, @this.Visit(n.Item2)), this)!;");
956WriteLine($"{(node.IsInternal ? "internal" : "public")} override IOperation {GetVisitorName(node)}({node.Name} operation, object? argument)");
958WriteLine($"var {internalName} = ({nameMinusI})operation;");
1006WriteLine($"{internalName}.IsImplicit);");
1012WriteLine("#endregion");
1013WriteLine("");
1018WriteLine("#region Visitors");
1019WriteLine(@"public abstract partial class OperationVisitor
1035WriteLine($"{accessibility} virtual void {GetVisitorName(type)}({type.Name} operation) => DefaultVisit(operation);");
1040WriteLine(@"public abstract partial class OperationVisitor<TArgument, TResult>
1054WriteLine($"{accessibility} virtual TResult? {GetVisitorName(type)}({type.Name} operation, TArgument argument) => DefaultVisit(operation, argument);");
1058WriteLine("#endregion");
1065WriteLine($"[Obsolete({tag.Message}, error: {tag.ErrorText})]");