<commit_before>Policy
======

    _ = require "underscore"

    class Policy
        constructor: () ->
            @rules = []
            @libsToWrap = []

            @policy =

Indicate if a given library (name) should be wrapped in a separate membrane. If
a policy doesn't talk about a specific depending library, then it there is no
need for it to be wrapped. Therefor, the default return value is `false`:

                wrapWithMembrane: (libName) -> false

        disable: (lib) -> this

        on: (name) ->
            child = new OnRule name, this
            # check if (lib, call) = name must be added to libsToWrap
            # iff lib[0].toLowerCase() == lib[0]
            @rules.push child
            child

        before: (name) ->
            child = new BeforeRule name, this
            @rules.push child
            child

        after: (name) ->
            child = new AfterRule name, this
            @rules.push child
            child

The `build` method generates the whole structure of our semantic model of the membrane object.

        build: () =>
            @libsToWrap = []

            strEqual = (fullName) -> (rule) -> fullName == rule.apiCall

            areType = (t) ->
                (rule) -> rule instanceof t

            conditionsAreTrue = (dTgt, ret) ->
                (rule) ->
                    _.chain(rule.conditions)
                        .map (cond) -> cond(dTgt, ret) == true
                        .reduce ((memo, c) -> memo and c), true
                        .value()

            doGetActions = (dTgt, args...) ->
                (rule) ->
                    _.chain(rule.actions)
                        .map (action) -> action.apply(this, [dTgt].concat(args))
                    return rule

            calcRetValue = (origRet, rule) -> rule.ret(origRet)

            isEmpty = (l) -> l.size().value() == 0
            isNotFunction = (v) -> typeof v != "function"

            @policy.onGet = (wTgt, name, wRec, dTgt, ret) =>
                name = name.toString()
                fullName = "#{dTgt.constructor.name.toString()}.#{name}"
                relevantRules = _.chain(@rules)
                    .filter(strEqual(fullName))

                onRules = relevantRules.filter(areType(OnRule))
                beforeRules = relevantRules.filter(areType(BeforeRule))
                afterRules = relevantRules.filter(areType(AfterRule))


                onGetValue = onRules.filter(conditionsAreTrue(dTgt, ret))
                    .map(doGetActions(dTgt, ret))
                    .reduce(calcRetValue, ret)
                    .value()

            @policy.functionCall = (dTgt, dryThis, dryArgs, calcResult, fullName) =>
                if dryThis != undefined and fullName.indexOf("/") != -1
                    fullName = "#{dryThis.constructor.name}.#{dTgt.name}"
                relevantRules = _.chain(@rules).filter(strEqual(fullName))

                beforeRules = relevantRules.filter(areType(BeforeRule))
                afterRules = relevantRules.filter(areType(AfterRule))

                calcResult = beforeRules.filter(conditionsAreTrue(dTgt, dryArgs))
                       .map(doGetActions(dTgt, dryArgs, calcResult))
                       .reduce(calcRetValue, calcResult)
                       .value()

                # return as function because the generic membrane will invoke it afterwards
                ->
                    ret = calcResult()
                    afterRules.filter(conditionsAreTrue(dTgt, ret))
                        .map(doGetActions(dTgt, dryArgs, ret))
                        .reduce(calcRetValue, ret)
                        .value()
<commit_msg>Added access to 'this' for advice functions<commit_after>Policy
======

    _ = require "underscore"

    class Policy
        constructor: () ->
            @rules = []
            @libsToWrap = []

            @policy =

Indicate if a given library (name) should be wrapped in a separate membrane. If
a policy doesn't talk about a specific depending library, then it there is no
need for it to be wrapped. Therefor, the default return value is `false`:

                wrapWithMembrane: (libName) -> false

        disable: (lib) -> this

        on: (name) ->
            child = new OnRule name, this
            # check if (lib, call) = name must be added to libsToWrap
            # iff lib[0].toLowerCase() == lib[0]
            @rules.push child
            child

        before: (name) ->
            child = new BeforeRule name, this
            @rules.push child
            child

        after: (name) ->
            child = new AfterRule name, this
            @rules.push child
            child

The `build` method generates the whole structure of our semantic model of the membrane object.

        build: () =>
            @libsToWrap = []

            strEqual = (fullName) -> (rule) -> fullName == rule.apiCall

            areType = (t) ->
                (rule) -> rule instanceof t

            conditionsAreTrue = (dTgt, ret) ->
                (rule) ->
                    _.chain(rule.conditions)
                        .map (cond) -> cond(dTgt, ret) == true
                        .reduce ((memo, c) -> memo and c), true
                        .value()

            doGetActions = (dTgt, args...) ->
                (rule) ->
                    _.chain(rule.actions)
                        .map (action) -> action.apply(this, [dTgt].concat(args))
                    return rule

            calcRetValue = (origRet, rule) -> rule.ret(origRet)

            isEmpty = (l) -> l.size().value() == 0
            isNotFunction = (v) -> typeof v != "function"

            @policy.onGet = (wTgt, name, wRec, dTgt, ret) =>
                name = name.toString()
                fullName = "#{dTgt.constructor.name.toString()}.#{name}"
                relevantRules = _.chain(@rules)
                    .filter(strEqual(fullName))

                onRules = relevantRules.filter(areType(OnRule))
                beforeRules = relevantRules.filter(areType(BeforeRule))
                afterRules = relevantRules.filter(areType(AfterRule))


                onGetValue = onRules.filter(conditionsAreTrue(dTgt, ret))
                    .map(doGetActions(dTgt, ret))
                    .reduce(calcRetValue, ret)
                    .value()

            @policy.functionCall = (dTgt, dryThis, dryArgs, calcResult, fullName) =>
                if dryThis != undefined and fullName.indexOf("/") != -1
                    fullName = "#{dryThis.constructor.name}.#{dTgt.name}"
                relevantRules = _.chain(@rules).filter(strEqual(fullName))

                beforeRules = relevantRules.filter(areType(BeforeRule))
                afterRules = relevantRules.filter(areType(AfterRule))

                calcResult = beforeRules.filter(conditionsAreTrue(dTgt, dryArgs))
                       .map(doGetActions(dryThis, dTgt, dryArgs, calcResult))
                       .reduce(calcRetValue, calcResult)
                       .value()

                # return as function because the generic membrane will invoke it afterwards
                ->
                    ret = calcResult()
                    afterRules.filter(conditionsAreTrue(dTgt, ret))
                        .map(doGetActions(dryThis, dTgt, dryArgs, ret))
                        .reduce(calcRetValue, ret)
                        .value()

{'fraction_non_alphanumeric': 0.1086313525141167, 'fraction_numerical': 0.0010755579456843238, 'mean_word_length': 1.4854660875375878, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6160526', 'n_tokens_mistral': 2003, 'n_tokens_neox': 1858, 'n_words': 500}