| 
 | 1 | +import 'dart:io';  | 
 | 2 | + | 
 | 3 | +import 'package:analyzer/dart/analysis/results.dart';  | 
 | 4 | +import 'package:analyzer/dart/analysis/session.dart';  | 
 | 5 | +import 'package:analyzer/dart/ast/ast.dart';  | 
 | 6 | +import 'package:analyzer/dart/element/element.dart';  | 
 | 7 | +import 'package:analyzer/error/error.dart' hide LintCode;  | 
 | 8 | +import 'package:analyzer/error/listener.dart';  | 
 | 9 | +import 'package:custom_lint_builder/custom_lint_builder.dart';  | 
 | 10 | +import 'package:drift_dev/src/analysis/backend.dart';  | 
 | 11 | +import 'package:drift_dev/src/analysis/driver/error.dart';  | 
 | 12 | +import 'package:drift_dev/src/analysis/options.dart';  | 
 | 13 | +import 'package:logging/logging.dart';  | 
 | 14 | + | 
 | 15 | +import '../analysis/driver/driver.dart';  | 
 | 16 | + | 
 | 17 | +final columnBuilderChecker =  | 
 | 18 | +    TypeChecker.fromName('DriftDatabase', packageName: 'drift');  | 
 | 19 | + | 
 | 20 | +class DriftBuildErrors extends DartLintRule {  | 
 | 21 | +  DriftBuildErrors() : super(code: _errorCode);  | 
 | 22 | + | 
 | 23 | +  static const _errorCode = LintCode(  | 
 | 24 | +    name: 'drift_build_errors',  | 
 | 25 | +    problemMessage: '{0}',  | 
 | 26 | +    errorSeverity: ErrorSeverity.ERROR,  | 
 | 27 | +  );  | 
 | 28 | +  LintCode get _warningCode => LintCode(  | 
 | 29 | +      name: _errorCode.name,  | 
 | 30 | +      problemMessage: _errorCode.problemMessage,  | 
 | 31 | +      errorSeverity: ErrorSeverity.WARNING);  | 
 | 32 | + | 
 | 33 | +  @override  | 
 | 34 | +  void run(CustomLintResolver resolver, ErrorReporter reporter,  | 
 | 35 | +      CustomLintContext context) async {  | 
 | 36 | +    final unit = await resolver.getResolvedUnitResult();  | 
 | 37 | +    final backend = CustomLintBackend(unit.session);  | 
 | 38 | +    final driver = DriftAnalysisDriver(backend, const DriftOptions.defaults());  | 
 | 39 | + | 
 | 40 | +    final file = await driver.fullyAnalyze(unit.uri);  | 
 | 41 | +    for (final error in file.allErrors) {  | 
 | 42 | +      if (error.span case final span?) {  | 
 | 43 | +        // ignore: deprecated_member_use  | 
 | 44 | +        reporter.reportErrorForSpan(  | 
 | 45 | +            error.level == DriftAnalysisErrorLevel.warning  | 
 | 46 | +                ? _warningCode  | 
 | 47 | +                : _errorCode,  | 
 | 48 | +            span,  | 
 | 49 | +            [error.message.trim()]);  | 
 | 50 | +      }  | 
 | 51 | +    }  | 
 | 52 | +  }  | 
 | 53 | +}  | 
 | 54 | + | 
 | 55 | +class CustomLintBackend extends DriftBackend {  | 
 | 56 | +  @override  | 
 | 57 | +  final Logger log = Logger('drift_dev.CustomLintBackend');  | 
 | 58 | +  final AnalysisSession session;  | 
 | 59 | + | 
 | 60 | +  CustomLintBackend(this.session);  | 
 | 61 | + | 
 | 62 | +  @override  | 
 | 63 | +  bool get canReadDart => true;  | 
 | 64 | + | 
 | 65 | +  @override  | 
 | 66 | +  Future<AstNode?> loadElementDeclaration(Element element) async {  | 
 | 67 | +    final library = element.library;  | 
 | 68 | +    if (library == null) return null;  | 
 | 69 | + | 
 | 70 | +    final info = await library.session.getResolvedLibraryByElement(library);  | 
 | 71 | +    if (info is ResolvedLibraryResult) {  | 
 | 72 | +      return info.getElementDeclaration(element)?.node;  | 
 | 73 | +    } else {  | 
 | 74 | +      return null;  | 
 | 75 | +    }  | 
 | 76 | +  }  | 
 | 77 | + | 
 | 78 | +  @override  | 
 | 79 | +  Future<String> readAsString(Uri uri) async {  | 
 | 80 | +    final file = session.getFile(uri.path);  | 
 | 81 | + | 
 | 82 | +    if (file is FileResult) {  | 
 | 83 | +      return file.content;  | 
 | 84 | +    }  | 
 | 85 | + | 
 | 86 | +    throw FileSystemException('Not a file result: $file');  | 
 | 87 | +  }  | 
 | 88 | + | 
 | 89 | +  @override  | 
 | 90 | +  Future<LibraryElement> readDart(Uri uri) async {  | 
 | 91 | +    final result = await session.getLibraryByUri(uri.toString());  | 
 | 92 | +    if (result is LibraryElementResult) {  | 
 | 93 | +      return result.element;  | 
 | 94 | +    }  | 
 | 95 | + | 
 | 96 | +    throw NotALibraryException(uri);  | 
 | 97 | +  }  | 
 | 98 | + | 
 | 99 | +  @override  | 
 | 100 | +  Future<Expression> resolveExpression(  | 
 | 101 | +      Uri context, String dartExpression, Iterable<String> imports) {  | 
 | 102 | +    throw CannotReadExpressionException('Not supported at the moment');  | 
 | 103 | +  }  | 
 | 104 | + | 
 | 105 | +  @override  | 
 | 106 | +  Future<Element?> resolveTopLevelElement(  | 
 | 107 | +      Uri context, String reference, Iterable<Uri> imports) {  | 
 | 108 | +    throw UnimplementedError();  | 
 | 109 | +  }  | 
 | 110 | + | 
 | 111 | +  @override  | 
 | 112 | +  Uri resolveUri(Uri base, String uriString) => base.resolve(uriString);  | 
 | 113 | +}  | 
0 commit comments