Skip to content

Rework Type Refs into Generic -> External & Internal #990

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ protected override FieldSymbol VisitField(FieldSymbol fieldSymbol)
{
AssertClearState();

VisitExternalTypeReference(fieldSymbol.Type);
VisitTypeReference(fieldSymbol.Type);
if (_syntax is not IdentifierNameSyntax typeIdentifierSyntax)
throw new InvalidOperationException("Field type Identifier was not visited correctly");
ClearState();
Expand Down
1 change: 1 addition & 0 deletions src/generators/Silk.NET.SilkTouch.Scraper/XmlVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ private IEnumerable<Symbol> VisitField(XmlElement field)
throw new InvalidOperationException("Field requires a name");
}

// TODO: Appropriately Visit Type.
var type = new ExternalTypeReference
(
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ namespace Silk.NET.SilkTouch.Symbols;
/// <summary>
/// Represents a reference to an external type
/// </summary>
public record ExternalTypeReference(IdentifierSymbol? Namespace, IdentifierSymbol TypeIdentifier) : Symbol
public sealed record ExternalTypeReference(IdentifierSymbol? Namespace, IdentifierSymbol TypeIdentifier) : TypeReference
{
/// <summary>
/// Gets the full unique name in C# global:: format.
/// </summary>
public string FullType => (Namespace is not null ? "global::" + Namespace.ToString() + "." : "") + TypeIdentifier.ToString();
}
4 changes: 2 additions & 2 deletions src/generators/Silk.NET.SilkTouch.Symbols/FieldSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Silk.NET.SilkTouch.Symbols;
/// <summary>
/// A <see cref="FieldSymbol"/>. A field is simply a named location that can hold some type.
/// </summary>
/// <param name="Type">The <see cref="ExternalTypeReference"/> of the data stored in this field</param>
/// <param name="Type">The <see cref="TypeReference"/> of the data stored in this field</param>
/// <param name="Identifier">The Identifier of this field</param>
/// <seealso cref="MemberSymbol"/>
public sealed record FieldSymbol(ExternalTypeReference Type, IdentifierSymbol Identifier) : MemberSymbol;
public sealed record FieldSymbol(TypeReference Type, IdentifierSymbol Identifier) : MemberSymbol;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Silk.NET.SilkTouch.Symbols;

/// <summary>
/// Represents a reference to a type that is also defined as part of this symbol tree.
/// </summary>
/// <param name="Referenced">The Type referenced</param>
public sealed record InternalTypeReference(TypeSymbol Referenced) : TypeReference()
{
}
36 changes: 32 additions & 4 deletions src/generators/Silk.NET.SilkTouch.Symbols/SymbolVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public virtual Symbol Visit(Symbol symbol)
if (symbol is NamespaceSymbol ns) return VisitNamespace(ns);

if (symbol is IdentifierSymbol @is) return VisitIdentifier(@is);
if (symbol is ExternalTypeReference etr) return VisitExternalTypeReference(etr);
if (symbol is TypeReference etr) return VisitTypeReference(etr);

return ThrowUnknownSymbol<Symbol>(symbol);
}
Expand Down Expand Up @@ -50,11 +50,39 @@ protected virtual MemberSymbol VisitMember(MemberSymbol memberSymbol)
/// </remarks>
protected virtual FieldSymbol VisitField(FieldSymbol fieldSymbol)
{
return new FieldSymbol(VisitExternalTypeReference(fieldSymbol.Type), VisitIdentifier(fieldSymbol.Identifier));
return new FieldSymbol(VisitTypeReference(fieldSymbol.Type), VisitIdentifier(fieldSymbol.Identifier));
}

/// <summary>
/// Visit an <see cref="ExternalTypeReference"/>. Will call the appropriate methods to visit the different parts of the reference.
/// Visit a <see cref="TypeReference"/>. Will call the appropriate methods to visit the different parts of the symbol.
/// </summary>
/// <param name="typeReference">The type reference to visit</param>
/// <returns>The rewritten symbol</returns>
/// <remarks>
/// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order.
/// </remarks>
protected virtual TypeReference VisitTypeReference(TypeReference typeReference)
{
if (typeReference is ExternalTypeReference etr) return VisitExternalTypeReference(etr);
if (typeReference is InternalTypeReference itr) return VisitInternalTypeReference(itr);
return ThrowUnknownSymbol<TypeReference>(typeReference);
}

/// <summary>
/// Visit a <see cref="InternalTypeReference"/>. Will call the appropriate methods to visit the different parts of the symbol.
/// </summary>
/// <param name="typeReference">The type reference to visit</param>
/// <returns>The rewritten symbol</returns>
/// <remarks>
/// The order in which the parts of the struct are visited is kept as an implementation detail. Do not rely on this order.
/// </remarks>
protected virtual InternalTypeReference VisitInternalTypeReference(InternalTypeReference typeReference)
{
return new InternalTypeReference(VisitType(typeReference.Referenced));
}

/// <summary>
/// Visit a <see cref="ExternalTypeReference"/>. Will call the appropriate methods to visit the different parts of the symbol.
/// </summary>
/// <param name="typeReference">The type reference to visit</param>
/// <returns>The rewritten symbol</returns>
Expand All @@ -65,7 +93,7 @@ protected virtual ExternalTypeReference VisitExternalTypeReference(ExternalTypeR
{
return new ExternalTypeReference
(
typeReference.Namespace is null ? null : VisitIdentifier(typeReference.Namespace),
typeReference.Namespace is not null ? VisitIdentifier(typeReference.Namespace) : null,
VisitIdentifier(typeReference.TypeIdentifier)
);
}
Expand Down
13 changes: 13 additions & 0 deletions src/generators/Silk.NET.SilkTouch.Symbols/TypeReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Silk.NET.SilkTouch.Symbols;

/// <summary>
/// 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.
/// </summary>
/// <seealso cref="ExternalTypeReference"/>
/// <seealso cref="InternalTypeReference"/>
public abstract record TypeReference() : Symbol
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public void CorrectType()

var symbol = Assert.Single(symbols);
var field = Assert.IsType<FieldSymbol>(symbol);
Assert.Equal("int", field.Type.FullType);
var type = Assert.IsType<ExternalTypeReference>(field.Type);
Assert.Equal("int", type.TypeIdentifier.Value);
Assert.Null(type.Namespace);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ public void RefIsVisitedAsRef()
.Verify<ExternalTypeReference>("VisitExternalTypeReference", Times.Once(), ItExpr.IsAny<ExternalTypeReference>());
}

[Fact,
Trait("Category", "Symbols")]
public void RefIsVisitedAsGenericRef()
{
var symbol = new ExternalTypeReference(null, new IdentifierSymbol(""));
var visitor = new Mock<SymbolVisitor>
{
CallBase = true
};

visitor.Object.Visit(symbol);

visitor.Protected()
.Verify<TypeReference>("VisitTypeReference", Times.Once(), ItExpr.IsAny<TypeReference>());
}

[Fact,
Trait("Category", "Symbols")]
public void RefTypeIdentifierIsVisitedAsIdentifier()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public void FieldIdentifierIsVisited()

visitor.Object.Visit(symbol);

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