Thanks to visit codestin.com
Credit goes to github.com

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
10 changes: 6 additions & 4 deletions src/MessagePack.Analyzers/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ Rule ID | Category | Severity | Notes
--------|----------|----------|-------
MsgPack001 | Reliability | Disabled | MsgPack001SpecifyOptionsAnalyzer
MsgPack002 | Reliability | Disabled | MsgPack002UseConstantOptionsAnalyzer
MsgPack003 | Usage | Error | MessagePackAnalyzer
MsgPack004 | Usage | Error | MessagePackAnalyzer
MsgPack005 | Usage | Error | MessagePackAnalyzer
MsgPack006 | Usage | Error | MessagePackAnalyzer
MsgPack003 | Usage | Error | MsgPack00xMessagePackAnalyzer
MsgPack004 | Usage | Error | MsgPack00xMessagePackAnalyzer
MsgPack005 | Usage | Error | MsgPack00xMessagePackAnalyzer
MsgPack006 | Usage | Error | MsgPack00xMessagePackAnalyzer
MsgPack007 | Usage | Error | MsgPack00xMessagePackAnalyzer
MsgPack008 | Usage | Error | MsgPack00xMessagePackAnalyzer
5 changes: 5 additions & 0 deletions src/MessagePack.Analyzers/CodeAnalysis/AnalyzerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public record AnalyzerOptions(

public string FormatterNamespace => "Formatters";

/// <summary>
/// Gets a value indicating whether the analyzer is generating source code.
/// </summary>
public bool IsGeneratingSource { get; init; }

public static AnalyzerOptions Parse(AnalyzerConfigOptions options, ImmutableArray<AdditionalText> additionalTexts)
{
if (!options.TryGetValue(RootNamespace, out string? projectRootNamespace))
Expand Down
59 changes: 39 additions & 20 deletions src/MessagePack.Analyzers/CodeAnalysis/TypeCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Operations;

namespace MessagePack.Analyzers.CodeAnalysis;

Expand Down Expand Up @@ -378,18 +379,25 @@ private bool CollectEnum(INamedTypeSymbol type, ISymbol enumUnderlyingType)

private bool CollectUnion(INamedTypeSymbol type)
{
if (!options.IsGeneratingSource)
{
// In analyzer-only mode, this method doesn't work.
return true;
}

ImmutableArray<TypedConstant>[] unionAttrs = type.GetAttributes().Where(x => x.AttributeClass.ApproximatelyEqual(this.typeReferences.UnionAttribute)).Select(x => x.ConstructorArguments).ToArray();
if (unionAttrs.Length == 0)
{
throw new MessagePackGeneratorResolveFailedException("Serialization Type must mark UnionAttribute." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.UnionAttributeRequired, type.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}

// 0, Int 1, SubType
UnionSubTypeInfo UnionSubTypeInfoSelector(ImmutableArray<TypedConstant> x)
UnionSubTypeInfo? UnionSubTypeInfoSelector(ImmutableArray<TypedConstant> x)
{
if (!(x[0] is { Value: int key }) || !(x[1] is { Value: ITypeSymbol typeSymbol }))
{
throw new NotSupportedException("AOT code generation only supports UnionAttribute that uses a Type parameter, but the " + type.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat) + " type uses an unsupported parameter.");
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.AotUnionAttributeRequiresTypeArg, GetIdentifierLocation(type)));
return null;
}

var typeName = typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
Expand All @@ -400,7 +408,7 @@ UnionSubTypeInfo UnionSubTypeInfoSelector(ImmutableArray<TypedConstant> x)
type.ContainingNamespace.IsGlobalNamespace ? null : type.ContainingNamespace.ToDisplayString(),
type.Name,
type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
unionAttrs.Select(UnionSubTypeInfoSelector).OrderBy(x => x.Key).ToArray());
unionAttrs.Select(UnionSubTypeInfoSelector).Where(i => i is not null).OrderBy(x => x!.Key).ToArray()!);

this.collectedUnionInfo.Add(info);
return true;
Expand Down Expand Up @@ -439,7 +447,7 @@ private bool CollectArray(IArrayTypeSymbol array)

var fullName = array.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
var elementTypeDisplayName = elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
string formatterName;
string? formatterName;
if (array.IsSZArray)
{
formatterName = "MsgPack::Formatters.ArrayFormatter<" + elementTypeDisplayName + ">";
Expand All @@ -451,8 +459,13 @@ private bool CollectArray(IArrayTypeSymbol array)
2 => "MsgPack::Formatters.TwoDimensionalArrayFormatter<" + elementTypeDisplayName + ">",
3 => "MsgPack::Formatters.ThreeDimensionalArrayFormatter<" + elementTypeDisplayName + ">",
4 => "MsgPack::Formatters.FourDimensionalArrayFormatter<" + elementTypeDisplayName + ">",
_ => throw new InvalidOperationException("does not supports array dimension, " + fullName),
_ => null,
};
if (formatterName is null)
{
////this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.AotArrayRankTooHigh));
return false;
}
}

