Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Cecil diagnostics with Roslyn Analyzer #24

Merged
merged 2 commits into from
Apr 9, 2023
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
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/

*.*~
.vs
.vscode
.idea
.gradle
*.DotSettings.user
9 changes: 4 additions & 5 deletions CodeGen/AtomILPostProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,12 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
var sw = Stopwatch.StartNew();

var assemblyDefinition = AssemblyDefinitionFor(compiledAssembly);
var diagnostics = new List<DiagnosticMessage>();

diagnostics.AddRange(new AtomWeaverV2().Weave(assemblyDefinition, out var madeAnyChange));
var madeAnyChange = new AtomWeaverV2().Weave(assemblyDefinition);

if (!madeAnyChange || diagnostics.Any(d => d.DiagnosticType == DiagnosticType.Error))
if (!madeAnyChange)
{
return new ILPostProcessResult(null, diagnostics);
return new ILPostProcessResult(null);
}

var pe = new MemoryStream();
Expand All @@ -60,7 +59,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
UnityEngine.Debug.Log($"Weaved {compiledAssembly.Name} in {sw.ElapsedMilliseconds}ms");
#endif

return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), diagnostics);
return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()));
}

private static AssemblyDefinition AssemblyDefinitionFor(ICompiledAssembly compiledAssembly)
Expand Down
64 changes: 34 additions & 30 deletions CodeGen/AtomWeaverV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using UniMob.Core;
using Unity.CompilationPipeline.Common.Diagnostics;

namespace UniMob.Editor.Weaver
{
Expand All @@ -21,8 +19,6 @@ internal class AtomWeaverV2
private const string ThrowIfDisposedMethodName = nameof(LifetimeScopeExtension.ThrowIfDisposed);
private const string KeepAliveParameterName = nameof(AtomAttribute.KeepAlive);

private List<DiagnosticMessage> _diagnosticMessages = new List<DiagnosticMessage>();

private ModuleDefinition _module;

private TypeReference _atomType;
Expand All @@ -38,22 +34,34 @@ internal class AtomWeaverV2

private bool _generateDebugNames;

public List<DiagnosticMessage> Weave(AssemblyDefinition assembly, out bool didAnyChange)
public bool Weave(AssemblyDefinition assembly)
{
Prepare(assembly);

var allProperties = _module
.GetAllTypes()
.SelectMany(type => type.Properties);
_module = assembly.MainModule;
_lifetimeScopeInterfaceType = _module.ImportReference(typeof(ILifetimeScope));

didAnyChange = false;
var didAnyChange = false;
var prepared = false;

foreach (var property in allProperties)
foreach (var type in _module.GetAllTypes())
{
didAnyChange |= Weave(property);
if (!ShouldWeaveType(type))
{
continue;
}

if (!prepared)
{
prepared = true;
Prepare(assembly);
}

foreach (var property in type.Properties)
{
didAnyChange |= Weave(property);
}
}

return _diagnosticMessages;
return didAnyChange;
}

private void Prepare(AssemblyDefinition assembly)
Expand All @@ -62,11 +70,8 @@ private void Prepare(AssemblyDefinition assembly)
#if UNIMOB_ATOM_GENERATE_DEBUG_NAMES
_generateDebugNames = true;
#endif

_module = assembly.MainModule;


_atomType = _module.ImportReference(typeof(ComputedAtom<>));
_lifetimeScopeInterfaceType = _module.ImportReference(typeof(ILifetimeScope));

var atomTypeDef = _atomType.Resolve();
var atomPullDef = _module.ImportReference(typeof(Func<>)).Resolve();
Expand All @@ -85,47 +90,46 @@ private void Prepare(AssemblyDefinition assembly)
_module.ImportReference(lifetimeScopeExtensionsDef.FindMethod(ThrowIfDisposedMethodName, 1));
}

public bool Weave(PropertyDefinition property)
private bool ShouldWeaveType(TypeDefinition type)
{
var atomAttribute = Helpers.GetCustomAttribute<AtomAttribute>(property);
if (atomAttribute == null)
if (!type.IsClass)
{
return false;
}

if (property.DeclaringType.HasGenericParameters)
if (type.HasGenericParameters)
{
_diagnosticMessages.Add(UserError.AtomAttributeCannotBeUsedOnGenericClasses(property));
return false;
}

if (!property.DeclaringType.IsClass || property.DeclaringType.IsValueType)
if (!type.IsInterfaceImplemented(_lifetimeScopeInterfaceType))
{
_diagnosticMessages.Add(UserError.AtomAttributeCanBeUsedOnlyOnClassMembers(property));
return false;
}

if (!property.DeclaringType.IsInterfaceImplemented(_lifetimeScopeInterfaceType))
return true;
}

public bool Weave(PropertyDefinition property)
{
var atomAttribute = Helpers.GetCustomAttribute<AtomAttribute>(property);
if (atomAttribute == null)
{
_diagnosticMessages.Add(UserError.AtomAttributeCanBeUsedOnlyOnLifetimeScope(property));
return false;
}

if (property.GetMethod == null)
{
_diagnosticMessages.Add(UserError.CannotUseAtomAttributeOnSetOnlyProperty(property));
return false;
}

if (property.GetMethod.IsStatic)
{
_diagnosticMessages.Add(UserError.CannotUseAtomAttributeOnStaticProperty(property));
return false;
}

if (property.GetMethod.IsAbstract)
{
_diagnosticMessages.Add(UserError.CannotUseAtomAttributeOnAbstractProperty(property));
return false;
}

Expand Down
71 changes: 0 additions & 71 deletions CodeGen/UserError.cs

This file was deleted.

3 changes: 0 additions & 3 deletions CodeGen/UserError.cs.meta

This file was deleted.

Binary file added Runtime/UniMob.Analyzers.dll
Binary file not shown.
88 changes: 88 additions & 0 deletions Runtime/UniMob.Analyzers.dll.meta

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

Loading