Skip to content
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
6 changes: 3 additions & 3 deletions src/Zomp.MethodCloning.Variants/VariantGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ private static ImmutableArray<ClonedMethod> Clone(CloneTarget target, Cancellati

// Each variant keeps the nullable context the method was written in, so that a method
// written without annotations does not gain them in its variants.
var disableNullable = !context.SemanticModel.GetNullableContext(syntax.SpanStart).AnnotationsEnabled();
var nullableDisabled = !context.SemanticModel.GetNullableContext(syntax.SpanStart).AnnotationsEnabled();

var name = syntax.Identifier.ValueText;

if (name.IndexOf(original, StringComparison.Ordinal) < 0)
{
var diagnostic = ReportedDiagnostic.Create(VariantDiagnostics.NameWithoutOriginal, syntax.Identifier.GetLocation(), name);
return ImmutableArray.Create(ClonedMethod.Create(location, syntax, syntax, disableNullable, ImmutableArray.Create(diagnostic)));
return ImmutableArray.Create(ClonedMethod.Create(location, syntax, syntax, nullableDisabled, ImmutableArray.Create(diagnostic)));
}

var clones = ImmutableArray.CreateBuilder<ClonedMethod>();
Expand All @@ -128,7 +128,7 @@ private static ImmutableArray<ClonedMethod> Clone(CloneTarget target, Cancellati
// Each file is named after the method and the variant. The variant's name alone would
// not do: methods written for different variants, such as GetBmpMetadata and an
// overload GetGifMetadata, can both produce a GetPngMetadata.
clones.Add(ClonedMethod.Create(variantLocation, syntax, rewritten, disableNullable, rewriter.Diagnostics, $"{name}.{to}"));
clones.Add(ClonedMethod.Create(variantLocation, syntax, rewritten, nullableDisabled, rewriter.Diagnostics, $"{name}.{to}"));
}

return clones.ToImmutable();
Expand Down
4 changes: 2 additions & 2 deletions src/Zomp.MethodCloning.Variants/VariantRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal sealed class VariantRewriter(SemanticModel semanticModel, MethodDeclara
// The base qualifies a return type written as a generic, nullable or qualified name, but
// leaves one written as a simple name, which may name the variant, as it is.
var returnType = node.ReturnType is IdentifierNameSyntax
? ProcessType(node.ReturnType).WithTriviaFrom(clone.ReturnType)
? Qualify(node.ReturnType).WithTriviaFrom(clone.ReturnType)
: clone.ReturnType;

return clone
Expand Down Expand Up @@ -105,7 +105,7 @@ internal sealed class VariantRewriter(SemanticModel semanticModel, MethodDeclara
if (SemanticModel.Compilation.GetTypeByMetadataName(counterpartName) is { } counterpart
&& !SymbolEqualityComparer.Default.Equals(counterpart, type))
{
return ProcessSymbol(counterpart);
return Qualify(counterpart);
}

if (methodLocation is not null && !kept.Contains(type, SymbolEqualityComparer.Default))
Expand Down
26 changes: 13 additions & 13 deletions src/Zomp.MethodCloning/ClonedMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ namespace Zomp.MethodCloning;
/// A method rewritten by a transformation, ready to be emitted into a file of its own.
/// </summary>
/// <param name="Location">Where the original method sits.</param>
/// <param name="MethodName">Name of the original method.</param>
/// <param name="FileName">Stem of the name of the file the method is emitted to, by default the name of the original method.</param>
/// <param name="Implementation">The rewritten method.</param>
/// <param name="DisableNullable">True to leave the <c>#nullable enable</c> directive out of the file.</param>
/// <param name="NullableDisabled">True to leave the <c>#nullable enable</c> directive out of the file.</param>
/// <param name="Diagnostics">Diagnostics the transformation reported.</param>
/// <param name="HasErrors">True if there are errors in <see cref="Diagnostics"/>, in which case nothing is emitted.</param>
/// <param name="Signature">Signature the rewritten method will be emitted with, used to detect colliding overloads.</param>
internal sealed record ClonedMethod(
MethodLocation Location,
string MethodName,
string FileName,
string Implementation,
bool DisableNullable,
bool NullableDisabled,
EquatableArray<ReportedDiagnostic> Diagnostics,
bool HasErrors,
MethodSignature? Signature)
Expand All @@ -34,21 +34,21 @@ internal sealed record ClonedMethod(
/// <param name="location">Where the original method sits.</param>
/// <param name="original">Declaration of the original method.</param>
/// <param name="rewritten">Result of rewriting the method, or the extension block which holds it.</param>
/// <param name="disableNullable">True to leave the <c>#nullable enable</c> directive out of the file.</param>
/// <param name="nullableDisabled">True to leave the <c>#nullable enable</c> directive out of the file.</param>
/// <param name="diagnostics">Diagnostics the transformation reported.</param>
/// <param name="name">
/// Name the file is emitted under. A transformation which clones a method more than once
/// gives each copy its own, since files named after the same method would collide. Defaults to
/// the name of the original method.
/// <param name="fileName">
/// Stem of the name of the file the method is emitted to. A transformation which clones a
/// method more than once gives each copy its own, since files named after the same method
/// would collide. Defaults to the name of the original method.
/// </param>
/// <returns>A new <see cref="ClonedMethod"/>.</returns>
public static ClonedMethod Create(
MethodLocation location,
MethodDeclarationSyntax original,
SyntaxNode rewritten,
bool disableNullable,
bool nullableDisabled,
ImmutableArray<ReportedDiagnostic> diagnostics,
string? name = null)
string? fileName = null)
{
var hasErrors = false;
foreach (var diagnostic in diagnostics)
Expand All @@ -58,9 +58,9 @@ public static ClonedMethod Create(

return new(
location,
name ?? original.Identifier.ValueText,
fileName ?? original.Identifier.ValueText,
rewritten.ToFullString(),
disableNullable,
nullableDisabled,
diagnostics,
hasErrors,
MethodSignature.Create(rewritten, location, original));
Expand Down
4 changes: 2 additions & 2 deletions src/Zomp.MethodCloning/ClonedMethodOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ private static (ClonedMethod Method, string Path, string Content) GenerateSource
{
var location = m.Location;

var scope = location.Scope + (location.IsCSharp14Extension ? ".ext" : string.Empty);
var scope = location.Scope + (location.IsInExtensionBlock ? ".ext" : string.Empty);

var method = m.MethodName + (location.Index == 1 ? string.Empty : "_" + location.Index);
var method = m.FileName + (location.OverloadIndex == 1 ? string.Empty : "_" + location.OverloadIndex);

var sourcePath = BuildFileName(scope, method);

Expand Down
18 changes: 9 additions & 9 deletions src/Zomp.MethodCloning/ClonedMethodSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,17 @@ public static string Generate(ClonedMethod method)
}

// Handle classes
foreach (var parent in location.Parents)
foreach (var parent in location.ContainingTypes)
{
var indent = new string(' ', 4 * i);

var modifiers = string.Join(string.Empty, parent.Modifiers.Select(z => GetKeyword((SyntaxKind)z) + " "));
var parentType = parent.MethodParent switch
var parentType = parent.Kind switch
{
MethodParent.Class => "class",
MethodParent.Interface => "interface",
MethodParent.Struct => "struct",
MethodParent.Record => "record"
ContainingTypeKind.Class => "class",
ContainingTypeKind.Interface => "interface",
ContainingTypeKind.Struct => "struct",
ContainingTypeKind.Record => "record"
+ parent.ClassOrStructKeyword.Kind() switch
{
SyntaxKind.StructKeyword => " struct",
Expand All @@ -101,8 +101,8 @@ public static string Generate(ClonedMethod method)
_ => throw new NotImplementedException("Cannot handle the parent of the method"),
};

var classDeclarationLine = $"{modifiers}partial {parentType} {parent.ParentName}{(parent.TypeParameterListSyntax.IsEmpty ? string.Empty
: "<" + string.Join(", ", parent.TypeParameterListSyntax) + ">")}";
var classDeclarationLine = $"{modifiers}partial {parentType} {parent.Name}{(parent.TypeParameters.IsEmpty ? string.Empty
: "<" + string.Join(", ", parent.TypeParameters) + ">")}";

_ = sbBegin.Append(FormattableString.Invariant($$"""
{{indent}}{{classDeclarationLine}}
Expand Down Expand Up @@ -136,7 +136,7 @@ public static string Generate(ClonedMethod method)
}

var beforeNamespace = $"""
// <auto-generated/>{(method.DisableNullable ? string.Empty : """
// <auto-generated/>{(method.NullableDisabled ? string.Empty : """

#nullable enable
""")}{sbOuterUsings}
Expand Down
Loading
Loading