Skip to content

Commit

Permalink
Update API following review
Browse files Browse the repository at this point in the history
  • Loading branch information
cston committed Nov 19, 2023
1 parent 5ae2a11 commit f3bb8d1
Show file tree
Hide file tree
Showing 10 changed files with 464 additions and 291 deletions.
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Portable/CSharpExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -853,12 +853,12 @@ public static Conversion GetOutConversion(this ICompoundAssignmentOperation comp
}

/// <summary>
/// Gets the underlying item <see cref="Conversion"/> information from this <see cref="ISpreadOperation"/>.
/// Gets the underlying element <see cref="Conversion"/> information from this <see cref="ISpreadOperation"/>.
/// </summary>
/// <remarks>
/// This spread operation must have been created from C# code.
/// </remarks>
public static Conversion GetSpreadItemConversion(this ISpreadOperation spread)
public static Conversion GetElementConversion(this ISpreadOperation spread)
{
if (spread == null)
{
Expand All @@ -867,7 +867,7 @@ public static Conversion GetSpreadItemConversion(this ISpreadOperation spread)

if (spread.Language == LanguageNames.CSharp)
{
return (Conversion)((SpreadOperation)spread).ItemConversionConvertible;
return (Conversion)((SpreadOperation)spread).ElementConversionConvertible;
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1286,12 +1286,12 @@ private IOperation CreateBoundCollectionExpressionSpreadElement(BoundCollectionE
var collection = Create(element.Expression);
SyntaxNode syntax = element.Syntax;
bool isImplicit = element.WasCompilerGenerated;
var itemType = element.EnumeratorInfoOpt?.ElementType.GetPublicSymbol();
var itemConversion = BoundNode.GetConversion(iteratorItem, element.ElementPlaceholder);
var elementType = element.EnumeratorInfoOpt?.ElementType.GetPublicSymbol();
var elementConversion = BoundNode.GetConversion(iteratorItem, element.ElementPlaceholder);
return new SpreadOperation(
collection,
itemType: itemType,
itemConversion,
elementType: elementType,
elementConversion,
_semanticModel,
syntax,
type: null,
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ Microsoft.CodeAnalysis.CSharp.Conversion.IsCollectionExpression.get -> bool
Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax.ReadOnlyKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken refKindKeyword, Microsoft.CodeAnalysis.SyntaxToken readOnlyKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax! type) -> Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax!
Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax.WithReadOnlyKeyword(Microsoft.CodeAnalysis.SyntaxToken readOnlyKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax!
static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetSpreadItemConversion(this Microsoft.CodeAnalysis.Operations.ISpreadOperation! spread) -> Microsoft.CodeAnalysis.CSharp.Conversion
static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetElementConversion(this Microsoft.CodeAnalysis.Operations.ISpreadOperation! spread) -> Microsoft.CodeAnalysis.CSharp.Conversion
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CrefParameter(Microsoft.CodeAnalysis.SyntaxToken refKindKeyword, Microsoft.CodeAnalysis.SyntaxToken readOnlyKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax! type) -> Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax!
655 changes: 408 additions & 247 deletions src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs

Large diffs are not rendered by default.

25 changes: 13 additions & 12 deletions src/Compilers/Core/Portable/Generated/Operations.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3675,7 +3675,8 @@ public interface ICollectionExpressionOperation : IOperation
/// <summary>
/// Collection expression elements.
/// <para>
/// If the element is an expression, the entry is converted to the target element type;
/// If the element is an expression, the entry is the expression, with a conversion to
/// the target element type if necessary;
/// otherwise, the entry is an ISpreadOperation.
/// </para>
/// </summary>
Expand Down Expand Up @@ -3703,14 +3704,14 @@ public interface ISpreadOperation : IOperation
/// </summary>
IOperation Operand { get; }
/// <summary>
/// Type of the collection iterator item.
/// Type of the elements in the collection.
/// </summary>
ITypeSymbol? ItemType { get; }
ITypeSymbol? ElementType { get; }
/// <summary>
/// Conversion from the type of the iterator item to the target element type
/// Conversion from the type of the collection element to the target element type
/// of the containing collection expression.
/// </summary>
CommonConversion ItemConversion { get; }
CommonConversion ElementConversion { get; }
}
#endregion

Expand Down Expand Up @@ -10445,18 +10446,18 @@ internal override (bool hasNext, int nextSlot, int nextIndex) MoveNextReversed(i
}
internal sealed partial class SpreadOperation : Operation, ISpreadOperation
{
internal SpreadOperation(IOperation operand, ITypeSymbol? itemType, IConvertibleConversion itemConversion, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
internal SpreadOperation(IOperation operand, ITypeSymbol? elementType, IConvertibleConversion elementConversion, SemanticModel? semanticModel, SyntaxNode syntax, ITypeSymbol? type, bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
Operand = SetParentOperation(operand, this);
ItemType = itemType;
ItemConversionConvertible = itemConversion;
ElementType = elementType;
ElementConversionConvertible = elementConversion;
Type = type;
}
public IOperation Operand { get; }
public ITypeSymbol? ItemType { get; }
internal IConvertibleConversion ItemConversionConvertible { get; }
public CommonConversion ItemConversion => ItemConversionConvertible.ToCommonConversion();
public ITypeSymbol? ElementType { get; }
internal IConvertibleConversion ElementConversionConvertible { get; }
public CommonConversion ElementConversion => ElementConversionConvertible.ToCommonConversion();
internal override int ChildOperationsCount =>
(Operand is null ? 0 : 1);
internal override IOperation GetCurrent(int slot, int index)
Expand Down Expand Up @@ -11121,7 +11122,7 @@ public override IOperation VisitCollectionExpression(ICollectionExpressionOperat
public override IOperation VisitSpread(ISpreadOperation operation, object? argument)
{
var internalOperation = (SpreadOperation)operation;
return new SpreadOperation(Visit(internalOperation.Operand), internalOperation.ItemType, internalOperation.ItemConversionConvertible, internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit);
return new SpreadOperation(Visit(internalOperation.Operand), internalOperation.ElementType, internalOperation.ElementConversionConvertible, internalOperation.OwningSemanticModel, internalOperation.Syntax, internalOperation.Type, internalOperation.IsImplicit);
}
}
#endregion
Expand Down
36 changes: 23 additions & 13 deletions src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6371,7 +6371,7 @@ IArrayInitializerOperation popAndAssembleArrayInitializerValues(IArrayInitialize
public override IOperation? VisitCollectionExpression(ICollectionExpressionOperation operation, int? argument)
{
EvalStackFrame frame = PushStackFrame();
var elements = VisitArray(operation.Elements);
var elements = VisitArray(operation.Elements, unwrapElement, wrapElement);
PopStackFrame(frame);
return new CollectionExpressionOperation(
operation.ConstructMethod,
Expand All @@ -6380,22 +6380,32 @@ IArrayInitializerOperation popAndAssembleArrayInitializerValues(IArrayInitialize
operation.Syntax,
operation.Type,
IsImplicit(operation));

static IOperation unwrapElement(IOperation element)
{
return element is ISpreadOperation spread ?
spread.Operand :
element;
}

IOperation wrapElement(IOperation operation, int index, ImmutableArray<IOperation> elements)
{
return elements[index] is ISpreadOperation spread ?
new SpreadOperation(
operation,
elementType: spread.ElementType,
elementConversion: ((SpreadOperation)spread).ElementConversionConvertible,
semanticModel: null,
spread.Syntax,
spread.Type,
IsImplicit(spread)) :
operation;
}
}

public override IOperation? VisitSpread(ISpreadOperation operation, int? argument)
{
EvalStackFrame frame = PushStackFrame();
var operand = Visit(operation.Operand);
Debug.Assert(operand is { });
PopStackFrame(frame);
return new SpreadOperation(
operand,
itemType: operation.ItemType,
itemConversion: ((SpreadOperation)operation).ItemConversionConvertible,
semanticModel: null,
operation.Syntax,
operation.Type,
IsImplicit(operation));
throw ExceptionUtilities.Unreachable();
}

public override IOperation VisitInstanceReference(IInstanceReferenceOperation operation, int? captureIdForResult)
Expand Down
11 changes: 6 additions & 5 deletions src/Compilers/Core/Portable/Operations/OperationInterfaces.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3414,7 +3414,8 @@
<summary>
Collection expression elements.
<para>
If the element is an expression, the entry is converted to the target element type;
If the element is an expression, the entry is the expression, with a conversion to
the target element type if necessary;
otherwise, the entry is an ISpreadOperation.
</para>
</summary>
Expand All @@ -3436,17 +3437,17 @@
<summary>Collection being spread.</summary>
</Comments>
</Property>
<Property Name="ItemType" Type="ITypeSymbol?">
<Property Name="ElementType" Type="ITypeSymbol?">
<Comments>
<summary>
Type of the collection iterator item.
Type of the elements in the collection.
</summary>
</Comments>
</Property>
<Property Name="ItemConversion" Type="CommonConversion">
<Property Name="ElementConversion" Type="CommonConversion">
<Comments>
<summary>
Conversion from the type of the iterator item to the target element type
Conversion from the type of the collection element to the target element type
of the containing collection expression.
</summary>
</Comments>
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/Core/Portable/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Microsoft.CodeAnalysis.Operations.ICollectionExpressionOperation.ConstructMethod
Microsoft.CodeAnalysis.Operations.ICollectionExpressionOperation
Microsoft.CodeAnalysis.Operations.ICollectionExpressionOperation.Elements.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation!>
Microsoft.CodeAnalysis.Operations.ISpreadOperation
Microsoft.CodeAnalysis.Operations.ISpreadOperation.ItemConversion.get -> Microsoft.CodeAnalysis.Operations.CommonConversion
Microsoft.CodeAnalysis.Operations.ISpreadOperation.ItemType.get -> Microsoft.CodeAnalysis.ITypeSymbol?
Microsoft.CodeAnalysis.Operations.ISpreadOperation.ElementConversion.get -> Microsoft.CodeAnalysis.Operations.CommonConversion
Microsoft.CodeAnalysis.Operations.ISpreadOperation.ElementType.get -> Microsoft.CodeAnalysis.ITypeSymbol?
Microsoft.CodeAnalysis.Operations.ISpreadOperation.Operand.get -> Microsoft.CodeAnalysis.IOperation!
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitCollectionExpression(Microsoft.CodeAnalysis.Operations.ICollectionExpressionOperation! operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitSpread(Microsoft.CodeAnalysis.Operations.ISpreadOperation! operation) -> void
Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/Test/Core/Compilation/OperationTreeVerifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1639,16 +1639,16 @@ public override void VisitCollectionExpression(ICollectionExpressionOperation op
public override void VisitSpread(ISpreadOperation operation)
{
LogString(nameof(ISpreadOperation));
LogSymbol(operation.ItemType, $" ({nameof(operation.ItemType)}");
LogSymbol(operation.ElementType, $" ({nameof(operation.ElementType)}");
LogString(")");
LogCommonPropertiesAndNewLine(operation);

Visit(operation.Operand, nameof(operation.Operand));
Indent();
LogConversion(operation.ItemConversion, nameof(operation.ItemConversion));
LogConversion(operation.ElementConversion, nameof(operation.ElementConversion));
LogNewLine();
Indent();
LogString($"({((SpreadOperation)operation).ItemConversionConvertible})");
LogString($"({((SpreadOperation)operation).ElementConversionConvertible})");
Unindent();
LogNewLine();
Unindent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2343,7 +2343,7 @@ public async Task ChangeNamespace_DoesNotThrowInDuplicateProgramDeclaration()

// No change namespace action because the folder name is not valid identifier
var (topLevelProgramFolder, topLevelProgramFilePath) = CreateDocumentFilePath(["3B", "C"], "Program.cs");
var (duplicateProgramFolder, duplicateProgramFilePath) = CreateDocumentFilePath([], "Program.cs");
var (duplicateProgramFolder, _) = CreateDocumentFilePath([], "Program.cs");

var code =
$$"""
Expand Down

0 comments on commit f3bb8d1

Please sign in to comment.