Skip to content

Commit a95ee6f

Browse files
authored
Rework Type Refs into Generic -> External & Internal (#990)
1 parent 5cf58c8 commit a95ee6f

File tree

11 files changed

+83
-38
lines changed

11 files changed

+83
-38
lines changed

src/generators/Silk.NET.SilkTouch.Emitter/CSharpEmitter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ protected override FieldSymbol VisitField(FieldSymbol fieldSymbol)
109109
{
110110
AssertClearState();
111111

112-
VisitExternalTypeReference(fieldSymbol.Type);
112+
VisitTypeReference(fieldSymbol.Type);
113113
if (_syntax is not IdentifierNameSyntax typeIdentifierSyntax)
114114
throw new InvalidOperationException("Field type Identifier was not visited correctly");
115115
ClearState();

src/generators/Silk.NET.SilkTouch.Scraper/XmlVisitor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ private IEnumerable<Symbol> VisitField(XmlElement field)
4040
throw new InvalidOperationException("Field requires a name");
4141
}
4242

43+
// TODO: Appropriately Visit Type.
4344
var type = new ExternalTypeReference
4445
(
4546
null,

src/generators/Silk.NET.SilkTouch.Symbols/ExternalTypeReference.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ namespace Silk.NET.SilkTouch.Symbols;
66
/// <summary>
77
/// Represents a reference to an external type
88
/// </summary>
9-
public record ExternalTypeReference(IdentifierSymbol? Namespace, IdentifierSymbol TypeIdentifier) : Symbol
9+
public sealed record ExternalTypeReference(IdentifierSymbol? Namespace, IdentifierSymbol TypeIdentifier) : TypeReference
1010
{
11-
/// <summary>
12-
/// Gets the full unique name in C# global:: format.
13-
/// </summary>
14-
public string FullType => (Namespace is not null ? "global::" + Namespace.ToString() + "." : "") + TypeIdentifier.ToString();
1511
}

src/generators/Silk.NET.SilkTouch.Symbols/FieldSymbol.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Silk.NET.SilkTouch.Symbols;
66
/// <summary>
77
/// A <see cref="FieldSymbol"/>. A field is simply a named location that can hold some type.
88
/// </summary>
9-
/// <param name="Type">The <see cref="ExternalTypeReference"/> of the data stored in this field</param>
9+
/// <param name="Type">The <see cref="TypeReference"/> of the data stored in this field</param>
1010
/// <param name="Identifier">The Identifier of this field</param>
1111
/// <seealso cref="MemberSymbol"/>
12-
public sealed record FieldSymbol(ExternalTypeReference Type, IdentifierSymbol Identifier) : MemberSymbol;
12+
public sealed record FieldSymbol(TypeReference Type, IdentifierSymbol Identifier) : MemberSymbol;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Silk.NET.SilkTouch.Symbols;
5+
6+
/// <summary>
7+
/// Represents a reference to a type that is also defined as part of this symbol tree.
8+
/// </summary>
9+
/// <param name="Referenced">The Type referenced</param>
10+
public sealed record InternalTypeReference(TypeSymbol Referenced) : TypeReference()
11+
{
12+
}

src/generators/Silk.NET.SilkTouch.Symbols/SymbolVisitor.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public virtual Symbol Visit(Symbol symbol)
2222
if (symbol is NamespaceSymbol ns) return VisitNamespace(ns);
2323

2424
if (symbol is IdentifierSymbol @is) return VisitIdentifier(@is);
25-
if (symbol is ExternalTypeReference etr) return VisitExternalTypeReference(etr);
25+
if (symbol is TypeReference etr) return VisitTypeReference(etr);
2626

2727
return ThrowUnknownSymbol<Symbol>(symbol);
2828
}
@@ -50,11 +50,39 @@ protected virtual MemberSymbol VisitMember(MemberSymbol memberSymbol)
5050
/// </remarks>
5151
protected virtual FieldSymbol VisitField(FieldSymbol fieldSymbol)
5252
{
53-
return new FieldSymbol(VisitExternalTypeReference(fieldSymbol.Type), VisitIdentifier(fieldSymbol.Identifier));
53+
return new FieldSymbol(VisitTypeReference(fieldSymbol.Type), VisitIdentifier(fieldSymbol.Identifier));
5454
}
5555

5656
/// <summary>
57-
/// Visit an <see cref="ExternalTypeReference"/>. Will call the appropriate methods to visit the different parts of the reference.
57+
/// Visit a <see cref="TypeReference"/>. Will call the appropriate methods to visit the different parts of the symbol.
58+
/// </summary>
59+
/// <param name="typeReference">The type reference to visit</param>
60+
/// <returns>The rewritten symbol</returns>
61+
/// <remarks>
62+
/// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order.
63+
/// </remarks>
64+
protected virtual TypeReference VisitTypeReference(TypeReference typeReference)
65+
{
66+
if (typeReference is ExternalTypeReference etr) return VisitExternalTypeReference(etr);
67+
if (typeReference is InternalTypeReference itr) return VisitInternalTypeReference(itr);
68+
return ThrowUnknownSymbol<TypeReference>(typeReference);
69+
}
70+
71+
/// <summary>
72+
/// Visit a <see cref="InternalTypeReference"/>. Will call the appropriate methods to visit the different parts of the symbol.
73+
/// </summary>
74+
/// <param name="typeReference">The type reference to visit</param>
75+
/// <returns>The rewritten symbol</returns>
76+
/// <remarks>
77+
/// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order.
78+
/// </remarks>
79+
protected virtual InternalTypeReference VisitInternalTypeReference(InternalTypeReference typeReference)
80+
{
81+
return new InternalTypeReference(VisitType(typeReference.Referenced));
82+
}
83+
84+
/// <summary>
85+
/// Visit a <see cref="ExternalTypeReference"/>. Will call the appropriate methods to visit the different parts of the symbol.
5886
/// </summary>
5987
/// <param name="typeReference">The type reference to visit</param>
6088
/// <returns>The rewritten symbol</returns>
@@ -65,7 +93,7 @@ protected virtual ExternalTypeReference VisitExternalTypeReference(ExternalTypeR
6593
{
6694
return new ExternalTypeReference
6795
(
68-
typeReference.Namespace is null ? null : VisitIdentifier(typeReference.Namespace),
96+
typeReference.Namespace is not null ? VisitIdentifier(typeReference.Namespace) : null,
6997
VisitIdentifier(typeReference.TypeIdentifier)
7098
);
7199
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Silk.NET.SilkTouch.Symbols;
5+
6+
/// <summary>
7+
/// Represents a reference to a type, commonly used in places where a type needs to be referenced, but no access to all its members is required.
8+
/// </summary>
9+
/// <seealso cref="ExternalTypeReference"/>
10+
/// <seealso cref="InternalTypeReference"/>
11+
public abstract record TypeReference() : Symbol
12+
{
13+
}

tests/Silk.NET.SilkTouch.Scraper.Tests/FieldScrapingTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public void CorrectType()
5050

5151
var symbol = Assert.Single(symbols);
5252
var field = Assert.IsType<FieldSymbol>(symbol);
53-
Assert.Equal("int", field.Type.FullType);
53+
var type = Assert.IsType<ExternalTypeReference>(field.Type);
54+
Assert.Equal("int", type.TypeIdentifier.Value);
55+
Assert.Null(type.Namespace);
5456
}
5557
}

tests/Silk.NET.SilkTouch.Symbols.Tests/ExternalTypeReferenceTests.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ public void RefIsVisitedAsRef()
2525
.Verify<ExternalTypeReference>("VisitExternalTypeReference", Times.Once(), ItExpr.IsAny<ExternalTypeReference>());
2626
}
2727

