XamlX icon indicating copy to clipboard operation
XamlX copied to clipboard

XamlParserTests crashes with dotnet test exception for net47

Open rstm-sf opened this issue 4 years ago • 2 comments

Hello!

XamlParserTests crashes with dotnet test exception for net47

dotnet test -f net47 --filter Compiler_Should_Compile_Simple_Xaml .\tests\XamlParserTests\XamlParserTests.csproj
Test run for D:\a\XamlX\XamlX\tests\XamlParserTests\bin\Debug\net47\XamlParserTests.dll(.NETFramework,Version=v4.7)
Microsoft (R) Test Execution Command Line Tool Version 16.7.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...

A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.19] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (32-bit Desktop .NET 4.0.30319.42000)
[xUnit.net 00:00:03.15]   Discovering: XamlParserTests
[xUnit.net 00:00:03.42]   Discovered:  XamlParserTests
[xUnit.net 00:00:03.43]   Starting:    XamlParserTests
  √ XamlParserTests.BasicCompilerTests.Compiler_Should_Compile_Simple_Xaml(populate: False) [1s 141ms]
[xUnit.net 00:00:05.66]     XamlParserTests.BasicCompilerTests.Compiler_Should_Compile_Simple_Xaml(populate: True) [FAIL]
[xUnit.net 00:00:05.66]       System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
[xUnit.net 00:00:05.66]       Stack Trace:
[xUnit.net 00:00:05.67]            at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
[xUnit.net 00:00:05.67]            at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
[xUnit.net 00:00:05.67]            at System.Collections.Generic.List`1.Enumerator.MoveNext()
[xUnit.net 00:00:05.67]         D:\a\XamlX\XamlX\src\XamlX\Transform\XamlXmlnsMappings.cs(22,0): at XamlX.Transform.XamlXmlnsMappings.Resolve(IXamlTypeSystem typeSystem, XamlLanguageTypeMappings typeMappings)
[xUnit.net 00:00:05.67]         D:\a\XamlX\XamlX\src\XamlX\Transform\TransformerConfiguration.cs(59,0): at XamlX.Transform.TransformerConfiguration..ctor(IXamlTypeSystem typeSystem, IXamlAssembly defaultAssembly, XamlLanguageTypeMappings typeMappings, XamlXmlnsMappings xmlnsMappings, XamlValueConverter customValueConverter)
[xUnit.net 00:00:05.67]         CompilerTestBase.cs(30,0): at XamlParserTests.CompilerTestBase..ctor(IXamlTypeSystem typeSystem)
[xUnit.net 00:00:05.67]         CompilerTestBase.cs(82,0): at XamlParserTests.CompilerTestBase..ctor()
[xUnit.net 00:00:05.67]            at XamlParserTests.BasicCompilerTests..ctor()
[xUnit.net 00:00:05.67]            at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
[xUnit.net 00:00:05.67]   Finished:    XamlParserTests
  X XamlParserTests.BasicCompilerTests.Compiler_Should_Compile_Simple_Xaml(populate: True) [1ms]
  Error Message:
   System.InvalidOperationException : Collection was modified; enumeration operation may not execute.
  Stack Trace:
     at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at XamlX.Transform.XamlXmlnsMappings.Resolve(IXamlTypeSystem typeSystem, XamlLanguageTypeMappings typeMappings) in D:\a\XamlX\XamlX\src\XamlX\Transform\XamlXmlnsMappings.cs:line 22
   at XamlX.Transform.TransformerConfiguration..ctor(IXamlTypeSystem typeSystem, IXamlAssembly defaultAssembly, XamlLanguageTypeMappings typeMappings, XamlXmlnsMappings xmlnsMappings, XamlValueConverter customValueConverter) in D:\a\XamlX\XamlX\src\XamlX\Transform\TransformerConfiguration.cs:line 59
   at XamlParserTests.CompilerTestBase..ctor(IXamlTypeSystem typeSystem) in D:\a\XamlX\XamlX\tests\XamlParserTests\CompilerTestBase.cs:line 30
Test Run Failed.
   at XamlParserTests.CompilerTestBase..ctor() in D:\a\XamlX\XamlX\tests\XamlParserTests\CompilerTestBase.cs:line 82
   at XamlParserTests.BasicCompilerTests..ctor()
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)

Total tests: 2
     Passed: 1
     Failed: 1
 Total time: 11.4751 Seconds

If you write ToList() here, then everything will be fine https://github.com/kekekeks/XamlX/blob/697a419675a8055b7ef9a1904360359522b30616/src/XamlX/IL/SreTypeSystem.cs#L18

Unlike #33, here it seems to me that the problem of the main library

rstm-sf avatar Oct 17 '20 14:10 rstm-sf

Since collection is guaranteed to be append-only, we should probably use a specialized enumerator there, e. g.


    struct AppendOnlyListEnumerator<T> : IEnumerator<T>
    {
        private readonly IReadOnlyList<T> _list;
        private int _index;

        public AppendOnlyListEnumerator(IReadOnlyList<T> list)
        {
            _list = list;
            _index = -1;
        }

        public bool MoveNext()
        {
            if (_list.Count > _index + 1)
            {
                _index++;
                return true;
            }
            return false;
        }

        public void Reset() => _index = -1;

        public T Current => _list[_index];

        object IEnumerator.Current => Current;

        public void Dispose()
        {
        }
    }

    struct AppendOnlyEnumerable<T> : IEnumerable<T>
    {
        private readonly IReadOnlyList<T> _list;

        public AppendOnlyEnumerable(IReadOnlyList<T> list)
        {
            _list = list;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return new AppendOnlyListEnumerator<T>(_list);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    static class ListExtensions
    {
        public static AppendOnlyEnumerable<T> EnumerateAsAppendOnly<T>(this List<T> list) =>
            new AppendOnlyEnumerable<T>(list);
    }

kekekeks avatar Oct 17 '20 15:10 kekekeks

Can we replace IReadOnlyList with IEnumerable in a similar way?

rstm-sf avatar Oct 19 '20 20:10 rstm-sf