| 1397 | } |
| 1398 | |
| 1399 | ResultType Object::DefineProp(ResultToken &aResultToken, int aID, int aFlags, ExprTokenType *aParam[], int aParamCount) |
| 1400 | { |
| 1401 | auto name = ParamIndexToString(0, _f_number_buf); |
| 1402 | if (!*name) |
| 1403 | _o_throw_param(0); |
| 1404 | ExprTokenType getter, setter, method, value; |
| 1405 | getter.symbol = SYM_INVALID; |
| 1406 | setter.symbol = SYM_INVALID; |
| 1407 | method.symbol = SYM_INVALID; |
| 1408 | value.symbol = SYM_INVALID; |
| 1409 | auto desc = dynamic_cast<Object *>(ParamIndexToObject(1)); |
| 1410 | if (!desc // Must be an Object. |
| 1411 | || desc->GetOwnProp(getter, _T("Get")) && getter.symbol != SYM_OBJECT // If defined, must be an object. |
| 1412 | || desc->GetOwnProp(setter, _T("Set")) && setter.symbol != SYM_OBJECT |
| 1413 | || desc->GetOwnProp(method, _T("Call")) && method.symbol != SYM_OBJECT |
| 1414 | || desc->GetOwnProp(value, _T("Value")) && (getter.symbol != SYM_INVALID || setter.symbol != SYM_INVALID || method.symbol != SYM_INVALID) |
| 1415 | // To help prevent errors, throw if none of the above properties were present. This also serves to |
| 1416 | // reserve some cases for possible future use, such as passing a function object to imply {get:...}. |
| 1417 | || getter.symbol == SYM_INVALID && setter.symbol == SYM_INVALID && method.symbol == SYM_INVALID && value.symbol == SYM_INVALID) |
| 1418 | _o_throw_param(1); |
| 1419 | if (value.symbol != SYM_INVALID) // Above already verified that neither Get nor Set was present. |
| 1420 | { |
| 1421 | if (!SetOwnProp(name, value)) |
| 1422 | _o_throw_oom; |
| 1423 | AddRef(); |
| 1424 | _o_return(this); |
| 1425 | } |
| 1426 | auto prop = DefineProperty(name); |
| 1427 | if (!prop) |
| 1428 | _o_throw_oom; |
| 1429 | if (getter.symbol == SYM_OBJECT) prop->SetGetter(getter.object); |
| 1430 | if (setter.symbol == SYM_OBJECT) prop->SetSetter(setter.object); |
| 1431 | if (method.symbol == SYM_OBJECT) prop->SetMethod(method.object); |
| 1432 | prop->MaxParams = -1; |
| 1433 | if (auto obj = prop->Getter()) |
| 1434 | { |
| 1435 | int max_params; |
| 1436 | switch (GetObjMaxParams(obj, max_params, aResultToken)) |
| 1437 | { |
| 1438 | case FAIL: |
| 1439 | case EARLY_EXIT: |
| 1440 | return aResultToken.Result(); |
| 1441 | case OK: |
| 1442 | prop->MaxParams = max_params - 1; |
| 1443 | } |
| 1444 | } |
| 1445 | if (auto obj = prop->Setter()) |
| 1446 | { |
| 1447 | int max_params; |
| 1448 | switch (GetObjMaxParams(obj, max_params, aResultToken)) |
| 1449 | { |
| 1450 | case FAIL: |
| 1451 | case EARLY_EXIT: |
| 1452 | return aResultToken.Result(); |
| 1453 | case OK: |
| 1454 | if (prop->MaxParams < max_params - 2) |
| 1455 | prop->MaxParams = max_params - 2; |
| 1456 | } |
nothing calls this directly
no test coverage detected