28+
[Fact,
29+
Trait("Category", "Symbols")]
30+
public void RefIsVisitedAsGenericRef()
31+
{
32+
var symbol = new ExternalTypeReference(null, new IdentifierSymbol(""));
33+
var visitor = new Mock<SymbolVisitor>
34+
{
35+
CallBase = true
36+
};
37+
38+
visitor.Object.Visit(symbol);
39+
40+
visitor.Protected()
41+
.Verify<TypeReference>("VisitTypeReference", Times.Once(), ItExpr.IsAny<TypeReference>());
42+
}
43+
2844
[Fact,
2945
Trait("Category", "Symbols")]
3046
public void RefTypeIdentifierIsVisitedAsIdentifier()

tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ public void FieldIdentifierIsVisited()
7474

7575
visitor.Object.Visit(symbol);
7676

77-
// note that this also tests whether the struct identifier is visited, there's just no good way of testing JUST the field identifier
7877
visitor.Protected()
79-
.Verify<ExternalTypeReference>("VisitExternalTypeReference", Times.Exactly(1), ItExpr.IsAny<ExternalTypeReference>());
78+
.Verify<IdentifierSymbol>
79+
("VisitIdentifier", Times.Exactly(1), ItExpr.Is<IdentifierSymbol>(x => object.ReferenceEquals(x, symbol.Identifier)));
8080
}
8181
}

0 commit comments

Comments
 (0)