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); }
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); }