| 4489 | } |
| 4490 | |
| 4491 | BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfFieldDef* field) |
| 4492 | { |
| 4493 | bool isDeclType = (field->mFieldDeclaration != NULL) && BfNodeDynCastExact<BfExprModTypeRef>(field->mTypeRef) != NULL; |
| 4494 | |
| 4495 | auto fieldType = fieldInstance->GetResolvedType(); |
| 4496 | if ((field->mIsConst) && (!isDeclType)) |
| 4497 | { |
| 4498 | ResolveConstField(typeInstance, fieldInstance, field); |
| 4499 | return fieldInstance->GetResolvedType(); |
| 4500 | } |
| 4501 | |
| 4502 | bool staticOnly = (field->mIsStatic) && (!isDeclType); |
| 4503 | |
| 4504 | if (!fieldInstance->mIsInferredType) |
| 4505 | return fieldType; |
| 4506 | if ((!fieldType->IsVar()) && (!fieldType->IsUndefSizedArray())) |
| 4507 | return fieldType; |
| 4508 | |
| 4509 | SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance); |
| 4510 | |
| 4511 | BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); |
| 4512 | SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState, mContext->mCurTypeState->mType != typeInstance); |
| 4513 | |
| 4514 | auto typeDef = typeInstance->mTypeDef; |
| 4515 | |
| 4516 | if ((!field->mIsStatic) && (typeDef->mIsStatic)) |
| 4517 | { |
| 4518 | AssertErrorState(); |
| 4519 | return fieldType; |
| 4520 | } |
| 4521 | |
| 4522 | bool hadInferenceCycle = false; |
| 4523 | if (mContext->mFieldResolveReentrys.size() > 1) |
| 4524 | { |
| 4525 | if (mContext->mFieldResolveReentrys.IndexOf(fieldInstance, 1) != -1) |
| 4526 | { |
| 4527 | for (int i = 1; i < (int)mContext->mFieldResolveReentrys.size(); i++) |
| 4528 | { |
| 4529 | auto fieldInst = mContext->mFieldResolveReentrys[i]; |
| 4530 | auto fieldDef = fieldInst->GetFieldDef(); |
| 4531 | auto fieldOwner = fieldInst->mOwner; |
| 4532 | |
| 4533 | auto fieldModule = fieldOwner->mModule; |
| 4534 | SetAndRestoreValue<bool> prevIgnoreError(fieldModule->mIgnoreErrors, false); |
| 4535 | fieldModule->Fail(StrFormat("Field '%s.%s' creates a type inference cycle", TypeToString(fieldOwner).c_str(), fieldDef->mName.c_str()), fieldDef->mTypeRef, true); |
| 4536 | } |
| 4537 | |
| 4538 | return fieldType; |
| 4539 | } |
| 4540 | } |
| 4541 | mContext->mFieldResolveReentrys.push_back(fieldInstance); |
| 4542 | |
| 4543 | AutoPopBack<decltype (mContext->mFieldResolveReentrys)> popTypeResolveReentry(&mContext->mFieldResolveReentrys); |
| 4544 | SetAndRestoreValue<bool> prevResolvingVar(typeInstance->mResolvingVarField, true); |
| 4545 | SetAndRestoreValue<bool> prevCtxResolvingVar(mContext->mResolvingVarField, true); |
| 4546 | |
| 4547 | if ((field->GetInitializer() == NULL) && (!isDeclType)) |
| 4548 | { |
no test coverage detected