| 2381 | } |
| 2382 | |
| 2383 | void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit) |
| 2384 | { |
| 2385 | BfAstNode* localNameNode = localVar->mNameNode; |
| 2386 | if ((localVar->mIsThis) && (mCurMethodInstance != NULL)) |
| 2387 | { |
| 2388 | localNameNode = mCurMethodInstance->mMethodDef->GetRefNode(); |
| 2389 | } |
| 2390 | |
| 2391 | if (localNameNode != NULL) |
| 2392 | { |
| 2393 | bool isOut = false; |
| 2394 | if (localVar->mResolvedType->IsRef()) |
| 2395 | { |
| 2396 | auto refType = (BfRefType*)localVar->mResolvedType; |
| 2397 | isOut = refType->mRefKind == BfRefType::RefKind_Out; |
| 2398 | } |
| 2399 | |
| 2400 | if ((localVar->mReadFromId == -1) || (isOut) || ((localVar->mIsThis) && (mCurTypeInstance->IsStruct()))) |
| 2401 | { |
| 2402 | if ((localVar->mAssignedKind != BfLocalVarAssignKind_Unconditional) & (localVar->IsParam())) |
| 2403 | TryLocalVariableInit(localVar); |
| 2404 | |
| 2405 | // We may skip processing of local methods, so we won't know if it bind to any of our local variables or not |
| 2406 | bool deferFullAnalysis = mCurMethodState->GetRootMethodState()->mLocalMethodCache.size() != 0; |
| 2407 | |
| 2408 | // We may have init blocks that we aren't processing here... |
| 2409 | if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsAutocompleteMethod) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)) |
| 2410 | deferFullAnalysis = true; |
| 2411 | |
| 2412 | //bool deferFullAnalysis = true; |
| 2413 | bool deferUsageWarning = deferFullAnalysis && (mCompiler->IsAutocomplete()) && |
| 2414 | (mCompiler->mResolvePassData->mAutoComplete->mResolveType != BfResolveType_GetFixits); |
| 2415 | |
| 2416 | if (((localVar->mAssignedKind != BfLocalVarAssignKind_Unconditional) || (localVar->mHadExitBeforeAssign)) && |
| 2417 | (!localVar->mIsImplicitParam)) |
| 2418 | { |
| 2419 | if (deferUsageWarning) |
| 2420 | { |
| 2421 | // Ignore |
| 2422 | } |
| 2423 | else if (localVar->mIsThis) |
| 2424 | { |
| 2425 | bool foundFields = false; |
| 2426 | |
| 2427 | auto checkTypeInstance = mCurTypeInstance; |
| 2428 | while (checkTypeInstance != NULL) |
| 2429 | { |
| 2430 | for (auto& fieldInstance : checkTypeInstance->mFieldInstances) |
| 2431 | { |
| 2432 | if (fieldInstance.mMergedDataIdx == -1) |
| 2433 | continue; |
| 2434 | |
| 2435 | int checkMask = 1 << fieldInstance.mMergedDataIdx; |
| 2436 | if ((localVar->mUnassignedFieldFlags & checkMask) != 0) |
| 2437 | { |
| 2438 | auto fieldDef = fieldInstance.GetFieldDef(); |
| 2439 | |
| 2440 | if (mCurMethodInstance->mMethodDef->mDeclaringType->mIsPartial) |
nothing calls this directly
no test coverage detected