Skip to content

Commit

Permalink
Merge pull request #223 from JPaja/issue/multigeneric-typenameparser
Browse files Browse the repository at this point in the history
Fix: Multiple generics support in TypeNameParser
  • Loading branch information
Washi1337 authored Nov 28, 2021
2 parents 42d6727 + 4bb1eb9 commit 8977a4d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ private ArrayDimension ParseArrayDimension()
private TypeSignature ParseGenericTypeSpec(TypeSignature typeName)
{
var result = new GenericInstanceTypeSignature(typeName.ToTypeDefOrRef(), typeName.IsValueType);

result.TypeArguments.Add(ParseGenericTypeArgument(result));

bool stop = false;
Expand All @@ -248,7 +249,9 @@ private TypeSignature ParseGenericTypeSpec(TypeSignature typeName)
private TypeSignature ParseGenericTypeArgument(GenericInstanceTypeSignature genericInstance)
{
var extraBracketToken = TryExpect(TypeNameTerminal.OpenBracket);
var result = ParseTypeSpec();
var result = !extraBracketToken.HasValue
? ParseSimpleTypeSpec()
: ParseTypeSpec();
if (extraBracketToken.HasValue)
Expect(TypeNameTerminal.CloseBracket);
return result;
Expand Down
55 changes: 55 additions & 0 deletions test/AsmResolver.DotNet.Tests/Signatures/TypeNameParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,43 @@ public void GenericTypeSingleBrackets()
Assert.Equal(expected, actual, _comparer);
}

[Fact]
public void GenericTypeSingleBracketsMultiElements()
{
const string ns = "MyNamespace";
const string name = "MyType";

var elementType = new TypeReference(_module, ns, name);
var argumentType = _module.CorLibTypeFactory.Object;
var argumentType2 = _module.CorLibTypeFactory.Int32;

var expected = new GenericInstanceTypeSignature(elementType, false, argumentType, argumentType2);

var actual = TypeNameParser.Parse(_module, $"{ns}.{name}[{argumentType.Namespace}.{argumentType.Name},{argumentType2.Namespace}.{argumentType2.Name}]");
Assert.Equal(expected, actual, _comparer);
}


[Fact]
public void GenericTypeSingleBracketsMultiElementsWithPlus()
{
const string ns = "MyNamespace";
const string name = "MyType";

const string escapedPName = "MyType\\+WithPlus";
const string pname = "MyType+WithPlus";


var elementType = new TypeReference(_module, ns, name);
var argumentType = _module.CorLibTypeFactory.Object;
var argumentType2 = new TypeReference(_module, ns, pname).ToTypeSignature(); ;

var expected = new GenericInstanceTypeSignature(elementType, false, argumentType, argumentType2);

var actual = TypeNameParser.Parse(_module, $"{ns}.{name}[{argumentType.Namespace}.{argumentType.Name},{ns}.{escapedPName}]");
Assert.Equal(expected, actual, _comparer);
}

[Theory]
[InlineData("System", "Object")]
[InlineData("System", "#=abc")]
Expand All @@ -166,6 +203,24 @@ public void GenericTypeMultiBrackets(string argNs, string argName)
Assert.Equal(expected, actual, _comparer);
}

[Fact]
public void GenericTypeMultiBracketsMultiElementsVersion()
{
const string ns = "MyNamespace";
const string name = "MyType";

var elementType = new TypeReference(_module, ns, name);
var argumentType = _module.CorLibTypeFactory.Object;
var argumentType2 = _module.CorLibTypeFactory.Int32;
var fullName = _module.CorLibTypeFactory.CorLibScope.GetAssembly().FullName;

var expected = new GenericInstanceTypeSignature(elementType, false, argumentType, argumentType2);

var actual = TypeNameParser.Parse(_module, $"{ns}.{name}[[{argumentType.Namespace}.{argumentType.Name}, {fullName}],[{argumentType2.Namespace}.{argumentType2.Name}, {fullName}]]");
Assert.Equal(expected, actual, _comparer);
}


[Fact]
public void SpacesInAssemblySpec()
{
Expand Down

0 comments on commit 8977a4d

Please sign in to comment.