IOperationClassWriter.cs (119)
72WriteLine("{");
79WriteLine("}");
138WriteLine("#region Interfaces");
144WriteLine("#endregion");
176WriteLine("// Licensed to the .NET Foundation under one or more agreements.");
177WriteLine("// The .NET Foundation licenses this file to you under the MIT license.");
178WriteLine("// See the LICENSE file in the project root for more information.");
179WriteLine("// < auto-generated />");
180WriteLine("#nullable enable");
186WriteLine($"using {nsName};");
191WriteLine($"namespace Microsoft.CodeAnalysis{(namespaceSuffix is null ? "" : $".{namespaceSuffix}")}");
205WriteLine($"{(node.IsInternal ? "internal" : "public")} interface {node.Name} : {node.Base}");
240WriteLine($"/// <{el.LocalName}>");
251WriteLine($"/// {line.Substring(indentation)}");
260WriteLine($"/// </{el.LocalName}>");
265WriteLine("/// <remarks>");
267WriteLine("/// </remarks>");
275WriteLine("/// <para>This node is associated with the following operation kinds:</para>");
276WriteLine("/// <list type=\"bullet\">");
279WriteLine($"/// <item><description><see cref=\"OperationKind.{kind}\"/></description></item>");
281WriteLine("/// </list>");
284WriteLine("/// <para>This interface is reserved for implementation by its associated APIs. We reserve the right to");
285WriteLine("/// change it in the future.</para>");
295WriteLine($"{modifiers}{prop.Type} {prop.Name} {{ get; }}");
300WriteLine("/// <summary>");
301WriteLine("/// All of the kinds of operations, including statements and expressions.");
302WriteLine("/// </summary>");
303WriteLine("public enum OperationKind");
306WriteLine("/// <summary>Indicates an <see cref=\"IOperation\"/> for a construct that is not implemented yet.</summary>");
307WriteLine("None = 0x0,");
337WriteLine($"// Unused: {i:x}");
370WriteLine($"/// <summary>Indicates an <see cref=\"{operationName}\"/>.{(extraText is object ? $" {extraText}" : "")}</summary>");
374WriteLine("[EditorBrowsable(EditorBrowsableState.Never)]");
379WriteLine($"[Obsolete({obsoleteMessage}, error: {obsoleteError})]");
382WriteLine($"{kind} = 0x{value:x},");
388WriteLine("#region Implementations");
397WriteLine("#endregion");
460WriteLine($"public override ITypeSymbol? Type {(node.HasType ? "{ get; }" : "=> null;")}");
462WriteLine($"internal override ConstantValue? OperationConstantValue {(hasConstantValue ? "{ get; }" : "=> null;")}");
466WriteLine("public override OperationKind Kind { get; }");
471WriteLine($"public override OperationKind Kind => OperationKind.{kind};");
481WriteLine($"internal {extensibility} partial class {@class} : {baseType}, {@interface}");
526WriteLine(")");
552WriteLine(" { }");
566WriteLine($"{prop.Name}Convertible = {prop.Name.ToCamelCase()};");
573WriteLine($"{prop.Name} = {initializer};");
579WriteLine("OperationConstantValue = constantValue;");
584WriteLine("Type = type;");
589WriteLine("Kind = kind;");
602WriteLine($"internal IConvertibleConversion {prop.Name}Convertible {{ get; }}");
603WriteLine($"public CommonConversion {prop.Name} => {prop.Name}Convertible.ToCommonConversion();");
626WriteLine(";");
634WriteLine($"public {propExtensibility}{prop.Type} {prop.Name} {{ get; }}");
640WriteLine($"public override void Accept(OperationVisitor visitor) => visitor.{visitorName}(this);");
641WriteLine($"public override TResult? Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument) where TResult : default => visitor.{visitorName}(this, argument);");
665WriteLine(" 0;");
669WriteLine("");
680WriteLine(" +");
693WriteLine(";");
726WriteLine("internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));");
727WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);");
728WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);");
733WriteLine("internal override IOperation GetCurrent(int slot, int index)");
735WriteLine("=> slot switch");
746WriteLine($"index < {prop.Name}.Length");
748WriteLine($"=> {prop.Name}[index],");
753WriteLine($"{prop.Name} != null");
755WriteLine($"=> {prop.Name},");
760WriteLine("_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),");
762WriteLine("};");
768WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)");
770WriteLine("switch (previousSlot)");
797WriteLine($"case {previousSlot}:");
803WriteLine($"if (!{prop.Name}.IsEmpty) return (true, {slot}, 0);");
807WriteLine($"if ({prop.Name} != null) return (true, {slot}, 0);");
810WriteLine($"else goto case {slot};");
816WriteLine($"case {slot} when previousIndex + 1 < {prop.Name}.Length:");
818WriteLine($"return (true, {slot}, previousIndex + 1);");
828WriteLine($"case {lastSlot}:");
829WriteLine($"case {slot}:");
831WriteLine($"return (false, {slot}, 0);");
834WriteLine("default:");
836WriteLine("throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));");
844WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)");
846WriteLine("switch (previousSlot)");
873WriteLine($"case {previousSlot}:");
879WriteLine($"if (!{prop.Name}.IsEmpty) return (true, {slot}, {prop.Name}.Length - 1);");
883WriteLine($"if ({prop.Name} != null) return (true, {slot}, 0);");
886WriteLine($"else goto case {slot};");
892WriteLine($"case {slot} when previousIndex > 0:");
894WriteLine($"return (true, {slot}, previousIndex - 1);");
903WriteLine("case 0:");
904WriteLine("case -1:");
906WriteLine($"return (false, -1, 0);");
909WriteLine("default:");
911WriteLine("throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));");
927WriteLine("#region Cloner");
929WriteLine(@"internal sealed partial class OperationCloner : OperationVisitor<object?, IOperation>");
932WriteLine("private static readonly OperationCloner s_instance = new OperationCloner();");
933WriteLine("/// <summary>Deep clone given IOperation</summary>");
934WriteLine("public static T CloneOperation<T>(T operation) where T : IOperation => s_instance.Visit(operation);");
935WriteLine("public OperationCloner() { }");
936WriteLine(@"[return: NotNullIfNotNull(""node"")]");
937WriteLine("private T? Visit<T>(T? node) where T : IOperation? => (T?)Visit(node, argument: null);");
938WriteLine("public override IOperation DefaultVisit(IOperation operation, object? argument) => throw ExceptionUtilities.Unreachable();");
939WriteLine("private ImmutableArray<T> VisitArray<T>(ImmutableArray<T> nodes) where T : IOperation => nodes.SelectAsArray((n, @this) => @this.Visit(n), this)!;");
940WriteLine("private ImmutableArray<(ISymbol, T)> VisitArray<T>(ImmutableArray<(ISymbol, T)> nodes) where T : IOperation => nodes.SelectAsArray((n, @this) => (n.Item1, @this.Visit(n.Item2)), this)!;");
952WriteLine($"{(node.IsInternal ? "internal" : "public")} override IOperation {GetVisitorName(node)}({node.Name} operation, object? argument)");
954WriteLine($"var {internalName} = ({nameMinusI})operation;");
1002WriteLine($"{internalName}.IsImplicit);");
1008WriteLine("#endregion");
1009WriteLine("");
1014WriteLine("#region Visitors");
1015WriteLine(@"public abstract partial class OperationVisitor
1031WriteLine($"{accessibility} virtual void {GetVisitorName(type)}({type.Name} operation) => DefaultVisit(operation);");
1036WriteLine(@"public abstract partial class OperationVisitor<TArgument, TResult>
1050WriteLine($"{accessibility} virtual TResult? {GetVisitorName(type)}({type.Name} operation, TArgument argument) => DefaultVisit(operation, argument);");
1054WriteLine("#endregion");
1061WriteLine($"[Obsolete({tag.Message}, error: {tag.ErrorText})]");