I have two classes:
[DataContractAttribute, SysOperationContractProcessingAttribute(classStr(CustBalanceUIBuilder)), SysOperationGroupAttribute('Date',"@ApplicationPlatform:SingleSpace", '1')]
public class CustBalanceDataContract implements SysOperationValidatable
{
NoYesId allowModifyDate;
TransDate transDate;
str packedQuery;
[DataMemberAttribute('DateTransactionDate'), SysOperationLabelAttribute(literalStr("@SYS11284")), SysOperationGroupMemberAttribute('Date'), SysOperationDisplayOrderAttribute('1')]
public TransDate parmTransDate(TransDate _transDate = transDate)
{
transDate = _transDate;
return transDate;
}
[DataMemberAttribute('DateControl'), SysOperationLabelAttribute("Enable date control"), SysOperationGroupMemberAttribute('Date'), SysOperationDisplayOrderAttribute('0')]
public NoYesId parmAllowModifyDate(NoYesId _allowModifyDate = allowModifyDate)
{
allowModifyDate = _allowModifyDate;
return allowModifyDate;
}
public boolean validate()
{
boolean ret = true;
if(!transDate && allowModifyDate)
{
ret = checkFailed('Transaction date cannot be empty');
}
return ret;
}
[DataMemberAttribute, AifQueryTypeAttribute('_packedQuery', querystr(CustTableSRS))]
public str parmQuery(str _packedQuery = packedQuery)
{
packedQuery = _packedQuery;
return packedQuery;
}
public Query getQuery()
{
return new Query(SysOperationHelper::base64Decode(packedQuery));
}
public void setQuery(Query _query)
{
packedQuery =SysOperationHelper::base64Encode(_query.pack());
}
}
and
public class CustBalanceService
{
public void processData(CustBalanceDataContract _custBalanceDataContract)
{
QueryRun queryRun = new queryRun(_custBalanceDataContract.getQuery());
while(queryRun.next())
{
CustTable custTable = queryRun.get(tableNum(custTable));
TransDate transDate = _custBalanceDataContract.parmTransDate();
Amount balance = (transDate)
? custTable.balanceMST(dateNull(), transDate)
: custTable.balanceMST();
info(strFmt('%1 - %2', custTable.AccountNum, balance));
}
}
}
When it compiles successfully, it behaves as expected.
However, if I save CustBalanceDataContract
, the solution recompiles and then tells me there is an error in CustBalanceService
because _custBalanceDataContract.parmTransDate();
is missing argument 1, which you can see from the signature public TransDate parmTransDate(TransDate _transDate = transDate)
should be an optional argument.
But then if I change nothing and save CustBalanceService
again, the compilation is as expected.
Is this a bug in the compiler? Is it a known issue? Is there a fix for this? Is there something actually wrong with the code which might cause failures even after it successfully compiles and executes?
I can reproduce the issue.
It seems you have a knack for finding those little idiosynchracies in x++. To answer your questions, yes, this could be an issue in the compiler. As I said in a comment on one of your other questions, x++ has some legacy baggage from the time when it wasn't part of the .NET language family. In general, I consider compilation during save of a single object or even the compilation of a whole project/solution more of a nice to have. The only compilation that in my experience works reliably and produces a useful result is the compilation of the complete package/model (in Visual Studio, it is the one called by the Dynamics 365 > Build models... menu).
I don't think the issue you describe is a known issue. At least I wasn't aware of it and I don't know of a fix for it. And no, I don't think there is something wrong with the code. If it compiles successfully with the "Build models..." compilation, it should be good to go.