Make getAnnotation generic

This commit is contained in:
Tobe O 2019-04-08 15:53:07 -04:00
parent 1b1c190de4
commit 62709c0bbd
15 changed files with 41 additions and 37 deletions

View file

@ -1,3 +1,7 @@
# 2.0.0-alpha.24
* Add `AngelEnv` class to `core`.
* Deprecate `Angel.isProduction`, in favor of `AngelEnv`.
# 2.0.0-alpha.23
* `ResponseContext.render` sets `charset` to `utf8` in `contentType`.

View file

@ -3,4 +3,4 @@ analyzer:
implicit-casts: false
linter:
rules:
- avoid_slow_async_io
- avoid_slow_async_io

View file

@ -75,9 +75,9 @@ class Controller {
methodName != 'call' &&
methodName != 'equals' &&
methodName != '==') {
Expose exposeDecl = decl.function.annotations
var exposeDecl = decl.function.annotations
.map((m) => m.reflectee)
.firstWhere((r) => r is Expose, orElse: () => null);
.firstWhere((r) => r is Expose, orElse: () => null) as Expose;
if (exposeDecl == null) return;

View file

@ -1,6 +1,7 @@
export 'anonymous_service.dart';
export 'controller.dart';
export 'driver.dart';
export 'env.dart';
export 'hooked_service.dart';
export 'map_service.dart';
export 'metadata.dart';

View file

@ -1,15 +1,15 @@
import 'dart:io';
/// A constant instance of [AngelEnv].
const AngelEnv angelEnv = const AngelEnv();
const AngelEnvironment angelEnv = const AngelEnvironment();
/// Queries the environment's `ANGEL_ENV` value.
class AngelEnv {
class AngelEnvironment {
final String _customValue;
/// You can optionally provide a custom value, in order to override the system's
/// value.
const AngelEnv([this._customValue]);
const AngelEnvironment([this._customValue]);
/// Returns the value of the `ANGEL_ENV` variable; defaults to `'development'`.
String get value =>

View file

@ -90,7 +90,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
/// Adds hooks to this instance.
void addHooks(Angel app) {
Hooks hooks = getAnnotation(inner, Hooks, app.container.reflector);
Hooks hooks = getAnnotation<Hooks>(inner, app.container.reflector);
List<HookedServiceEventListener<Id, Data, T>> before = [], after = [];
if (hooks != null) {
@ -101,7 +101,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
void applyListeners(
Function fn, HookedServiceEventDispatcher<Id, Data, T> dispatcher,
[bool isAfter]) {
Hooks hooks = getAnnotation(fn, Hooks, app.container.reflector);
Hooks hooks = getAnnotation<Hooks>(fn, app.container.reflector);
final listeners = <HookedServiceEventListener<Id, Data, T>>[]
..addAll(isAfter == true ? after : before);

View file

@ -53,8 +53,8 @@ resolveInjection(requirement, InjectionRequest injection, RequestContext req,
requirement.length == 2 &&
requirement.first is String &&
requirement.last is Type) {
String key = requirement.first;
Type type = requirement.last;
var key = requirement.first;
var type = requirement.last;
if (req.params.containsKey(key) ||
req.app.configuration.containsKey(key) ||
_primitiveTypes.contains(type)) {

View file

@ -51,7 +51,7 @@ class MapService extends Service<String, Map<String, dynamic>> {
if (allowQuery == false || params == null || params['query'] is! Map)
return new Future.value(items);
else {
Map query = params['query'];
var query = params['query'] as Map;
return new Future.value(items.where((item) {
for (var key in query.keys) {

View file

@ -99,7 +99,7 @@ class Routable extends Router<RequestHandler> {
final handlers = <RequestHandler>[];
// Merge @Middleware declaration, if any
Middleware middlewareDeclaration =
getAnnotation(handler, Middleware, _container?.reflector);
getAnnotation<Middleware>(handler, _container?.reflector);
if (middlewareDeclaration != null) {
handlers.addAll(middlewareDeclaration.handlers);
}

View file

@ -15,6 +15,7 @@ import 'package:mime/mime.dart';
import 'package:tuple/tuple.dart';
import 'controller.dart';
import 'env.dart';
import 'hooked_service.dart';
import 'request_context.dart';
import 'response_context.dart';
@ -42,7 +43,6 @@ class Angel extends Routable {
MiddlewarePipeline>> handlerCache = new HashMap();
Router<RequestHandler> _flattened;
bool _isProduction;
Angel _parent;
/// A global Map of converters that can transform responses bodies.
@ -75,6 +75,8 @@ class Angel extends Routable {
/// A set of [Controller] objects that have been loaded into the application.
Map<Pattern, Controller> get controllers => _controllers;
/// Now *deprecated*, in favor of [AngelEnv] and [angelEnv].
///
/// Indicates whether the application is running in a production environment.
///
/// The criteria for this is the `ANGEL_ENV` environment variable being set to
@ -82,10 +84,8 @@ class Angel extends Routable {
///
/// This value is memoized the first time you call it, so do not change environment
/// configuration at runtime!
bool get isProduction {
return _isProduction ??=
(Platform.environment['ANGEL_ENV'] == 'production');
}
@deprecated
bool get isProduction => angelEnv.isProduction;
/// Returns the parent instance of this application, if any.
Angel get parent => _parent;
@ -282,7 +282,7 @@ class Angel extends Routable {
return parent != null ? parent.findProperty(key) : null;
}
/// Runs several optimizations, *if* [isProduction] is `true`.
/// Runs several optimizations, *if* [angelEnv.isProduction] is `true`.
///
/// * Preprocesses all dependency injection, and eliminates the burden of reflecting handlers
/// at run-time.
@ -291,7 +291,6 @@ class Angel extends Routable {
/// You may [force] the optimization to run, if you are not running in production.
void optimizeForProduction({bool force: false}) {
if (isProduction == true || force == true) {
_isProduction = true;
_flattened ??= flatten(this);
logger?.info('Angel is running in production mode.');
}

View file

@ -195,12 +195,12 @@ class Service<Id, Data> extends Routable {
// Add global middleware if declared on the instance itself
Middleware before =
getAnnotation(service, Middleware, app.container.reflector);
getAnnotation<Middleware>(service, app.container.reflector);
if (before != null) handlers.addAll(before.handlers);
Middleware indexMiddleware =
getAnnotation(service.index, Middleware, app.container.reflector);
getAnnotation<Middleware>(service.index, app.container.reflector);
get('/', (req, res) {
return this.index(mergeMap([
{'query': req.queryParameters},
@ -213,7 +213,7 @@ class Service<Id, Data> extends Routable {
..addAll((indexMiddleware == null) ? [] : indexMiddleware.handlers));
Middleware createMiddleware =
getAnnotation(service.create, Middleware, app.container.reflector);
getAnnotation<Middleware>(service.create, app.container.reflector);
post('/', (req, ResponseContext res) {
return req.parseBody().then((_) {
return this
@ -236,7 +236,7 @@ class Service<Id, Data> extends Routable {
(createMiddleware == null) ? [] : createMiddleware.handlers));
Middleware readMiddleware =
getAnnotation(service.read, Middleware, app.container.reflector);
getAnnotation<Middleware>(service.read, app.container.reflector);
get('/:id', (req, res) {
return this.read(
@ -252,7 +252,7 @@ class Service<Id, Data> extends Routable {
..addAll((readMiddleware == null) ? [] : readMiddleware.handlers));
Middleware modifyMiddleware =
getAnnotation(service.modify, Middleware, app.container.reflector);
getAnnotation<Middleware>(service.modify, app.container.reflector);
patch('/:id', (req, res) {
return req.parseBody().then((_) {
return this.modify(
@ -271,7 +271,7 @@ class Service<Id, Data> extends Routable {
(modifyMiddleware == null) ? [] : modifyMiddleware.handlers));
Middleware updateMiddleware =
getAnnotation(service.update, Middleware, app.container.reflector);
getAnnotation<Middleware>(service.update, app.container.reflector);
post('/:id', (req, res) {
return req.parseBody().then((_) {
return this.update(
@ -306,7 +306,7 @@ class Service<Id, Data> extends Routable {
(updateMiddleware == null) ? [] : updateMiddleware.handlers));
Middleware removeMiddleware =
getAnnotation(service.remove, Middleware, app.container.reflector);
getAnnotation<Middleware>(service.remove, app.container.reflector);
delete('/', (req, res) {
return this.remove(
null,

View file

@ -2,26 +2,26 @@ import 'package:angel_container/angel_container.dart';
final RegExp straySlashes = new RegExp(r'(^/+)|(/+$)');
matchingAnnotation(List<ReflectedInstance> metadata, Type T) {
T matchingAnnotation<T>(List<ReflectedInstance> metadata) {
for (ReflectedInstance metaDatum in metadata) {
if (metaDatum.type.reflectedType == T) {
return metaDatum.reflectee;
return metaDatum.reflectee as T;
}
}
return null;
}
getAnnotation(obj, Type T, Reflector reflector) {
T getAnnotation<T>(obj, Reflector reflector) {
if (reflector == null) {
return null;
} else {
if (obj is Function) {
var methodMirror = reflector.reflectFunction(obj);
return matchingAnnotation(methodMirror.annotations, T);
return matchingAnnotation<T>(methodMirror.annotations);
} else {
var classMirror = reflector.reflectClass(obj.runtimeType as Type);
return matchingAnnotation(classMirror.annotations, T);
return matchingAnnotation<T>(classMirror.annotations);
}
}
}

View file

@ -122,7 +122,7 @@ main() {
expect(rgx.firstMatch(response.body)?.start, equals(0));
Map todo = json.decode(response.body.replaceAll(rgx, ""));
var todo = json.decode(response.body.replaceAll(rgx, "")) as Map;
print("Todo: $todo");
expect(todo['text'], equals("Hello"));
expect(todo['over'], equals("world"));

View file

@ -73,19 +73,19 @@ main() {
test("make in route", () async {
var response = await client.get("$url/errands3");
String text = await json.decode(response.body);
var text = await json.decode(response.body) as String;
expect(text, equals(TEXT));
});
test("make in controller", () async {
var response = await client.get("$url/errands4");
String text = await json.decode(response.body);
var text = await json.decode(response.body) as String;
expect(text, equals(TEXT));
});
}
void validateTodoSingleton(response) {
Map todo = json.decode(response.body.toString());
var todo = json.decode(response.body.toString()) as Map;
expect(todo["id"], equals(null));
expect(todo["text"], equals(TEXT));
expect(todo["over"], equals(OVER));

View file

@ -77,7 +77,7 @@ main() {
body: json.encode({"arbitrary": "data"}),
headers: headers as Map<String, String>);
print(response.body);
Map result = json.decode(response.body);
var result = json.decode(response.body) as Map;
expect(result["hello"], equals("hooked world"));
});
@ -95,7 +95,7 @@ main() {
var response = await client.get("$url/todos");
print(response.body);
List result = json.decode(response.body);
var result = json.decode(response.body) as List;
expect(result[0]["angel"], equals("framework"));
});