<commit_before>package hunit.mock;

import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
import tink.macro.Member;
import tink.core.Outcome;

using hunit.Utils;


/**
 * Generates class which grants write access to all properties of target type
 *
 */
class MockModifierGenerator
{
    /** defined modifiers */
    static private var definedTypes : Map<String,TypeDefinition> = new Map();

    /** mocked type */
    private var target : Type;
    /** Generated type of MockModifier */
    private var definedType : TypeDefinition;


    /**
     * Constructor
     *
     */
    public function new (type:Type) : Void
    {
        target = type;
    }


    /**
     * Get mocked type
     *
     */
    public function getTarget () : Type
    {
        return target;
    }


    /**
     * Get MockModifier type definition
     *
     */
    public function getTypeDefinition () : TypeDefinition
    {
        defineType();

        return definedType;
    }


    /**
     * Define creator type
     *
     */
    public function defineType () : Void
    {
        if (definedType != null) return;
        var typeNamePostfix = '_MockModifier';

        var modifierClassName = getTarget().toString() + typeNamePostfix;

        definedType = definedTypes.get(modifierClassName);
        if (definedType != null) return;

        var targetTypePath = getTarget().getTypePath();
        var pack = targetTypePath.pack;
        var name = targetTypePath.name + typeNamePostfix;
        var pos  = Context.currentPos();

        var targetPack = getTarget().getTypePath().pack.join('.').parse(pos);

        definedType = {
            pack   : pack,
            name   : name,
            pos    : pos,
            kind   : TDClass(),
            fields : getFields(),
            meta   : [{name:':access', params:[macro $targetPack], pos:pos}]
        }
        definedTypes.set(modifierClassName, definedType);

        Context.defineType(definedType);
    }


    /**
     * Get fields for mock modifier type
     *
     */
    private function getFields () : Array<Field>
    {
        var targetComplexType = getTarget().toComplexType();
        var def = macro class Dummy {
            var __hu_mock__ : $targetComplexType;
            public function new (mock) __hu_mock__ = mock;
        }

        var fields = def.fields;

        var pos = Context.currentPos();
        switch (getTarget().getFields()) {
            case Failure(_):
            case Success(mockFields):
                for (field in mockFields) {
                    if (field.name == '__hu_mock__') continue;
                    var member : Member = field.toField();

                    switch (member.getVar()) {
                        case Success(v):
                            var name = field.name;
                            fields.push(Member.prop(name, v.type, pos, false, false));

                            if (v.set != 'never') {
                                var setterBody = macro return __hu_mock__.$name = value;
                                fields.push(Member.setter(name, 'value', pos, setterBody));
                            }
                            if (v.get != 'never') {<commit_msg>fix private access to mocks when getter or setter are set to `never`<commit_after>package hunit.mock;

import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
import tink.macro.Member;
import tink.core.Outcome;

using hunit.Utils;


/**
 * Generates class which grants write access to all properties of target type
 *
 */
class MockModifierGenerator
{
    /** defined modifiers */
    static private var definedTypes : Map<String,TypeDefinition> = new Map();

    /** mocked type */
    private var target : Type;
    /** Generated type of MockModifier */
    private var definedType : TypeDefinition;


    /**
     * Constructor
     *
     */
    public function new (type:Type) : Void
    {
        target = type;
    }


    /**
     * Get mocked type
     *
     */
    public function getTarget () : Type
    {
        return target;
    }


    /**
     * Get MockModifier type definition
     *
     */
    public function getTypeDefinition () : TypeDefinition
    {
        defineType();

        return definedType;
    }


    /**
     * Define creator type
     *
     */
    public function defineType () : Void
    {
        if (definedType != null) return;
        var typeNamePostfix = '_MockModifier';

        var modifierClassName = getTarget().toString() + typeNamePostfix;

        definedType = definedTypes.get(modifierClassName);
        if (definedType != null) return;

        var targetTypePath = getTarget().getTypePath();
        var pack = targetTypePath.pack;
        var name = targetTypePath.name + typeNamePostfix;
        var pos  = Context.currentPos();

        var targetPack = getTarget().getTypePath().pack.join('.').parse(pos);

        definedType = {
            pack   : pack,
            name   : name,
            pos    : pos,
            kind   : TDClass(),
            fields : getFields(),
            meta   : [{name:':access', params:[macro $targetPack], pos:pos}]
        }
        definedTypes.set(modifierClassName, definedType);

        Context.defineType(definedType);
    }


    /**
     * Get fields for mock modifier type
     *
     */
    private function getFields () : Array<Field>
    {
        var targetComplexType = getTarget().toComplexType();
        var def = macro class Dummy {
            var __hu_mock__ : $targetComplexType;
            public function new (mock) __hu_mock__ = mock;
        }

        var fields = def.fields;

        var pos = Context.currentPos();
        switch (getTarget().getFields()) {
            case Failure(_):
            case Success(mockFields):
                for (field in mockFields) {
                    if (field.name == '__hu_mock__') continue;
                    var member : Member = field.toField();

                    switch (member.getVar()) {
                        case Success(v):
                            var name = field.name;
                            var hasSetter = (v.set != 'never');
                            var hasGetter = (v.get != 'never');

                            fields.push(Member.prop(name, v.type, pos, !hasGetter, !hasSetter));

                            if (hasSetter) {
                                var setterBody = macro return __hu_mock__.$name = value;
                                fields.push(Member.setter(name, 'value', pos, setterBody));
                            }
                            if (hasGetter) {
{'fraction_non_alphanumeric': 0.10569105691056911, 'fraction_numerical': 0.0, 'mean_word_length': 1.672164119066774, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1774064', 'n_tokens_mistral': 1802, 'n_tokens_neox': 1722, 'n_words': 452}