Created
August 19, 2016 00:19
-
-
Save bkad/08d22f48bd6e1c769b9ab46cda9e23b6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Utility function to annotate CoffeeScript classes for Angular | |
_nextClassId = 0 | |
isFunction = (thing) -> | |
typeof thing is "function" | |
isArray = (thing) -> | |
Array.isArray(thing) | |
stringify = (thing) -> | |
if typeof thing is "string" | |
thing | |
else if not thing? | |
"#{thing}" | |
else if thing.overriddenName | |
thing.overriddenName | |
else if thing.name | |
thing.name | |
else | |
res = thing.toString() | |
newLineIndex = res.indexOf("\n") | |
if newLineIndex is -1 then res else res.substring(0, newLineIndex) | |
extractAnnotation = (annotation) -> | |
if isFunction(annotation) and annotation.hasOwnProperty("annotation") | |
annotation.annotation | |
else | |
annotation | |
applyParams = (fnOrArray, key) -> | |
if isFunction(fnOrArray) | |
fnOrArray | |
else if isArray(fnOrArray) | |
[annotations..., fn] = fnOrArray | |
annoLength = annotations.length | |
if not isFunction(fn) | |
throw new Error("Last position of Class method array must be Function in key '#{key}' was #{stringify(fn)}") | |
if annoLength isnt fn.length | |
throw new Error("Number of annotations (#{annoLength}) does not match number of arguments (#{fn.length}) | |
in the function: #{stringify(fn)}") | |
paramsAnnotations = [] | |
for annotation in annotations | |
currAnnotations = [] | |
paramsAnnotations.push(currAnnotations) | |
if isArray(annotation) | |
for subAnnotation in annotation | |
currAnnotations.push(extractAnnotation(subAnnotation)) | |
else if isFunction(annotation) | |
currAnnotations.push(extractAnnotation(annotation)) | |
else | |
currAnnotations.push(annotation) | |
Reflect.defineMetadata("parameters", paramsAnnotations, fn) | |
fn | |
else | |
throw new Error("Only Function or Array is supported in Class definition for key '#{key}' is '#{stringify(fnOrArray)}'") | |
module.exports = (coffeeClass) -> | |
proto = coffeeClass.prototype | |
parameters = proto.parameters ? [] | |
applied = [parameters..., proto.constructor] | |
constructor = proto.constructor = applyParams(applied, "constructor") | |
unless constructor.name | |
constructor.overriddenName = "_anno_class#{_nextClassId++}" | |
if isArray(proto.annotations) | |
Reflect.defineMetadata("annotations", proto.annotations) | |
decorators = proto.decorators | |
if isArray(decorators) | |
callback = (accum, decorator) -> | |
decorator(accum) | |
constructor = decorators.reduceRight(callback, constructor) | |
constructor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment