Make getAnnotation generic
This commit is contained in:
parent
1b1c190de4
commit
62709c0bbd
15 changed files with 41 additions and 37 deletions
|
@ -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`.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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"));
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue