List _validateAst()

in packages/pigeon/lib/pigeon_lib.dart [439:530]


List<Error> _validateAst(Root root, String source) {
  final List<Error> result = <Error>[];
  final List<String> customClasses =
      root.classes.map((Class x) => x.name).toList();
  final Iterable<String> customEnums = root.enums.map((Enum x) => x.name);
  for (final Class klass in root.classes) {
    for (final NamedType field in klass.fields) {
      if (field.type.typeArguments != null) {
        for (final TypeDeclaration typeArgument in field.type.typeArguments) {
          if (!typeArgument.isNullable) {
            result.add(Error(
              message:
                  'Generic type arguments must be nullable in field "${field.name}" in class "${klass.name}".',
              lineNumber: _calculateLineNumberNullable(source, field.offset),
            ));
          }
          if (customEnums.contains(typeArgument.baseName)) {
            result.add(Error(
              message:
                  'Enum types aren\'t supported in type arguments in "${field.name}" in class "${klass.name}".',
              lineNumber: _calculateLineNumberNullable(source, field.offset),
            ));
          }
        }
      }
      if (!(validTypes.contains(field.type.baseName) ||
          customClasses.contains(field.type.baseName) ||
          customEnums.contains(field.type.baseName))) {
        result.add(Error(
          message:
              'Unsupported datatype:"${field.type.baseName}" in class "${klass.name}".',
          lineNumber: _calculateLineNumberNullable(source, field.offset),
        ));
      }
    }
  }
  for (final Api api in root.apis) {
    for (final Method method in api.methods) {
      if (method.returnType.isNullable) {
        result.add(Error(
          message:
              'Nullable return types types aren\'t supported for Pigeon methods: "${method.returnType.baseName}" in API: "${api.name}" method: "${method.name}"',
          lineNumber: _calculateLineNumberNullable(source, method.offset),
        ));
      }
      if (method.arguments.isNotEmpty &&
          method.arguments.any((NamedType element) =>
              customEnums.contains(element.type.baseName))) {
        result.add(Error(
          message:
              'Enums aren\'t yet supported for primitive arguments: "${method.arguments[0]}" in API: "${api.name}" method: "${method.name}" (https://github.com/flutter/flutter/issues/87307)',
          lineNumber: _calculateLineNumberNullable(source, method.offset),
        ));
      }
      if (customEnums.contains(method.returnType.baseName)) {
        result.add(Error(
          message:
              'Enums aren\'t yet supported for primitive return types: "${method.returnType}" in API: "${api.name}" method: "${method.name}" (https://github.com/flutter/flutter/issues/87307)',
        ));
      }
      if (method.arguments.isNotEmpty &&
          method.arguments
              .any((NamedType element) => element.type.isNullable)) {
        result.add(Error(
          message:
              'Nullable argument types aren\'t supported for Pigeon in API: "${api.name}" method: "${method.name}"',
          lineNumber: _calculateLineNumberNullable(source, method.offset),
        ));
      }
      for (final NamedType unnamedType in method.arguments
          .where((NamedType element) => element.type.baseName.isEmpty)) {
        result.add(Error(
          message:
              'Arguments must specify their type in method "${method.name}" in API: "${api.name}"',
          lineNumber: _calculateLineNumberNullable(source, unnamedType.offset),
        ));
      }
      if (method.objcSelector.isNotEmpty) {
        if (':'.allMatches(method.objcSelector).length !=
            method.arguments.length) {
          result.add(Error(
            message:
                'Invalid selector, expected ${method.arguments.length} arguments.',
            lineNumber: _calculateLineNumberNullable(source, method.offset),
          ));
        }
      }
    }
  }

  return result;
}