Skip to content

Commit

Permalink
Allow collection expressions with CreateCompilation (#71134)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv committed Dec 18, 2023
1 parent 422687f commit 219fa7d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ static void Main()
static T F<T>(T t) => t;
}
""";
var comp = CreateCompilation(new[] { source, s_collectionExtensions });
var comp = CreateCompilation([source, s_collectionExtensions]);
comp.VerifyEmitDiagnostics(
// 0.cs(5,9): error CS0411: The type arguments for method 'Program.F<T>(T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// F([1, 2]).Report();
Expand Down Expand Up @@ -467,7 +467,7 @@ static void Main()
}
}
""";
var comp = CreateCompilation(new[] { source, s_collectionExtensions });
var comp = CreateCompilation([source, s_collectionExtensions]);
comp.VerifyEmitDiagnostics(
// 0.cs(6,25): error CS9174: Cannot initialize type 'IEnumerable' with a collection expression because the type is not constructible.
// IEnumerable a = [1];
Expand Down Expand Up @@ -503,7 +503,7 @@ static void Main()
}
""";
CompileAndVerify(
new[] { source, s_collectionExtensions },
[source, s_collectionExtensions],
expectedOutput: "(System.Int32[]) [], (System.Collections.Generic.List<System.Int32>) [], (System.Collections.Generic.List<System.Int32>) [], (System.Int32[]) [], (System.Int32[]) [], ");
}

Expand All @@ -530,7 +530,7 @@ static void Main()
}
""";
CompileAndVerify(
new[] { source, s_collectionExtensions },
[source, s_collectionExtensions],
expectedOutput: "(<>z__ReadOnlyArray<System.Int32>) [1], (System.Collections.Generic.List<System.Int32>) [2], (System.Collections.Generic.List<System.Int32>) [3], (<>z__ReadOnlyArray<System.Int32>) [4], (<>z__ReadOnlyArray<System.Int32>) [5], ");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4635,7 +4635,7 @@ class C
var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, @"\_/"));

var comp = CreateCompilation(
new[] { (source, path), s_attributesSource },
[(source, path), s_attributesSource],
parseOptions: RegularWithInterceptors,
options: TestOptions.DebugExe.WithSourceReferenceResolver(
new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)));
Expand Down
31 changes: 31 additions & 0 deletions src/Compilers/Test/Core/CollectionBuilderAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#if !NET8_0_OR_GREATER

namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
public sealed class CollectionBuilderAttribute : Attribute
{
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}

public Type BuilderType { get; }
public string MethodName { get; }
}
}

#else

using System.Runtime.CompilerServices;

#pragma warning disable RS0016 // Add public types and members to the declared API (this is a supporting forwarder for an internal polyfill API)
[assembly: TypeForwardedTo(typeof(CollectionBuilderAttribute))]
#pragma warning restore RS0016 // Add public types and members to the declared API

#endif
17 changes: 15 additions & 2 deletions src/Compilers/Test/Utilities/CSharp/CSharpTestSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#nullable disable

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis.Text;
Expand All @@ -19,7 +19,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities
/// Represents the source code used for a C# test. Allows us to have single helpers that enable all the different ways
/// we typically provide source in testing.
/// </summary>
public readonly struct CSharpTestSource
[System.Runtime.CompilerServices.CollectionBuilder(typeof(CSharpTestSourceBuilder), nameof(CSharpTestSourceBuilder.Create))]
public readonly struct CSharpTestSource : IEnumerable<CSharpTestSource>
{
public static CSharpTestSource None => new CSharpTestSource(null);

Expand Down Expand Up @@ -83,5 +84,17 @@ public SyntaxTree[] GetSyntaxTrees(CSharpParseOptions parseOptions, string sourc
public static implicit operator CSharpTestSource(List<SyntaxTree> source) => new CSharpTestSource(source.ToArray());
public static implicit operator CSharpTestSource(ImmutableArray<SyntaxTree> source) => new CSharpTestSource(source.ToArray());
public static implicit operator CSharpTestSource(CSharpTestSource[] source) => new CSharpTestSource(source);

// Dummy IEnumerable support to satisfy the collection expression and CollectionBuilder requirements
IEnumerator<CSharpTestSource> IEnumerable<CSharpTestSource>.GetEnumerator() => throw new NotImplementedException();
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();

internal static class CSharpTestSourceBuilder
{
public static CSharpTestSource Create(ReadOnlySpan<CSharpTestSource> source)
{
return source.ToArray();
}
}
}
}

0 comments on commit 219fa7d

Please sign in to comment.