Exemple #1
0
        public void ToMemberId_returns_expected_value_for_generic_parameters_02()
        {
            // ARRANGE
            var cs = @"
                using System;
                using System.Collections.Generic;

                namespace Namespace1.Namespace2
                {
                    public class Class1<T1>
                    {
                        public void Method1(T1 foo) => throw new NotImplementedException();
                    }
                }
            ";

            using var assembly = Compile(cs);

            var typeReference = assembly.MainModule.Types
                                .Single(x => x.Name == "Class1`1")
                                .Methods
                                .Single(x => x.Name == "Method1")
                                .Parameters
                                .First()
                                .ParameterType;

            var expectedMemberId = new GenericTypeParameterId(GenericTypeParameterId.MemberKind.Type, 0);

            // ACT
            var actualMemberId = typeReference.ToMemberId();

            // ASSERT
            Assert.NotNull(actualMemberId);
            Assert.Equal(expectedMemberId, actualMemberId);
        }
Exemple #2
0
        private TypeId ParseTypeName()
        {
            TypeId type;

            if (TestAndMatchToken(MemberIdTokenKind.Backtick))
            {
                var index = Int32.Parse(MatchToken(MemberIdTokenKind.Number));
                type = new GenericTypeParameterId(GenericTypeParameterId.MemberKind.Type, index);
            }
            else if (TestAndMatchToken(MemberIdTokenKind.DoubleBacktick))
            {
                var index = Int32.Parse(MatchToken(MemberIdTokenKind.Number));
                type = new GenericTypeParameterId(GenericTypeParameterId.MemberKind.Method, index);
            }
            else
            {
                var typeIdBuilder = TypeIdBuilder.Create();

                // there needs to be at least one name segment
                typeIdBuilder = typeIdBuilder.AddNameSegment(MatchToken(MemberIdTokenKind.Name));

                // consume all name tokens as long as the current token is a '.'
                // A open brace '{' indicates the start of a list of type arguments
                while (TestToken(MemberIdTokenKind.Dot, MemberIdTokenKind.OpenBrace))
                {
                    if (TestAndMatchToken(MemberIdTokenKind.Dot))
                    {
                        // match a single name token and append it to the current type name
                        var name = MatchToken(MemberIdTokenKind.Name);
                        typeIdBuilder = typeIdBuilder.AddNameSegment(name);

                        if (m_OuterTypes.Contains(typeIdBuilder.ToTypeId()))
                        {
                            typeIdBuilder = typeIdBuilder.BeginNestedType();
                        }
                    }
                    else if (TestAndMatchToken(MemberIdTokenKind.OpenBrace))
                    {
                        // parse list of type arguments
                        var typeArguments = ParseTypeNameList();
                        typeIdBuilder = typeIdBuilder.SetTypeArguments(typeArguments);

                        if (m_OuterTypes.Contains(typeIdBuilder.ToTypeId()))
                        {
                            typeIdBuilder = typeIdBuilder.BeginNestedType();
                        }

                        // type argument list must be followed by a '}'
                        MatchToken(MemberIdTokenKind.CloseBrace);
                    }
                    else
                    {
                        // should never happen
                        throw new InvalidOperationException();
                    }
                }

                type = typeIdBuilder.ToTypeId();
            }

            // optional part: array declaration
            // if the type if followed by square brackets, the id refers to an array type
            // arrays of arrays are allowed, too
            type = ParseArraySuffix(type);

            // optional suffix: @
            // if the type is followed by an '@' the parameter is being parsed by reference
            // (methods with 'out' or 'ref' parameter)

            if (TestAndMatchToken(MemberIdTokenKind.At))
            {
                type = new ByReferenceTypeId(type);
            }

            return(type);
        }