Skip to content

Test plan for "Extension GetEnumerator" #43184

@jcouv

Description

@jcouv

Language proposal: dotnet/csharplang#3194
General compiler test plan: https://github.com/dotnet/roslyn/blob/master/docs/contributing/Compiler%20Test%20Plan.md

Spec:

  • Complete proposal spec is checked into csharplang

Compiler (Both sync and async for each of these):

  • [x] LangVer (TestGetEnumeratorPatternViaExtensionsCSharp8, )
  • [x] Feature spec exists and reviewed with LDM
  • [x] Update compiler test plan
  • [x] IOperation/CFG
    • [x] CFG shows the extension method getting called
  • [ ] GetForEachStatementInfo
  • [x] Differing access modifiers
    • [x] Extension GetEnumerator should work for internal, unlike regular GetEnumerator (TestGetEnumeratorPatternViaInternalExtensions, TestGetAsyncEnumeratorPatternViaInternalExtensions)
    • [x] Test with internal instance method and extension method on the same type (TestGetEnumeratorPatternViaExtensionWithInternalInstanceGetEnumerator, TestGetAsyncEnumeratorPatternViaExtensionWithInternalInstanceGetAsyncEnumerator)
    • [x] private extension methods when inside a static class (TestGetEnumeratorPatternViaAccessiblePrivateExtension, TestGetAsyncEnumeratorPatternViaAccessiblePrivateExtension)
  • [x] out/ref disallowed.
    • [x] out (, )
    • [x] ref (TestGetEnumeratorPatternViaRefExtensionOnNonAssignableVariable, TestGetAsyncEnumeratorPatternViaExtensionWithParams)
  • [x] in allowed in the same places as Deconstruct. (TestGetEnumeratorPatternViaInExtensionOnNonAssignableVariable, TestGetAsyncEnumeratorPatternViaInExtensionOnAssignableVariable)
  • [x] Default parameters (TestGetEnumeratorPatternViaExtensionWithOptionalParameter, TestGetAsyncEnumeratorPatternViaExtensionWithOptionalParameter)
  • [x] params arrays (TestGetEnumeratorPatternViaExtensionWithParams, TestGetAsyncEnumeratorPatternViaExtensionWithParams)
  • [x] __arglist parameter (TestGetEnumeratorPatternViaExtensionWithArgList, TestGetAsyncEnumeratorPatternViaExtensionWithArgList)
  • [x] dynamic prefers existing attempt to call instance GetEnumerator, not an extension method, or does not work on async (TestPreferIEnumeratorInterfaceOnDynamicThanViaExtension, TestCannotUseExtensionGetAsyncEnumeratorOnDynamic)
  • [x] Conversions
    • [x] Reference conversions (TestGetEnumeratorPatternViaExtensionsWithUpcast, TestGetAsyncEnumeratorPatternViaExtensionsWithUpcast)
    • [x] Boxing conversion (TestGetEnumeratorPatternViaExtensionsWithNullableValueTypeConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithNullableValueTypeConversion)
    • [x] Unboxing (should show helpful error, like for regular invocation) (TestGetEnumeratorPatternViaExtensionsWithUnboxingConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithUnboxingConversion)
    • [x] Literal 0 to enum (same as Unboxing) (TestGetEnumeratorPatternViaExtensionsWithZeroToEnumConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithZeroToEnumConversion)
    • [x] Unconstrained generics (TestGetEnumeratorPatternViaExtensionsWithUnconstrainedGenericConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithUnconstrainedGenericConversion)
    • [x] Constrained generics (TestGetEnumeratorPatternViaExtensionsWithConstrainedGenericConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithConstrainedGenericConversion)
    • [x] Interpolated string conversions (IFormattableString vs object) (TestGetEnumeratorPatternViaExtensionsWithFormattableStringConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithFormattableStringConversion1)
    • [x] User-defined conversions (should be invalid) (TestGetEnumeratorPatternViaExtensionsWithUserDefinedImplicitConversion, TestGetAsyncEnumeratorPatternViaExtensionsWithUserDefinedImplicitConversion)
    • [x] Tuple type conversions (TestGetEnumeratorPatternViaExtensionsOnTupleWithNestedConversions, TestGetAsyncEnumeratorPatternViaExtensionsOnTupleWithNestedConversions)
  • [x] this types:
    • [x] class (a lot)
    • [x] interface (TestGetEnumeratorPatternViaExtensionsOnInterface, TestGetAsyncEnumeratorPatternViaExtensionsOnInterface)
    • [x] delegate (TestGetEnumeratorPatternViaExtensionsOnDelegate, TestGetAsyncEnumeratorPatternViaExtensionsOnDelegate)
    • [x] struct (, TestGetAsyncEnumeratorPatternOnRange)
    • [x] enum (TestGetEnumeratorPatternViaExtensionsOnEnum, TestGetAsyncEnumeratorPatternViaExtensionsOnEnum)
    • [x] nullable (TestGetEnumeratorPatternViaExtensionsOnNullable, TestGetAsyncEnumeratorPatternViaExtensionsOnNullable)
    • [x] type parameters (TestGetEnumeratorPatternViaExtensionsOnTypeParameter, TestGetAsyncEnumeratorPatternViaExtensionsOnTypeParameter)
  • [x] Ambiguous overloads (TestGetEnumeratorPatternViaAmbiguousExtensions, TestGetAsyncEnumeratorPatternViaAmbiguousExtensions)
  • [x] Correct name signature, but return doesn't fulfill the pattern (, TestMoveNextAsyncPatternViaExtensions1)
  • [x] Extension is preferred last (TestPreferEnumeratorPatternFromInstanceThanViaExtension, TestPreferAsyncEnumeratorPatternFromInstanceThanViaExtension)
  • [x] If GetEnumerator is defined on the class, extensions are not searched, even if return is incorrect. (TestPreferEnumeratorPatternFromInstanceThanViaExtensionEvenWhenInvalid, TestPreferAsyncEnumeratorPatternFromInstanceThanViaExtensionEvenWhenInvalid)
  • [x] Multiple extensions in different namespace levels
    • [x] Valid overload in closest namespace (with invalid in outer namespace) (TestGetEnumeratorPatternViaValidExtensionInClosestNamespaceInvalidInFurtherNamespace1-2, TestGetAsyncEnumeratorPatternViaValidExtensionInClosestNamespaceInvalidInFurtherNamespace1-2)
    • [x] Invalid overload in closest namespace (with valid in outer namespace) (TestGetEnumeratorPatternViaInvalidExtensionInClosestNamespaceValidInFurtherNamespace1-2, TestGetAsyncEnumeratorPatternViaInvalidExtensionInClosestNamespaceValidInFurtherNamespace1-2)
  • [x] ref returns (TestGetEnumeratorPatternViaExtensionWithRefReturn, TestGetAsyncEnumeratorPatternViaExtensionWithRefReturn)
  • [x] Nullable warnings
    • [x] No warning for extension method accepting null (ForEach_ExtensionGetEnumerator6, ForEach_ExtensionGetAsyncEnumerator6)
    • [x] Warning for extension method not accepting null (ForEach_ExtensionGetEnumerator1, ForEach_ExtensionGetAsyncEnumerator5)
    • [x] Constraint mismatch warnings (ForEach_ExtensionGetEnumerator3, ForEach_ExtensionGetAsyncEnumerator3)
    • [x] Warning for nullable return (ForEach_ExtensionGetEnumerator15, ForEach_ExtensionGetAsyncEnumerator15)
    • [x] Output attributes are honored after call (ForEach_ExtensionGetEnumerator7-8, ForEach_ExtensionGetAsyncEnumerator7)
  • [x] Obsolete extension methods (TestGetEnumeratorPatternViaObsoleteExtension, TestWithObsoletePatternMethodsViaExtension)
  • Disposal
    • [x] GetEnumerator() returning IDisposable types (TestForEachViaExtensionExplicitlyDisposableStruct, TestAwaitForEachViaExtensionExplicitlyDisposableStruct)
    • [x] Uses pattern-based Dispose method on async, not on sync (TestForEachViaExtensionDisposeStruct, TestAwaitForEachViaExtensionAsyncDisposeStruct)
    • [x] Uses pattern-based for both for ref structs (, TestAwaitForEachViaExtensionImplicitlyDisposableStruct)

Productivity:

  • [ ] test FindAllReferences
  • [x] AddParameter to a GetEnumerator
  • [ ] AddUsing to bring extension GetEnumerator into scope
  • [ ] foreach to Linq
  • [ ] Linq to foreach

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions