pamidur / aspect-injector

AOP framework for .NET (c#, vb, etc)
Apache License 2.0
765 stars 114 forks source link

An error occurs at compile time when the value of the optional argument is empty. #114

Closed LaborJos closed 5 years ago

LaborJos commented 5 years ago

Example

public class SomeType
{
    /// <summary>
    /// When all the arguments are filled in.
    /// </summary>
    [SomeAspect("Good", "Good")]
    public int Good { get; set; }

    /// <summary>
    /// When the value of an optional argument is empty.
    /// </summary>
    [SomeAspect("NotGood")]
    public int NotGood { get; set; }
}

[Aspect(Scope.Global)]
public class SomeAspect
{
    [Advice(Kind.Around, Targets = Target.Public | Target.Setter)]
    public object AroundSetter([Argument(Source.Instance)] object instance, [Argument(Source.Name)] string propertyName, [Argument(Source.Triggers)] Attribute[] attributes)
    {
        return default;
    }
}

//Not good(Optional Arguments)
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
[Injection(typeof(SomeAspect))]
public class SomeAspectAttribute : Attribute
{
    public SomeAspectAttribute(string parameter1, string parameter2 = default)
    {
    }
}

Build Log

1>AspectInjector|2.2.4:22c922c4ea1caad47231f500154ecdf36db8f739: Found 1 aspects, 2 injections
1>AspectInjector|2.2.4:22c922c4ea1caad47231f500154ecdf36db8f739: error AI_ERR0: Processing failure: System.NullReferenceException: Object reference not set to an instance of an object.
1>   at System.Object.GetType()
1>   at FluentIL.Values.AttributeArgument(Cut pc, CustomAttributeArgument argument)
1>   at FluentIL.Values.Value(Cut pc, Object value)
1>   at AspectInjector.Core.Advice.Weavers.Processes.AdviceWeaveProcessBase`1.<>c__DisplayClass14_0.<LoadInjectionsArgument>b__2(Cut ilc)
1>   at FluentIL.Cut.Here(PointCut pc)
1>   at FluentIL.Statements.Call(Cut cut, MethodReference method, PointCut args)
1>   at AspectInjector.Core.Advice.Weavers.Processes.AdviceWeaveProcessBase`1.<>c__DisplayClass14_0.<LoadInjectionsArgument>b__1(Cut il)
1>   at FluentIL.Cut.Here(PointCut pc)
1>   at FluentIL.Arrays.SetByIndex(Cut pc, TypeReference elementType, Int32 index, PointCut value)
1>   at FluentIL.Arrays.CreateArray(Cut pc, TypeReference elementType, PointCut[] elements)
1>   at AspectInjector.Core.Advice.Weavers.Processes.AdviceWeaveProcessBase`1.LoadInjectionsArgument(Cut pc, AdviceArgument parameter)
1>   at AspectInjector.Core.Advice.Weavers.Processes.AdviceWeaveProcessBase`1.LoadAdviceArgs(Cut cut)
1>   at FluentIL.Cut.Here(PointCut pc)
1>   at FluentIL.Statements.Call(Cut cut, MethodReference method, PointCut args)
1>   at AspectInjector.Core.Advice.Weavers.Processes.AdviceAroundProcess.<Execute>b__5_0(Cut e)
1>   at FluentIL.Cut.Here(PointCut pc)
1>   at FluentIL.MethodEditor.Instead(MethodBody body, PointCut action)
1>   at AspectInjector.Core.Advice.Weavers.AdviceInlineWeaver.Weave(InjectionDefinition injection)
1>   at AspectInjector.Core.Processor.PatchAssembly(AssemblyDefinition assembly, Boolean optimize, Boolean verbose)
1>   at FluentIL.PatcherBase.Process(String assemblyFile, IAssemblyResolver resolver, Boolean optimize, Boolean verbose)
1>   at AspectInjector.Compiler.Execute(String filename, IReadOnlyList`1 references, Boolean optimize, Boolean verbose). Please submit an issue to https://github.com/pamidur/aspect-injector
1>AspectInjector : error AI_FAIL: Aspect Injector processing has failed. See other errors.
LaborJos commented 5 years ago

FluentIL/Cuts/Values.cs

private static Cut AttributeArgument(Cut pc, CustomAttributeArgument argument)
{
    var val = argument.Value;

    if (val?.GetType().IsArray ?? false)
        pc = pc.CreateArray(
            argument.Type.GetElementType(),
            ((Array)val).Cast<object>().Select<object, PointCut>(v => il => il.Value(v)).ToArray()
            );
    else
    {
        pc = pc.Value(val);

        if (val is CustomAttributeArgument next)
            pc = pc.Cast(next.Type, argument.Type);
    }

    return pc;
}

A null check on the if statement will solve the problem.

pamidur commented 5 years ago

Thank you for the report. I'll take a look asap

pamidur commented 5 years ago

should be fixed in 2.2.5