Skip to content

Commit

Permalink
Add a Roslyn analyzer to detect parameter/attribute issues (#9031)
Browse files Browse the repository at this point in the history
Co-authored-by: Artyom M <artem.melnikov@live.com>
  • Loading branch information
peterthorpe81 and ScarletKuro committed Jun 20, 2024
1 parent 7e92520 commit b1fa28c
Show file tree
Hide file tree
Showing 48 changed files with 2,277 additions and 21 deletions.
7 changes: 7 additions & 0 deletions src/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<ItemGroup>
<CompilerVisibleProperty Include="MudDebugAnalyzer" />
<CompilerVisibleProperty Include="MudAllowedAttributePattern" />
<CompilerVisibleProperty Include="MudIllegalParameters" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@*to add extra diagnostics which get filtered on the tests*@
<MudChip T="string" Text="Href set" AvatarClass="y" />
@*illegal parameter different case *@
<MudChip T="string" Text="Href set" avatarclass></MudChip>
13 changes: 13 additions & 0 deletions src/MudBlazor.Analyzers.TestComponents/InheritedMudChip.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@typeparam T
@attribute [CascadingTypeParameter(nameof(T))]
@inherits MudChip<T>

@{
base.BuildRenderTree(__builder);
}

@code
{
[Parameter]
public string? AvatarClass { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>MudBlazor.Analyzers.TestComponents</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\MudBlazor\MudBlazor.csproj" />
</ItemGroup>

<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>

<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
</Project>
55 changes: 55 additions & 0 deletions src/MudBlazor.Analyzers.TestComponents/ParametersTest.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@*illegal parameter OffserX with value *@
<MudAutocomplete T="string" OffsetX="5" />
@*illegal parameter icon different case *@
<MudFab icon="dd"></MudFab>
@*illegal parameter Text no value *@
<MudSlider T="int" Text/>

@*inheritence with AvatarClass implemented *@
<InheritedMudChip T="string" Text="Href set" Avatar="" AvatarClass="@bindx" />

@*sub component invalid Parameter Image*@
<MudContainer>
<MudAvatar Image="y" />
</MudContainer>

@*in code section parameter Minimum*@
@{
<MudProgressLinear Minimum="0" />
}

@*in loop section parameter Dense *@
@for (int i = 0; i < 5; i++)
{
<MudToggleGroup T="string" Dense="true" />
}

@*bind-ErrorText will create ErrorTextChanged event which is invalid*@
<MudCheckBox Value="@bindx" @bind-ErrorText=@bindx />

@*bind-Value will mean a TypeInference class in source generator*@
<MudChip @bind-Value="@bindx" Text="Href set" @bind-Value:after="Test" AvatarClass="@bindx" />

@*bind- case2*@
<MudChip T="string" @bind="@bindx" Text="Href set" @bind:after="Test" />

@*valid bind*@
<MudTextField @bind-Value="@bindx" @bind-Value:after="Test" Label="Standard" Variant="Variant.Text"></MudTextField>

@*attribute casing*@
<MudProgressCircular lowerCase UpperCase />

@*attribute dataandaria*@
<MudRadio T="string" data-animation="a" aria-disabled="false" />

@code
{
public static string __description__ = "Invalid parameter Avatar on MudChip";

public string bindx = "y";

internal Task Test()
{
return Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"profiles": {
"MudBlazor.Analyzers.TestComponents": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:61192;http://localhost:61193"
}
}
}
21 changes: 21 additions & 0 deletions src/MudBlazor.Analyzers.TestComponents/Util.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) MudBlazor 2021
// MudBlazor licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;

namespace MudBlazor.Analyzers.TestComponents
{
public static class Util
{
private static string ThisDirectory([CallerFilePath] string callerFilePath = "")
{
return System.IO.Path.GetDirectoryName(callerFilePath)!;
}

public static string ProjectPath([CallerFilePath] string? callerFilePath = null)
{
return System.IO.Path.Combine(ThisDirectory(), "MudBlazor.Analyzers.TestComponents.csproj");
}
}
}
7 changes: 7 additions & 0 deletions src/MudBlazor.Analyzers.TestComponents/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.JSInterop
@using MudBlazor.Analyzers.TestComponents
@using MudBlazor
14 changes: 14 additions & 0 deletions src/MudBlazor.Analyzers/AllowedAttributePattern.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) MudBlazor 2021
// MudBlazor licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace MudBlazor.Analyzers
{
public enum AllowedAttributePattern
{
Any,
LowerCase,
DataAndAria,
None
}
}
102 changes: 102 additions & 0 deletions src/MudBlazor.Analyzers/IllegalParameterSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) MudBlazor 2021
// MudBlazor licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace MudBlazor.Analyzers
{
internal class IllegalParameterSet
{
internal Dictionary<INamedTypeSymbol, string[]> Parameters { get; set; }

internal StringComparer Comparer { get; set; }
internal IllegalParameters IllegalParameters { get; set; }

private Compilation _compilation;

internal IllegalParameterSet(Compilation compilation, IllegalParameters illegalParameters)
{
_compilation = compilation;
Parameters = [];
IllegalParameters = illegalParameters;
Comparer = illegalParameters == IllegalParameters.V7IgnoreCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture;

if (illegalParameters != IllegalParameters.Disabled)
{
AddIllegalParameterSet("MudBlazor.MudBadge", "Bottom", "Left", "Start");

AddIllegalParameterSet("MudBlazor.MudProgressCircular", "Minimum", "Maximum");
AddIllegalParameterSet("MudBlazor.MudProgressLinear", "Minimum", "Maximum");

AddIllegalParameterSet("MudBlazor.MudRadio`1", "Option");
AddIllegalParameterSet("MudBlazor.MudFab", "Icon");

AddIllegalParameterSet("MudBlazor.MudCheckBox`1", "Checked");
AddIllegalParameterSet("MudBlazor.MudSwitch`1", "Checked");

AddIllegalParameterSet("MudBlazor.MudPopover`1", "Direction", "OffsetX", "OffsetY", "SelectOnClick");
AddIllegalParameterSet("MudBlazor.MudAutocomplete`1", "Direction", "OffsetX", "OffsetY", "SelectOnClick");
AddIllegalParameterSet("MudBlazor.MudSelect`1", "Direction", "OffsetX", "OffsetY", "SelectOnClick");

AddIllegalParameterSet("MudBlazor.MudToggleGroup`1", "Outline", "Dense");

AddIllegalParameterSet("MudBlazor.MudAvatar", "Image", "Alt");

AddIllegalParameterSet("MudBlazor.MudSlider`1", "Text");

AddIllegalParameterSet("MudBlazor.MudRadioGroup`1", "SelectedOption", "SelectedOptionChanged");

AddIllegalParameterSet("MudBlazor.MudSwipeArea", "OnSwipe");

AddIllegalParameterSet("MudBlazor.MudChip`1", "Avatar", "AvatarClass");

AddIllegalParameterSet("MudBlazor.MudChipSet`1", "Filter", "MultiSelection", "Multiselection", "Mandatory",
"SelectedChip", "SelectedChipChanged", "SelectedChips", "SelectedChipsChanged");

AddIllegalParameterSet("MudBlazor.MudList`1", "SelectedItem", "SelectedItemChanged", "Clickable", "Avatar",
"AvatarClass", "AdornmentColor", "OnClickHandlerPreventDefault");

AddIllegalParameterSet("MudBlazor.MudListItem`1", "SelectedItem", "SelectedItemChanged", "Clickable", "Avatar",
"AvatarClass", "AdornmentColor", "OnClickHandlerPreventDefault");

AddIllegalParameterSet("MudBlazor.MudTreeView`1", "CanActivate", "CanHover", "CanSelect", "ActivatedValue",
"ActivatedValueChanged", "Multiselection", "MultiSelection", "Activated", "ExpandedIcon", "SelectedItem");

AddIllegalParameterSet("MudBlazor.MudTreeViewItem`1", "CanActivate", "CanHover", "CanSelect", "ActivatedValue",
"ActivatedValueChanged", "Multiselection", "MultiSelection", "Activated", "ExpandedIcon", "SelectedItem");

AddIllegalParameterSet("MudBlazor.MudMenu", "Link", "Target", "HtmlTag", "ButtonType");
AddIllegalParameterSet("MudBlazor.MudMenuItem", "Link", "Target", "HtmlTag", "ButtonType");

AddIllegalParameterSet("MudBlazor.MudFileUpload`1", "ButtonTemplate");

AddIllegalParameterSet("MudBlazor.MudButtonGroup", "VerticalAlign");

AddIllegalParameterSet("MudBlazor.MudTable`1", "QuickColumns");

AddIllegalParameterSet("MudBlazor.MudComponentBase", "UnCheckedColor", "Command", "CommandParameter", "IsEnabled",
"ClassAction", "InputIcon", "InputVariant", "AllowKeyboardInput", "ClassActions", "DisableRipple", "DisableGutters",
"DisablePadding", "DisableElevation", "DisableUnderLine", "DisableRowsPerPage", "Link", "Delayed", "AlertTextPosition",
"ShowDelimiters", "DelimitersColor", "DrawerWidth", "DrawerHeightTop", "DrawerHeightBottom", "AppbarMinHeight",
"ClassBackground", "Cancelled", "ClassContent", "IsExpanded", "IsExpandedChanged", "IsInitiallyExpanded", "InitiallyExpanded",
"RightAlignSmall", "IsExpandable", "ToolBarClass", "DisableToolbar", "DisableLegend", "DisableSliders", "DisablePreview",
"DisableModeSwitch", "DisableInputs", "DisableDragEffect", "DisableColorField", "DisableAlpha", "DisableSidePadding",
"DisableOverlay", "DisableSliderAnimation", "DisableModifiers", "IsChecked", "IsCheckable", "IsCheckedChanged",
"IsVisible", "IsVisibleChanged", "IsOpen", "IsOpened", "IsOpenChanged", "IsActive", "ItemIsDisabled", "IsSelected",
"IsSelectedChanged", "IsEditable", "IsEditing", "IsEditSwitchBlocked", "IsHidden", "IsHiddenChanged");
}
}

private void AddIllegalParameterSet(string typeName, params string[] parameterSet)
{
var symbol = _compilation.GetBestTypeByMetadataName(typeName);

if (symbol is not null)
{
if (!Parameters.ContainsKey(symbol))
Parameters.Add(symbol, parameterSet);
}
}
}


}
13 changes: 13 additions & 0 deletions src/MudBlazor.Analyzers/IllegalParameters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) MudBlazor 2021
// MudBlazor licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace MudBlazor.Analyzers
{
public enum IllegalParameters
{
Disabled,
V7CaseSensitive,
V7IgnoreCase
}
}
Loading

0 comments on commit b1fa28c

Please sign in to comment.