Skip to content

Commit

Permalink
Apply some code comments, clean-up the YAML Parsing method
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-hawker committed May 4, 2022
1 parent 0172351 commit 5b373f6
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace CommunityToolkit.Labs.Core.SourceGenerators.Tests
{
public partial class ToolkitSampleMetadataTests
{
//// We currently need at least one sample to test the document registry, so we'll have this for the base cases to share.
// We currently need at least one sample to test the document registry, so we'll have this for the base cases to share.
private static readonly string SimpleSource = $@"
using System.ComponentModel;
using CommunityToolkit.Labs.Core.SourceGenerators;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ from assembly in AppDomain.CurrentDomain.GetAssemblies()
GC.KeepAlive(sampleAttributeType);
}

//// From: https://github.com/dotnet/roslyn/blob/main/src/Compilers/Test/Core/SourceGeneration/TestGenerators.cs
// From: https://github.com/dotnet/roslyn/blob/main/src/Compilers/Test/Core/SourceGeneration/TestGenerators.cs
internal class InMemoryAdditionalText : AdditionalText
{
private readonly SourceText _content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,45 @@ namespace CommunityToolkit.Labs.Core.SourceGenerators.Metadata;
/// </summary>
public sealed class ToolkitSampleMetadata
{
/// <summary>
/// Gets or sets a unique identifier for the sample, across all samples.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets the display name for this sample page.
/// </summary>
public string DisplayName { get; set; }

/// <summary>
/// Gets or sets the description for this sample page.
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets a type that can be used to construct an instance of the sample control.
/// </summary>
public Type SampleControlType { get; set; }

/// <summary>
/// Gets or sets a factory method that returns a new instance of the control.
/// </summary>
public Func<object> SampleControlFactory { get; set; }

/// <summary>
/// Gets or sets the (optional) control type for the sample page's options pane.
/// Constructor should have exactly one parameter that can be assigned to the control type (<see cref="SampleControlType"/>).
/// </summary>
public Type? SampleOptionsPaneType { get; set; }

/// <summary>
/// Gets or sets a factory method that returns a new instance of the sample options control.
/// </summary>
public Func<object, object>? SampleOptionsPaneFactory { get; set; }

/// <summary>
/// Gets or sets the generated sample options that were declared alongside this sample, if any.
/// </summary>
public IEnumerable<IGeneratedToolkitSampleOptionViewModel>? GeneratedSampleOptions { get; set; }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@

namespace CommunityToolkit.Labs.Core.SourceGenerators;

/// <summary>
/// This part of the partial class deals with finding Markdown files and creating
/// <see cref="ToolkitFrontMatter"/> metadata from it.
/// </summary>
// This part of the partial class deals with finding Markdown files
// and creating ToolkitFrontMatter metadata from it.
public partial class ToolkitSampleMetadataGenerator
{
private const string FrontMatterRegexTitleExpression = @"^title:\s*(?<title>.*)$";
Expand Down Expand Up @@ -117,14 +115,14 @@ private ImmutableArray<ToolkitFrontMatter> GatherDocumentFrontMatter(SourceProdu
var subcategory = ParseYamlField(ref ctx, file.Path, ref frontmatter, FrontMatterRegexSubcategory, "subcategory");
// Check we have all the fields we expect to continue (errors will have been spit out otherwise already from the ParseYamlField method)
if (!(title.Success && description.Success && keywords.Success &&
category.Success && subcategory.Success))
if (title == null || description == null || keywords == null ||
category == null || subcategory == null)
{
return null;
}
// Grab/Check Enum values
if (!Enum.TryParse<ToolkitSampleCategory>(category.Text, out var categoryValue))
if (!Enum.TryParse<ToolkitSampleCategory>(category, out var categoryValue))
{
// TODO: extract index to get proper line number?
ctx.ReportDiagnostic(
Expand All @@ -136,7 +134,7 @@ private ImmutableArray<ToolkitFrontMatter> GatherDocumentFrontMatter(SourceProdu
return null;
}
if (!Enum.TryParse<ToolkitSampleSubcategory>(subcategory.Text, out var subcategoryValue))
if (!Enum.TryParse<ToolkitSampleSubcategory>(subcategory, out var subcategoryValue))
{
// TODO: extract index to get proper line number?
ctx.ReportDiagnostic(
Expand Down Expand Up @@ -173,9 +171,9 @@ private ImmutableArray<ToolkitFrontMatter> GatherDocumentFrontMatter(SourceProdu
// Finally, construct the complete object.
return new ToolkitFrontMatter()
{
Title = title.Text,
Description = description.Text,
Keywords = keywords.Text,
Title = title!,
Description = description!,
Keywords = keywords!,
Category = categoryValue,
Subcategory = subcategoryValue,
FilePath = filepath,
Expand All @@ -185,7 +183,7 @@ private ImmutableArray<ToolkitFrontMatter> GatherDocumentFrontMatter(SourceProdu
}).OfType<ToolkitFrontMatter>().ToImmutableArray();
}

private (bool Success, string? Text) ParseYamlField(ref SourceProductionContext ctx, string filepath, ref string content, Regex pattern, string fieldname)
private string? ParseYamlField(ref SourceProductionContext ctx, string filepath, ref string content, Regex pattern, string fieldname)
{
var match = pattern.Match(content);

Expand All @@ -197,10 +195,10 @@ private ImmutableArray<ToolkitFrontMatter> GatherDocumentFrontMatter(SourceProdu
Location.Create(filepath, TextSpan.FromBounds(0, 1), new LinePositionSpan(LinePosition.Zero, LinePosition.Zero)),
filepath,
fieldname));
return (false, null);
return null;
}

return (true, match.Groups[fieldname].Value.Trim());
return match.Groups[fieldname].Value.Trim();
}

private void AddDocuments(SourceProductionContext ctx, ImmutableArray<ToolkitFrontMatter> matter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace CommunityToolkit.Labs.Core.SourceGenerators;

/// <summary>
/// Crawls all referenced projects for <see cref="ToolkitSampleAttribute"/>s and generates a static method that returns metadata for each one found.
/// Crawls all referenced projects for <see cref="ToolkitSampleAttribute"/>s and generates a static method that returns metadata for each one found. Uses markdown files to generate a listing of <see cref="ToolkitFrontMatter"/> data and an index of references samples for them.
/// </summary>
[Generator]
public partial class ToolkitSampleMetadataGenerator : IIncrementalGenerator
Expand Down Expand Up @@ -72,7 +72,7 @@ void Execute(IncrementalValuesProvider<ISymbol> types)
.Collect();

var markdownFiles = context.AdditionalTextsProvider
.Where(static file => file.Path.EndsWith(".md")) // TODO: file.Path.Contains("samples") - this seems to break things?
.Where(static file => file.Path.EndsWith(".md"))
.Collect();

var all = optionsPaneAttributes
Expand Down Expand Up @@ -104,7 +104,7 @@ void Execute(IncrementalValuesProvider<ISymbol> types)
)
);
//// TODO: NOTE: BUGBUG: This is currently guarding us generating duplicate document registeries based on how the SG are setup to run twice to gather samples depending on how they're loaded.
//// TODO: NOTE: BUGBUG: This is currently guarding us generating duplicate document registeries based on how the SG are setup to run this Execute method twice to gather samples depending on how they're loaded.
//// However, that also means that if a sample only contains documentation without samples we won't load it. That shouldn't be the case currently, though makes testing more difficult.
if (!sampleMetadata.Any())
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ private async Task LoadData()
return;
}

// TODO: Show list of samples in a side-panel
List<ToolkitSampleMetadata> samples = new();
if (Metadata.SampleIdReferences != null && Metadata.SampleIdReferences.Length > 0 &&
!string.IsNullOrWhiteSpace(Metadata.SampleIdReferences[0]))
Expand Down Expand Up @@ -154,7 +153,6 @@ private void SampleListHyperlink_Click(object sender, RoutedEventArgs e)

private static async Task<string> GetDocumentationFileContents(ToolkitFrontMatter metadata)
{
// TODO: Path will be different if single vs. multi-sample?
var fileUri = new Uri($"ms-appx:///SourceAssets/{metadata.FilePath}");

try
Expand Down
32 changes: 17 additions & 15 deletions common/CommunityToolkit.Labs.Shared/TabbedPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,31 @@ public TabbedPage()

protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Note: Need to use as for tuple, think this is the tracking issue here: https://github.com/dotnet/csharplang/issues/3197
var info = e.Parameter as (IEnumerable<ToolkitSampleMetadata> Samples, IEnumerable<ToolkitFrontMatter> Docs, bool AreDocsFirst)?;

if (info is not null)
if (info is null)
{
if (info.Value.AreDocsFirst)
{
foreach (var item in info.Value.Docs)
{
Items.Add(item);
}
}

foreach (var item in info.Value.Samples)
return;
}
else if (info.Value.AreDocsFirst)
{
foreach (var item in info.Value.Docs)
{
Items.Add(item);
}
}

if (!info.Value.AreDocsFirst)
foreach (var item in info.Value.Samples)
{
Items.Add(item);
}

if (!info.Value.AreDocsFirst)
{
foreach (var item in info.Value.Docs)
{
foreach (var item in info.Value.Docs)
{
Items.Add(item);
}
Items.Add(item);
}
}

Expand Down

0 comments on commit 5b373f6

Please sign in to comment.