Skip to content

Commit

Permalink
加上智能提示功能
Browse files Browse the repository at this point in the history
  • Loading branch information
lindexi committed Aug 30, 2023
1 parent 2db8be6 commit 6aa457b
Show file tree
Hide file tree
Showing 7 changed files with 449 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Microsoft.CodeAnalysis;

using System;
using System.Collections.Generic;
using System.Resources;
using System.Text;
using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties;
using static dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources;

using static Microsoft.CodeAnalysis.WellKnownDiagnosticTags;

namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers.Diagnostics;

static class TesDiagnostics
{
// ReSharper disable InconsistentNaming
public static DiagnosticDescriptor Tes000_UnknownError => new DiagnosticDescriptor
(
nameof(Tes000),
Localize(nameof(Tes000)),
Localize(nameof(Tes000_Message)),
Categories.Compiler,
DiagnosticSeverity.Error,
true,
customTags: new[] { AnalyzerException, NotConfigurable }
);

public static DiagnosticDescriptor Tes001_MethodReturnTypeError => new DiagnosticDescriptor
(
nameof(Tes001),
Localize(nameof(Tes001)),
Localize(nameof(Tes001_Message)),
Categories.Compiler,
DiagnosticSeverity.Error,
true,
customTags: new[] { AnalyzerException, NotConfigurable }
);


private static class Categories
{
/// <summary>
/// 可能产生 bug,则报告此诊断。
/// </summary>
public const string AvoidBugs = "dotnetCampus.AvoidBugs";

/// <summary>
/// 为了提供代码生成能力,则报告此诊断。
/// </summary>
public const string CodeFixOnly = "dotnetCampus.CodeFixOnly";

/// <summary>
/// 因编译要求而必须满足的条件没有满足,则报告此诊断。
/// </summary>
public const string Compiler = "dotnetCampus.Compiler";

/// <summary>
/// 因 Telescope 库内的机制限制,必须满足此要求 Telescope 才可正常工作,则报告此诊断。
/// </summary>
public const string Mechanism = "dotnetCampus.Mechanism";

/// <summary>
/// 为了代码可读性,使之更易于理解、方便调试,则报告此诊断。
/// </summary>
public const string Readable = "dotnetCampus.Readable";

/// <summary>
/// 能写得出来正常编译,但会引发运行时异常,则报告此诊断。
/// </summary>
public const string RuntimeException = "dotnetCampus.RuntimeException";

/// <summary>
/// 编写了无法生效的代码,则报告此诊断。
/// </summary>
public const string Useless = "dotnetCampus.Useless";
}

public static LocalizableString Localize(string key) => new LocalizableResourceString(key, dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources.ResourceManager, typeof(Resources));
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers;
using Microsoft.CodeAnalysis;

namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers;

class ExportMethodReturnTypeCollectionDiagnostic : IExportMethodReturnTypeCollectionResult
{
public ExportMethodReturnTypeCollectionDiagnostic(DiagnosticDescriptor diagnosticDescriptor,
Location? location = null, params object[]? messageArgs)
{
DiagnosticDescriptor = diagnosticDescriptor;
Location = location;
MessageArgs = messageArgs;
}

public Location? Location { get; set; }
public DiagnosticDescriptor DiagnosticDescriptor { get; }
public object[]? MessageArgs { set; get; }

public Diagnostic ToDiagnostic() => Diagnostic.Create(DiagnosticDescriptor, Location, MessageArgs);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
using System.Text;

using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Core;
using dotnetCampus.Telescope.SourceGeneratorAnalyzers.Diagnostics;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;

using static dotnetCampus.Telescope.SourceGeneratorAnalyzers.TelescopeExportTypeToMethodIncrementalGenerator;
using static dotnetCampus.Telescope.SourceGeneratorAnalyzers.Properties.Resources;

namespace dotnetCampus.Telescope.SourceGeneratorAnalyzers;

Expand Down Expand Up @@ -112,7 +113,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
// 尝试判断是 ValueTuple 的情况
// 要求符合以下定义
// static partial IEnumerable<(Type, FooAttribute xx, Func<Base> xxx)> ExportFooEnumerable()
if (namedTypeSymbol.TypeArguments.Length == 1 && namedTypeSymbol.TypeArguments[0] is INamedTypeSymbol tupleType && tupleType.IsTupleType && tupleType.TupleElements.Length>0)
if (namedTypeSymbol.TypeArguments.Length == 1 &&
namedTypeSymbol.TypeArguments[0] is INamedTypeSymbol tupleType && tupleType.IsTupleType &&
tupleType.TupleElements.Length > 0)
{
if (tupleType.TupleElements.Length == 3)
{
Expand All @@ -121,13 +124,20 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
if (TypeSymbolHelper.TypeSymbolToFullName(tupleType.TupleElements[0].Type) != "global::System.Type")
{
// 这就是错误的
return ReturnTypeError(nameof(Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator));
}
// 表示的特性
var expectedClassAttributeType = tupleType.TupleElements[1].Type;
// Func<Base>
var funcTypeSymbol = (INamedTypeSymbol) tupleType.TupleElements[2].Type;
if (!funcTypeSymbol.IsGenericType || TypeSymbolHelper.TypeSymbolToFullName(funcTypeSymbol) != "global::System.Func")
{
// 不是 Func 的
return ReturnTypeError(nameof(Tes001_Message_EnumerableValueTupleWithTypeAttributeCreator));
}
// 准备导出的类型的基类型
var expectedClassBaseType = funcTypeSymbol.TypeArguments[0];
Expand All @@ -139,16 +149,34 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
}
// 其他不认识的,要告诉开发者不能这样写哦
return new ExportMethodReturnTypeCollectionDiagnostic() as IExportMethodReturnTypeCollectionResult;
return new ExportMethodReturnTypeCollectionDiagnostic(TesDiagnostics.Tes000_UnknownError) as IExportMethodReturnTypeCollectionResult;
Location GetLocation()
{
var syntaxNode = exportTypeCollectionResult.GeneratorSyntaxContext.Node;
var location = Location.Create(syntaxNode.SyntaxTree, syntaxNode.Span);
return location;
}
ExportMethodReturnTypeCollectionDiagnostic ReturnTypeError(string messageKey)
{
return new ExportMethodReturnTypeCollectionDiagnostic
(
TesDiagnostics.Tes001_MethodReturnTypeError,
GetLocation(),
TesDiagnostics.Localize(messageKey)
);
}
});

// 这是有定义出错的,需要反馈给到开发者的
var diagnosticIncrementalValuesProvider = exportMethodReturnTypeCollectionResultIncrementalValuesProvider.Select((t, _) => t as ExportMethodReturnTypeCollectionDiagnostic).Where(t => t is not null);
var diagnosticIncrementalValuesProvider = exportMethodReturnTypeCollectionResultIncrementalValuesProvider.Select((t, _) => t as ExportMethodReturnTypeCollectionDiagnostic)
.FilterNull();

//context.RegisterSourceOutput(diagnosticIncrementalValuesProvider , (productionContext, diagnostic) =>
//{
// productionContext.ReportDiagnostic();
//});
context.RegisterSourceOutput(diagnosticIncrementalValuesProvider, (productionContext, diagnostic) =>
{
productionContext.ReportDiagnostic(diagnostic.ToDiagnostic());
});

// 收集到了期望收集的内容,将开始进行整个项目的类型收集

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6aa457b

Please sign in to comment.