Permalink
Browse files

processor api changed for processParameters

  • Loading branch information...
1 parent 07578db commit e702e2d803e2a7cc9ed1cacfad4e14d052269e4f @warmuuh committed Mar 22, 2013
View
@@ -62,8 +62,8 @@ your own annotations easily. All need to be done is to register your processor.
```js
var myProcessor = {
annotation: "@NotNull",
- processFunction: function(object, fnDescription, configuration){... },
- processParameter: function(object, fnDescription, paramDescription, configuration){...}
+ processFunction: function(object, fnDescription, annotationParams, configuration){... },
+ processParameter: function(object, fnDescription, annotatedParameters, configuration){...}
}
yaap.register(myProcessor);
```
@@ -75,6 +75,8 @@ if an annotated parameter is found.
`Remark:` You can either define both or one of these functions, depending on
where you want to allow your annotation to be placed.
+More information on how to create custom annotation processors are available [here](docs/processors.md).
+
##wire.js Integration
To use @Autowired (and annotations in general) in wire.js, simply add it as a plugin:
```js
View
@@ -0,0 +1,56 @@
+#Processors
+
+If you want to register your own Annotation Processor, you need to define it first.
+Every processor can have a processFunction method and a processParameter method, depending,
+if your processor supports parameter-annotations or function-annotations.
+
+The "annotation" property defines the name of your annotation. The following example declares the @NotNull annotation processor.
+
+```js
+var myProcessor = {
+ annotation: "@NotNull",
+ processFunction: function(object, fnDescription, annotationParams, configuration){... },
+ processParameter: function(object, fnDescription, annotatedParameters, configuration){...}
+}
+yaap.register(myProcessor);
+```
+
+The last line registers the processor at yaap. The annotation is now ready to be used.
+
+The configuration object can be supplied as argument to yaap.process so you could hand over some dependencies to the annotation processors.
+
+#Process Functions
+
+the processFunction parameter will be called, if a function-annotation is discovered, e.g.:
+
+```js
+myFn = function() /*@NotNull*/ {...}
+```
+
+It recieves the object on which yaap was called as first attribute. The second attribute is a description of the function, e.g.:
+```js
+{
+name: "myFn",
+parameters: [{name: "..."}, ...]
+}
+```
+Because Annotations can be "called" with parameters, the third parameter, "annotationParams" can contain the parameters.
+
+#Process Parameters
+analog to the function, this will be called in case of a discovered annotation on a parameter.
+The "annotatedParameters" parameter is an array of the parameters that are annotated by the annotation handled by this Annotation Processor.
+Each entry is an object like this:
+```js
+{
+name: "parameterName",
+index: 0,
+annotation: {
+ name:"@NotNull", //will only contain YOUR annotations
+ parameters:[...] //the parameter supplied to this annotation
+ }
+}
+```
+The parameters are handed over as array instead of multiple calls to "processParameters"
+because then you can handle each annotated parameter in one wrapper of the target function
+instead of one separate handler for each annotated parameter.
+
@@ -21,18 +21,20 @@ function() {
return {
annotation: "@Default",
- processParameter: function(obj, fnObj, param, annotationParams) {
+ processParameter: function(obj, fnDescription, annotatedParameters) {
//console.log("@Default("+ annotationParams +") attached at parameter: " + param.name);
- var origFn = obj[fnObj.name];
+ var origFn = obj[fnDescription.name];
- obj[fnObj.name] = function(){
- while (arguments.length -1 < param.index)
- [].push.call(arguments, undefined);
-
- if (arguments[param.index] == null) //tests for null or undefined because 'null==undefined'
- arguments[param.index] = annotationParams[0];
-
+ obj[fnDescription.name] = function(){
+ for(var i = 0; i < annotatedParameters.length; ++i){
+ var param = annotatedParameters[i];
+ while (arguments.length -1 < param.index)
+ [].push.call(arguments, undefined);
+
+ if (arguments[param.index] == null) //tests for null or undefined because 'null==undefined'
+ arguments[param.index] = param.annotation.parameters[0];
+ }
switch(arguments.length){
case 0: return origFn.call(obj);
@@ -23,19 +23,19 @@ return {
annotation: "@NotNull",
- processFunction: function(obj, fnObj) {
+ processFunction: function(obj, fnDescription, annotatedParameter) {
//console.log("@NotNull attached at function");
- var origFn = obj[fnObj.name];
- obj[fnObj.name] = function(){
+ var origFn = obj[fnDescription.name];
+ obj[fnDescription.name] = function(){
- if (fnObj.parameters.length != arguments.length)
- throw "Constraint violated: too few/many arguments at function " + fnObj.name;
+ if (fnDescription.parameters.length != arguments.length)
+ throw "Constraint violated: too few/many arguments at function " + fnDescription.name;
- var idx = arguments.length-1
+ var idx = arguments.length-1;
do{
if (arguments[idx] == null) //null or undefined
- throw "Constraint violated: parameter " + param.name + " of function " + fnObj.name + " is null or undefined.";
+ throw "Constraint violated: parameter " + annotatedParameter.name + " of function " + fnDescription.name + " is null or undefined.";
}while(idx--);
switch(arguments.length){
@@ -46,19 +46,22 @@ return {
default: return origFn.apply(obj, arguments);
}
- }
+ };
},
- processParameter: function(obj, fnObj, param) {
+ processParameter: function(obj, fnDescription, annotatedParameters) {
//console.log("@NotNull attached at parameter: " + param.name);
- var origFn = obj[fnObj.name];
- obj[fnObj.name] = function(){
- if (arguments[param.index] == null) //null or undefined
- throw "Constraint violated: parameter " + param.name + " of function " + fnObj.name + " is null or undefined.";
-
+ var origFn = obj[fnDescription.name];
+ obj[fnDescription.name] = function(){
+ for(var i = 0; i < annotatedParameters.length; ++i)
+ {
+ var param = annotatedParameters[i];
+ if (arguments[param.index] == null) //null or undefined
+ throw "Constraint violated: parameter " + param.name + " of function " + fnDescription.name + " is null or undefined.";
+ }
switch(arguments.length){
case 0: return origFn.call(obj);
case 1: return origFn.call(obj, arguments[0]);
@@ -67,7 +70,7 @@ return {
default: return origFn.apply(obj, arguments);
}
- }
+ };
}
};
@@ -23,25 +23,33 @@ function(_, when) {
return {
annotation: "@Autowired",
- processParameter: function(obj, fnObj, param, annotationParams, cfg) {
+ processParameter: function(obj, fnDescription, annotatedParameters, context) {
//console.log("@Autowired("+ annotationParams +") attached at parameter: " + param.name);
- var refName = annotationParams.length == 1
- ? annotationParams[0]
- : param.name;
-
- var ref = {$ref: refName};
- cfg.wire(ref).then(function (value) {
+ var refs = {};
+ for(var i = 0; i < annotatedParameters.length; ++i){
+
+ var param = annotatedParameters[i];
+ var refName = param.annotation.parameters.length == 1
+ ? param.annotation.parameters[0]
+ : param.name;
+
+ refs[param.name] = {$ref: refName};
+ }
+
+ context.wire(refs).then(function (resolvedRefs) {
- var origFn = obj[fnObj.name];
+ var origFn = obj[fnDescription.name];
- obj[fnObj.name] = function(){
+ obj[fnDescription.name] = function(){
+ for(var i = 0; i < annotatedParameters.length; ++i){
+ var param = annotatedParameters[i];
while (arguments.length -1 < param.index)
[].push.call(arguments, undefined);
if (arguments[param.index] == null) //tests for null or undefined because 'null==undefined'
- arguments[param.index] = value;
-
+ arguments[param.index] = resolvedRefs[param.name];
+ }
switch(arguments.length){
case 0: return origFn.call(obj);
@@ -59,18 +67,18 @@ return {
},
- processFunction: function(obj, fnObj, annotationParams, cfg){
- //console.log("@Autowired("+ annotationParams +") attached at function: " + fnObj.name);
+ processFunction: function(obj, fnDescription, annotationParams, context){
+ //console.log("@Autowired("+ annotationParams +") attached at function: " + fnDescription.name);
- var refs = when.map(fnObj.parameters,
+ var refs = when.map(fnDescription.parameters,
function(param){
return {$ref: param.name};
});
- when.map(refs, cfg.wire).then(function (resolvedRefs){
- var origFn = obj[fnObj.name];
+ when.map(refs, context.wire).then(function (resolvedRefs){
+ var origFn = obj[fnDescription.name];
- obj[fnObj.name] = function(){
+ obj[fnDescription.name] = function(){
while (arguments.length < resolvedRefs.length)
[].push.call(arguments, undefined);
@@ -29,10 +29,10 @@ return {
- processFunction: function(obj, fnObj, annotationParams, cfg){
+ processFunction: function(obj, fnDescription, annotationParams, context){
- registeredInitializers.push({obj: obj, name: fnObj.name});
+ registeredInitializers.push({obj: obj, name: fnDescription.name});
},
afterProcessing: function(obj){
View
@@ -14,11 +14,11 @@
"use strict";
- function annotatesFacet(resolver, facet, wire) {
+ function processAnnotations(resolver, facet, wire) {
var options = facet.options;
var obj = facet.target;
yaap.process(obj, {
- wire: wire
+ wire: wire //feed in context, so Autowire can do its work
});
resolver.resolve();
@@ -41,7 +41,7 @@
yaap.register(initialize); //register annotation processor for @Initialize
return {
- configure: annotatesFacet,
+ configure: processAnnotations,
"ready": afterProcessing
};
}
View
@@ -16,50 +16,59 @@ define(["underscore", "./registry", "./plugins/NotNullProcessor", "./plugins/Def
function(_, registry, NotNullProcessor, DefaultProcessor, wire, PanPG_util, es5, walker) {
-
+ //default annotations are registered here
registry.register([
NotNullProcessor,
DefaultProcessor
]);
- function callProcessors(obj, fnObj, config) {
+ function callProcessors(obj, fnDescription, config) {
+
+
//process function-annotations
- _(fnObj.annotations).each(function (annotation) {
+ _(fnDescription.annotations).each(function (annotation) {
_(registry.getProcessors(annotation.name)).each(function (processor) {
if (_(processor).has("processFunction"))
- processor.processFunction(obj, fnObj, annotation.parameters, config);
+ processor.processFunction(obj, fnDescription, annotation.parameters, config);
else
console.log("Function-annotations are not supported for: " + annotation.name);
});
});
- //process parameter annotations
-
- _(fnObj.parameters).each(function (parameter){
- _(parameter.annotations).each(function (annotation){
- _(registry.getProcessors(annotation.name)).each(function(processor){
- if (_(processor).has("processParameter"))
- processor.processParameter(obj, fnObj, parameter, annotation.parameters, config);
- else
- console.log("Parameter-annotations are not supported for: " + annotation.name);
- });
-
- });
+ //process parameter annotations
+ var parameterArray = {};
+ _(fnDescription.parameters).each(function (parameter){
+ _(parameter.annotations).each(function (annotation){
+ if (parameterArray[annotation.name] === undefined)
+ parameterArray[annotation.name] = [];
+
+ var entry = {
+ name: parameter.name,
+ index: parameter.index,
+ annotation: annotation
+ };
+ parameterArray[annotation.name].push(entry);
+
+
+
+ });
});
-
-
-
-
- };
+ //call processors on annotated parameters
+ _(parameterArray).chain().keys().each(function (annotationName){
+ _(registry.getProcessors(annotationName)).each(function(processor){
+ if (_(processor).has("processParameter"))
+ processor.processParameter(obj, fnDescription, parameterArray[annotationName], config);
+ else
+ console.log("Parameter-annotations are not supported for: " + annotationName);
+ });
+ }).value();
+ }
-
-
-
return {
register: function (processor) {
registry.register([processor]);
@@ -81,14 +90,14 @@ function(_, registry, NotNullProcessor, DefaultProcessor, wire, PanPG_util, es5,
var ast = es5.Program(source);
//console.log(PanPG_util.showTree(ast));
- var fnObjs = null;
+ var fnDescriptions = null;
try{
- fnObjs = PanPG_util.treeWalker(walker, ast);
+ fnDescriptions = PanPG_util.treeWalker(walker, ast);
} catch(e){console.error(e); throw e;}
- _(fnObjs).each(function(fnObj){
- fnObj.name = f;
- callProcessors(obj, fnObj, config);
+ _(fnDescriptions).each(function(fnDescription){
+ fnDescription.name = f;
+ callProcessors(obj, fnDescription, config);
});
});

0 comments on commit e702e2d

Please sign in to comment.