From 108c31af48253a800bd3b70176c277504742b08c Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Tue, 4 Jul 2017 20:25:37 -0700 Subject: [PATCH] Add type checks. --- lib/src/type_checker.dart | 18 ++++++++++++++---- test/type_checker_test.dart | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/src/type_checker.dart b/lib/src/type_checker.dart index 5e91470e..6c091b40 100644 --- a/lib/src/type_checker.dart +++ b/lib/src/type_checker.dart @@ -58,15 +58,25 @@ abstract class TypeChecker { return results.isEmpty ? null : results.first; } + DartObject _checkedConstantValue(ElementAnnotation annotation) { + final result = annotation.computeConstantValue(); + if (result == null) { + throw new StateError( + 'Could not resolve $annotation. An import or dependency may be ' + 'missing or invalid.'); + } + return result; + } + /// Returns annotating constants on [element] assignable to this type. Iterable annotationsOf(Element element) => element.metadata - .map((a) => a.computeConstantValue()) - .where((a) => isAssignableFromType(a.type)); + .map(_checkedConstantValue) + .where((a) => a?.type != null && isAssignableFromType(a.type)); /// Returns annotating constants on [element] of exactly this type. Iterable annotationsOfExact(Element element) => element.metadata - .map((a) => a.computeConstantValue()) - .where((a) => isExactlyType(a.type)); + .map(_checkedConstantValue) + .where((a) => a?.type != null && isExactlyType(a.type)); /// Returns `true` if the type of [element] can be assigned to this type. bool isAssignableFrom(Element element) => diff --git a/test/type_checker_test.dart b/test/type_checker_test.dart index d5e6d8bc..ae127b6c 100644 --- a/test/type_checker_test.dart +++ b/test/type_checker_test.dart @@ -179,4 +179,19 @@ void main() { checkGeneratorForAnnotation: () => const TypeChecker.fromUrl( 'package:source_gen/src/generator_for_annotation.dart#GeneratorForAnnotation')); }); + + test('should gracefully when something is not resolvable', () async { + final resolver = await resolveSource(r''' + library _test; + + @depracated // Intentionally mispelled. + class X {} + '''); + final lib = resolver.getLibraryByName('_test'); + final classX = lib.getType('X'); + final $deprecated = const TypeChecker.fromRuntime(Deprecated); + + expect(() => $deprecated.annotationsOf(classX), throwsStateError, + reason: 'deprecated was spelled wrong; no annotation can be resolved'); + }); }