Open sandboxFocusImprove this doc

LAMA0050: The weaver of an aspect can't be found

Severity Error
Reported by Metalama.Framework
Message The weaver type '<WeaverType>' required to weave aspect '<AspectType>' is not found in the project. Make sure that the project references the assembly that defines this weaver, and that the weaver type is annotated with [MetalamaPlugIn].

Cause

Weaver-based aspects don't implement their transformations with the BuildAspect method but with a low-level weaver built with the Metalama SDK. The aspect class is bound to its weaver by the RequireAspectWeaverAttribute attribute, which gives the full name of the weaver type. Metalama loads the weavers from the compile-time code of the current project and of its references: a weaver is a class that implements IAspectWeaver and is annotated with [MetalamaPlugIn].

Metalama reports LAMA0050 when the project applies at least one instance of a weaver-based aspect, but no loaded weaver has the full name given by [RequireAspectWeaver]. In the message, <WeaverType> is this full name, and <AspectType> is the name of the aspect. Typical causes are:

  • The weaver is defined in a separate assembly or package that the current project doesn't reference.
  • The weaver class isn't annotated with [MetalamaPlugIn], so Metalama doesn't load it.
  • The name passed to [RequireAspectWeaver] as a string doesn't match the full name of the weaver type, for instance because of a typo, a renamed class, or a different namespace. For a nested type, the name must use the reflection syntax, with + between the containing type and the nested type.

Declaring a weaver-based aspect without its weaver isn't an error in itself: Metalama reports LAMA0050 only when the aspect is applied. The diagnostic isn't attached to any location in the source code.

In the following example, the Virtualize aspect requires the weaver Doc.LAMA0050.Error.VirtualizeWeaver, but the project doesn't define it. Metalama reports the error without a source location.

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0050.Error;
4
5// A low-level aspect, which requires the weaver Doc.LAMA0050.Error.VirtualizeWeaver.
6[RequireAspectWeaver( "Doc.LAMA0050.Error.VirtualizeWeaver" )]
7internal class VirtualizeAttribute : TypeAspect { }
8
1namespace Doc.LAMA0050.Error;
2
3// Error: the weaver required by the [Virtualize] aspect is not defined in the project or in its references.
4[Virtualize]
5internal class Calculator
6{
7    public int Add( int a, int b ) => a + b;
8}
9

Resolution

  • Make sure that the project where the aspect is applied references the project or package that defines the weaver. When the aspect and its weaver are distributed as a package, check that the package contains the weaver assembly.
  • Make sure that the weaver class implements IAspectWeaver, is annotated with [MetalamaPlugIn], and has a public parameterless constructor.
  • When the aspect project can reference the weaver type, pass the type itself to [RequireAspectWeaver] with typeof instead of a string. The compiler then verifies the name for you.

In the following example, the project defines the weaver VirtualizeWeaver, annotated with [MetalamaPlugIn], whose full name matches the name given to [RequireAspectWeaver].

1using Metalama.Framework.Aspects;
2
3namespace Doc.LAMA0050.Fixed;
4
5// A low-level aspect, which requires the weaver Doc.LAMA0050.Fixed.VirtualizeWeaver.
6[RequireAspectWeaver( "Doc.LAMA0050.Fixed.VirtualizeWeaver" )]
7internal class VirtualizeAttribute : TypeAspect { }
8
1using Metalama.Framework.Engine;
2using Metalama.Framework.Engine.AspectWeavers;
3using Microsoft.CodeAnalysis;
4using Microsoft.CodeAnalysis.CSharp;
5using Microsoft.CodeAnalysis.CSharp.Syntax;
6using System.Threading.Tasks;
7
8namespace Doc.LAMA0050.Fixed;
9
10// The weaver is annotated with [MetalamaPlugIn], and its full name matches the name given to [RequireAspectWeaver].
11[MetalamaPlugIn]
12internal class VirtualizeWeaver : IAspectWeaver
13{
14    public Task TransformAsync( AspectWeaverContext context )
15        => context.RewriteAspectTargetsAsync( new Rewriter() );
16
17    private class Rewriter : CSharpSyntaxRewriter
18    {
19        public override SyntaxNode VisitMethodDeclaration( MethodDeclarationSyntax node )
20            => node.AddModifiers( SyntaxFactory.Token( SyntaxKind.VirtualKeyword ).WithTrailingTrivia( SyntaxFactory.ElasticSpace ) );
21    }
22}
23
Source Code
1namespace Doc.LAMA0050.Fixed;
2
3[Virtualize]
4internal class Calculator
5{
6    public int Add( int a, int b ) => a + b;
7}
8
Transformed Code
1namespace Doc.LAMA0050.Fixed;
2
3[Virtualize]
4internal class Calculator
5{
6    public virtual int Add(int a, int b) => a + b;
7}
8

See also