You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter自定义@tupleRequired注解:基于参数类型触发警告需求

Got it, let's build this custom @tupleRequired annotation for Flutter that triggers static warnings based on the tuple type. Here's a step-by-step implementation:

1. Set Up Dependencies and Base Classes

First, we'll use the custom_lint package to create our custom static check. Add these dev dependencies to your pubspec.yaml:

dev_dependencies:
  custom_lint: ^0.5.0
  custom_lint_builder: ^0.5.0
  meta: ^1.9.0 # For the Required base class

Next, confirm your base classes and annotation are defined (you mentioned these already exist, but here's a reference):

import 'package:meta/meta.dart';

// Base tuple classes
abstract class Tuple {}
abstract class NullTuple extends Tuple {}
abstract class ParamTuple extends Tuple {}

// Custom annotation extending @required
class TupleRequired extends Required {
  const TupleRequired();
}
2. Implement the Custom Lint Rule

Create a new file (e.g., tuple_required_lint.dart) in your project to define the lint detector. This rule will scan method invocations, check for @tupleRequired annotations, and validate parameter usage:

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';

class TupleRequiredLint extends DartLintRule {
  TupleRequiredLint() : super(code: _code);

  // Define the lint code with custom messages
  static const _code = LintCode(
    name: 'tuple_parameter_mismatch',
    problemMessage: 'Incorrect tuple parameter usage',
    correctionMessage: 'Adjust parameter based on its tuple type',
  );

  @override
  void run(
    CustomLintResolver resolver,
    ErrorReporter reporter,
    CustomLintContext context,
  ) {
    // Listen for method invocations in the code
    context.registry.addMethodInvocation((node) {
      final methodElement = node.methodName.staticElement as MethodElement?;
      if (methodElement == null) return;

      // Check each parameter of the method
      for (final param in methodElement.parameters) {
        // Verify if the parameter has @tupleRequired annotation
        final hasTupleRequired = param.metadata.any(
          (meta) => meta.element?.name == 'TupleRequired',
        );
        if (!hasTupleRequired) continue;

        // Get the parameter's type and check its tuple parent class
        final paramType = param.type;
        final isNullTuple = paramType.isSubtypeOf(
          resolver.typeProvider.getType('NullTuple'),
        );
        final isParamTuple = paramType.isSubtypeOf(
          resolver.typeProvider.getType('ParamTuple'),
        );

        if (!isNullTuple && !isParamTuple) continue;

        // Check if the parameter was passed in the current invocation
        final passedArg = node.argumentList.arguments.firstWhere(
          (arg) => arg is NamedExpression && arg.name.label.name == param.name,
          orElse: () => null,
        );

        // Trigger warnings based on tuple type
        if (isNullTuple) {
          // Warn if NullTuple subclass parameter is passed
          if (passedArg != null) {
            reporter.reportErrorForNode(
              _code,
              passedArg,
              ['This NullTuple parameter is redundant and will be ignored'],
            );
          }
        } else if (isParamTuple) {
          // Warn if ParamTuple subclass parameter is missing
          if (passedArg == null) {
            reporter.reportErrorForNode(
              _code,
              node.methodName,
              ['This ParamTuple parameter must be provided'],
            );
          }
        }
      }
    });
  }
}
3. Configure Analysis Options

Update your analysis_options.yaml to enable the custom lint plugin and rule:

analyzer:
  plugins:
    - custom_lint

linter:
  rules:
    - custom_lint/tuple_parameter_mismatch
4. Test the Implementation

Use your example classes to verify the warnings work as expected:

// Define concrete tuple subclasses
class Tuple0 extends NullTuple {}
class Tuple1 extends ParamTuple {}

class Example {
  void nullParam({@tupleRequired Tuple0 param}) {}
  void withParam({@tupleRequired Tuple1 param}) {}
}

void main() {
  final example = Example();
  
  // This will trigger a warning: "This NullTuple parameter is redundant and will be ignored"
  example.nullParam(param: Tuple0());
  
  // This will trigger a warning: "This ParamTuple parameter must be provided"
  example.withParam();
  
  // No warnings here (correct usage)
  example.nullParam();
  example.withParam(param: Tuple1());
}

Once everything is set up, your IDE (like Android Studio or VS Code) will show the static warnings in real-time, just like the built-in @required annotation.

内容的提问来源于stack exchange,提问作者mohammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:27:43