[X++] Create set-methods automatically on AxBC classes

When taking a look on the class AxGenerateAxBCClass you propably notice that in method createInterfaceMethods there is a variable called setMethodName but it's never used!
Only parm-methods will be generated by this class.

Seems like Microsoft thought a good way for us but didn't implement it (for whatever reason).

Adding the defaultSetMethod-method

There is a method to get the source code of a default parm-method AxGenerateAxBCClass.defaultParmMethod. We also need such a method for the set methods:

public str defaultSetMethod(str          _typeName,
                             IdentifierName _methodName,
                             str            _variableName,
                             SysDictField   _dictField,
                             DictEnum       _dictEnum)
{
    str             defaultValue;
    DictEnum        dictBaseEnum;
    SysDictType     sysDictType;
    str             methodString;
    IdentifierName  setName = 'set'+_methodName;
    ;
    switch (_dictField.baseType())
    {
        case Types::String:
            if(SysDictType::isEqualOrExtending(_dictField.typeId(),extendedTypeNum(SysDim)))
            {
                sysDictType = new SysDictType(extendedTypeNum(Dimension));
                if (sysDictType.arraySize() == _dictField.arraySize())
                {
                    defaultValue = 'Dimensions::emptyDimension()';
                }
                else
                {
                    defaultValue = '\'\'';
                }
            }
            else
            {
                defaultValue = '\'\'';
            }
            break;
        case Types::Integer:
        case Types::Real, Types::Int64:
            defaultValue = '0';
            break;
        case Types::Date:
            defaultValue = 'dateNull()';
            break;
        case Types::Enum:

            if (_dictEnum)
            {
                defaultValue = strFmt("%1"+"::"+"%2",_dictEnum.name(),_dictEnum.index2Symbol(0));
            }
            else
            {
                dictBaseEnum = new DictEnum(_dictField.enumId());
                if (dictBaseEnum)
                {

                    defaultValue = strFmt("%1"+"::"+"%2",dictBaseEnum.name(),dictBaseEnum.index2Symbol(0));
                }
                else
                {
                defaultValue = '0';
                }
            }

            break;
        case Types::Container :
            defaultValue = 'connull()';
            break;
        case Types::Guid :
            defaultValue = 'nullValueFromType(Types::Guid)';
            break;
        case Types::UtcDateTime:
            defaultValue = 'UtcDateTimeNull()';
            break;
        default :
            defaultValue = '\'\'';
            break;
    }

    methodString =
           'protected void ' + setName + '()\n' +
           '{\n' ;

    methodString +=
           '    if (this.isMethodExecuted(funcname(),fieldnum(' + tableName + ', ' + _dictField.name() + ')))\n' +
           '    {\n' +
           '        return;' +
           '\n' +
           '    }\n' +
           '}\n';
    return methodString;

}

Basically this is very similar to the defaultParmMethod-method with some changes to match the set-methods.
This code should be self-explaining.

Now this method must be called somewhere. And this will be in the createInterfaceMethods method after line 74:

...
_newclass.addMethod(parmMethodName, todoString);
            // add set method -->
            todoString = this.yavDefaultSetMethod(typeName, methodName, variableName, _sysDictField, dictEnum);
            _newclass.addMethod(setMethodName, todoString);
            // add set method <--
        }
    }
}
Testing

Now when we run the class with the following code, it creates the set-methods aswell as the parm-methods:

AxGenerateAxBCClass gen;    
gen = AxGenerateAxBCClass::newTableId(tableNum(SalesTable));
gen.run();

Result AxBC class