IOperationClassWriter.cs (120)
73WriteLine("{");
80WriteLine("}");
140WriteLine("#region Interfaces");
146WriteLine("#endregion");
181WriteLine("// Licensed to the .NET Foundation under one or more agreements.");
182WriteLine("// The .NET Foundation licenses this file to you under the MIT license.");
183WriteLine("// See the LICENSE file in the project root for more information.");
184WriteLine("// < auto-generated />");
185WriteLine("#nullable enable");
191WriteLine($"using {nsName};");
196WriteLine($"namespace Microsoft.CodeAnalysis{(namespaceSuffix is null ? "" : $".{namespaceSuffix}")}");
211WriteLine($"{(node.IsInternal ? "internal" : "public")} interface {node.Name} : {node.Base}");
246WriteLine($"/// <{el.LocalName}>");
257WriteLine($"/// {line.Substring(indentation)}");
266WriteLine($"/// </{el.LocalName}>");
271WriteLine("/// <remarks>");
273WriteLine("/// </remarks>");
281WriteLine("/// <para>This node is associated with the following operation kinds:</para>");
282WriteLine("/// <list type=\"bullet\">");
285WriteLine($"/// <item><description><see cref=\"OperationKind.{kind}\"/></description></item>");
287WriteLine("/// </list>");
290WriteLine("/// <para>This interface is reserved for implementation by its associated APIs. We reserve the right to");
291WriteLine("/// change it in the future.</para>");
302WriteLine($"{modifiers}{prop.Type} {prop.Name} {{ get; }}");
307WriteLine("/// <summary>");
308WriteLine("/// All of the kinds of operations, including statements and expressions.");
309WriteLine("/// </summary>");
310WriteLine("public enum OperationKind");
313WriteLine("/// <summary>Indicates an <see cref=\"IOperation\"/> for a construct that is not implemented yet.</summary>");
314WriteLine("None = 0x0,");
344WriteLine($"// Unused: {i:x}");
379WriteLine($"/// <summary>Indicates an <see cref=\"{operationName}\"/>.{(extraText is object ? $" {extraText}" : "")}</summary>");
383WriteLine("[EditorBrowsable(EditorBrowsableState.Never)]");
393WriteLine($"[Obsolete({obsoleteMessage}, error: {obsoleteError})]");
396WriteLine($"{kind} = 0x{value:x},");
402WriteLine("#region Implementations");
411WriteLine("#endregion");
474WriteLine($"public override ITypeSymbol? Type {(node.HasType ? "{ get; }" : "=> null;")}");
476WriteLine($"internal override ConstantValue? OperationConstantValue {(hasConstantValue ? "{ get; }" : "=> null;")}");
480WriteLine("public override OperationKind Kind { get; }");
485WriteLine($"public override OperationKind Kind => OperationKind.{kind};");
495WriteLine($"internal {extensibility} partial class {@class} : {baseType}, {@interface}");
540WriteLine(")");
566WriteLine(" { }");
580WriteLine($"{prop.Name}Convertible = {prop.Name.ToCamelCase()};");
587WriteLine($"{prop.Name} = {initializer};");
593WriteLine("OperationConstantValue = constantValue;");
598WriteLine("Type = type;");
603WriteLine("Kind = kind;");
616WriteLine($"internal IConvertibleConversion {prop.Name}Convertible {{ get; }}");
617WriteLine($"public CommonConversion {prop.Name} => {prop.Name}Convertible.ToCommonConversion();");
640WriteLine(";");
648WriteLine($"public {propExtensibility}{prop.Type} {prop.Name} {{ get; }}");
654WriteLine($"public override void Accept(OperationVisitor visitor) => visitor.{visitorName}(this);");
655WriteLine($"public override TResult? Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument) where TResult : default => visitor.{visitorName}(this, argument);");
679WriteLine(" 0;");
683WriteLine("");
694WriteLine(" +");
707WriteLine(";");
740WriteLine("internal override IOperation GetCurrent(int slot, int index) => throw ExceptionUtilities.UnexpectedValue((slot, index));");
741WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);");
742WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex) => (false, int.MinValue, int.MinValue);");
747WriteLine("internal override IOperation GetCurrent(int slot, int index)");
749WriteLine("=> slot switch");
760WriteLine($"index < {prop.Name}.Length");
762WriteLine($"=> {prop.Name}[index],");
767WriteLine($"{prop.Name} != null");
769WriteLine($"=> {prop.Name},");
774WriteLine("_ => throw ExceptionUtilities.UnexpectedValue((slot, index)),");
776WriteLine("};");
782WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNext(int previousSlot, int previousIndex)");
784WriteLine("switch (previousSlot)");
811WriteLine($"case {previousSlot}:");
817WriteLine($"if (!{prop.Name}.IsEmpty) return (true, {slot}, 0);");
821WriteLine($"if ({prop.Name} != null) return (true, {slot}, 0);");
824WriteLine($"else goto case {slot};");
830WriteLine($"case {slot} when previousIndex + 1 < {prop.Name}.Length:");
832WriteLine($"return (true, {slot}, previousIndex + 1);");
842WriteLine($"case {lastSlot}:");
843WriteLine($"case {slot}:");
845WriteLine($"return (false, {slot}, 0);");
848WriteLine("default:");
850WriteLine("throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));");
858WriteLine("internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(int previousSlot, int previousIndex)");
860WriteLine("switch (previousSlot)");
887WriteLine($"case {previousSlot}:");
893WriteLine($"if (!{prop.Name}.IsEmpty) return (true, {slot}, {prop.Name}.Length - 1);");
897WriteLine($"if ({prop.Name} != null) return (true, {slot}, 0);");
900WriteLine($"else goto case {slot};");
906WriteLine($"case {slot} when previousIndex > 0:");
908WriteLine($"return (true, {slot}, previousIndex - 1);");
917WriteLine("case 0:");
918WriteLine("case -1:");
920WriteLine($"return (false, -1, 0);");
923WriteLine("default:");
925WriteLine("throw ExceptionUtilities.UnexpectedValue((previousSlot, previousIndex));");
941WriteLine("#region Cloner");
943WriteLine(@"internal sealed partial class OperationCloner : OperationVisitor<object?, IOperation>");
946WriteLine("private static readonly OperationCloner s_instance = new OperationCloner();");
947WriteLine("/// <summary>Deep clone given IOperation</summary>");
948WriteLine("public static T CloneOperation<T>(T operation) where T : IOperation => s_instance.Visit(operation);");
949WriteLine("public OperationCloner() { }");
950WriteLine(@"[return: NotNullIfNotNull(""node"")]");
951WriteLine("private T? Visit<T>(T? node) where T : IOperation? => (T?)Visit(node, argument: null);");
952WriteLine("public override IOperation DefaultVisit(IOperation operation, object? argument) => throw ExceptionUtilities.Unreachable();");
953WriteLine("private ImmutableArray<T> VisitArray<T>(ImmutableArray<T> nodes) where T : IOperation => nodes.SelectAsArray((n, @this) => @this.Visit(n), this)!;");
954WriteLine("private ImmutableArray<(ISymbol, T)> VisitArray<T>(ImmutableArray<(ISymbol, T)> nodes) where T : IOperation => nodes.SelectAsArray((n, @this) => (n.Item1, @this.Visit(n.Item2)), this)!;");
966WriteLine($"{(node.IsInternal ? "internal" : "public")} override IOperation {GetVisitorName(node)}({node.Name} operation, object? argument)");
968WriteLine($"var {internalName} = ({nameMinusI})operation;");
1016WriteLine($"{internalName}.IsImplicit);");
1022WriteLine("#endregion");
1023WriteLine("");
1028WriteLine("#region Visitors");
1029WriteLine(@"public abstract partial class OperationVisitor
1046WriteLine($"{accessibility} virtual void {GetVisitorName(type)}({type.Name} operation) => DefaultVisit(operation);");
1051WriteLine(@"public abstract partial class OperationVisitor<TArgument, TResult>
1066WriteLine($"{accessibility} virtual TResult? {GetVisitorName(type)}({type.Name} operation, TArgument argument) => DefaultVisit(operation, argument);");
1070WriteLine("#endregion");
1077WriteLine($"[Obsolete({tag.Message}, error: {tag.ErrorText})]");
1083WriteLine($"[Experimental(global::Microsoft.CodeAnalysis.RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = @\"{experimentalUrl.Replace("\"", "\"\"")}\")]");