Open sandboxFocusImprove this doc

LAMA0272: A void template contains a redundant return statement

Severity Error
Reported by Metalama.Framework
Message Redundant 'return' statements are not allowed in templates. Remove this 'return' statement.

Cause

Metalama doesn't distinguish auxiliary templates from other templates: a return statement in a template always becomes a return statement in the generated code. When a template calls a void auxiliary template, a return; in the auxiliary template doesn't return to the calling template. It returns from the target method and skips the code that follows the call, for instance the call to meta.Proceed().

To prevent this mistake, Metalama reports LAMA0272 on the return; statements of a void method marked with [Template] when every execution path of the method ends with such a statement, so that they're redundant in the template. Typical cases are:

  • a return; as the last statement of the template;
  • a return; at the end of both branches of an if...else statement, of all sections of a switch statement that has a default section, or of a try block and all its catch blocks.

Metalama doesn't report LAMA0272 when the end of the template is still reachable, for instance for a return; in an if statement without else. Such a statement intentionally returns from the target method.

In the following example, the Log auxiliary template ends with a return; statement.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0272.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        this.Log();
11
12        return meta.Proceed();
13    }
14
15    [Template]
16    private void Log()
17    {
18        Console.WriteLine( $"Executing {meta.Target.Method}." );
19
20        // Error: this return statement is redundant.
        Error LAMA0272: Redundant 'return' statements are not allowed in templates. Remove this 'return' statement.

21        return;
22    }
23}
24
1namespace Doc.LAMA0272.Error;
2
3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8

Resolution

Remove the redundant return; statements, as in the following example. If the generated code must return from the target method, make the auxiliary template return under a condition, or generate the return statement with meta.Return(...).

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0272.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8    public override dynamic? OverrideMethod()
9    {
10        this.Log();
11
12        return meta.Proceed();
13    }
14
15    [Template]
16    private void Log()
17    {
18        Console.WriteLine( $"Executing {meta.Target.Method}." );
19
20        // Fixed: the redundant return statement is removed.
21    }
22}
23
Source Code
1namespace Doc.LAMA0272.Fixed;
2


3internal class Calculator
4{
5    [Log]
6    public int Add( int a, int b ) => a + b;
7}
8
Transformed Code
1using System;
2
3namespace Doc.LAMA0272.Fixed;
4
5internal class Calculator
6{
7    [Log]
8    public int Add(int a, int b)
9    {
10        Console.WriteLine("Executing Calculator.Add(int, int).");
11        return a + b;
12    }
13}
14

See also