var info = new GenericSerializationInfo(fullName, formatterName, elemType is ITypeParameterSymbol);
Expand Down Expand Up @@ -782,15 +795,15 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if ((isIntKey && intKey == null) || (!isIntKey && stringKey == null))
{
throw new MessagePackGeneratorResolveFailedException("all members key type must be same." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DoNotMixStringAndIntKeys, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}
}

if (isIntKey)
{
if (intMembers.ContainsKey(intKey!.Value))
{
throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.KeysMustBeUnique, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}

var member = new MemberSerializationInfo(true, isWritable, isReadable, intKey!.Value, item.Name, item.Name, item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), item.Type.ToDisplayString(BinaryWriteFormat), customFormatterAttr?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
Expand All @@ -800,7 +813,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if (stringMembers.ContainsKey(stringKey!))
{
throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.KeysMustBeUnique, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}

var member = new MemberSerializationInfo(true, isWritable, isReadable, hiddenIntKey++, stringKey!, item.Name, item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), item.Type.ToDisplayString(BinaryWriteFormat), customFormatterAttr?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
Expand Down Expand Up @@ -855,7 +868,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
var stringKey = key is { Value: string stringKeyValue } ? stringKeyValue : default;
if (intKey == null && stringKey == null)
{
throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.BothStringAndIntKeyAreNull, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}

if (searchFirst)
Expand All @@ -867,15 +880,15 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if ((isIntKey && intKey == null) || (!isIntKey && stringKey == null))
{
throw new MessagePackGeneratorResolveFailedException("all members key type must be same." + " type: " + type.Name + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DoNotMixStringAndIntKeys, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}
}

if (isIntKey)
{
if (intMembers.ContainsKey(intKey!.Value))
{
throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.KeysMustBeUnique, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}

var member = new MemberSerializationInfo(true, isWritable, isReadable, intKey!.Value, item.Name, item.Name, item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), item.Type.ToDisplayString(BinaryWriteFormat), customFormatterAttr?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
Expand All @@ -885,7 +898,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if (stringMembers.ContainsKey(stringKey!))
{
throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.KeysMustBeUnique, item.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation()));
}

var member = new MemberSerializationInfo(true, isWritable, isReadable, hiddenIntKey++, stringKey!, item.Name, item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), item.Type.ToDisplayString(BinaryWriteFormat), customFormatterAttr?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
Expand Down Expand Up @@ -913,7 +926,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
// struct allows null ctor
if (ctor == null && isClass)
{
throw new MessagePackGeneratorResolveFailedException("can't find public constructor. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.NoDeserializingConstructor, GetIdentifierLocation(type)));
}

var constructorParameters = new List<MemberSerializationInfo>();
Expand Down Expand Up @@ -944,7 +957,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
}
else
{
throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterIndex:" + ctorParamIndex + " parameterType:" + item.Type.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DeserializingConstructorParameterTypeMismatch, GetLocation(item)));
}
}
}
Expand All @@ -957,7 +970,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
}
else
{
throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterIndex:" + ctorParamIndex);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DeserializingConstructorParameterIndexMissing, GetParameterListLocation(ctor)));
}
}
}
Expand All @@ -971,7 +984,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if (ctorEnumerator == null)
{
throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterName:" + item.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DeserializingConstructorParameterNameMissing, GetParameterListLocation(ctor)));
}

ctor = null;
Expand All @@ -985,7 +998,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if (ctorEnumerator == null)
{
throw new MessagePackGeneratorResolveFailedException("duplicate matched constructor parameter name:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterName:" + item.Name + " parameterType:" + item.Type.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DeserializingConstructorParameterNameDuplicate, GetLocation(item)));
}

ctor = null;
Expand All @@ -1001,7 +1014,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr
{
if (ctorEnumerator == null)
{
throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterName:" + item.Name + " parameterType:" + item.Type.Name);
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.DeserializingConstructorParameterTypeMismatch, GetLocation(item)));
}

ctor = null;
Expand All @@ -1016,7 +1029,7 @@ private bool CheckValidMessagePackFormatterAttribute(AttributeData formatterAttr

if (ctor == null)
{
throw new MessagePackGeneratorResolveFailedException("can't find matched constructor. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
this.reportDiagnostic?.Invoke(Diagnostic.Create(MsgPack00xMessagePackAnalyzer.NoDeserializingConstructor, GetIdentifierLocation(type)));
}
}

Expand Down Expand Up @@ -1078,6 +1091,12 @@ private static GenericTypeParameterInfo ToGenericTypeParameterInfo(ITypeParamete
return new GenericTypeParameterInfo(typeParameter.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), string.Join(", ", constraints));
}

private static Location? GetIdentifierLocation(INamedTypeSymbol type) => ((BaseTypeDeclarationSyntax?)type.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax())?.Identifier.GetLocation();

private static Location? GetLocation(IParameterSymbol parameter) => parameter.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation();

private static Location? GetParameterListLocation(IMethodSymbol? method) => ((BaseMethodDeclarationSyntax?)method?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax())?.ParameterList.GetLocation();

private static string GetGenericFormatterClassName(INamedTypeSymbol type)
{
return type.Name;
Expand Down
Loading