mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Merge pull request #2188 from Fusioon/impl-1889
Add fixit to generate missing switch cases
This commit is contained in:
commit
2d2313a9b1
1 changed files with 105 additions and 10 deletions
|
@ -5184,6 +5184,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
for (auto& field : enumType->mFieldInstances)
|
for (auto& field : enumType->mFieldInstances)
|
||||||
{
|
{
|
||||||
auto fieldDef = field.GetFieldDef();
|
auto fieldDef = field.GetFieldDef();
|
||||||
|
|
||||||
if (fieldDef == NULL)
|
if (fieldDef == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (!fieldDef->IsEnumCaseEntry())
|
if (!fieldDef->IsEnumCaseEntry())
|
||||||
|
@ -5212,23 +5213,117 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
|
|
||||||
if (!isComprehensive)
|
if (!isComprehensive)
|
||||||
{
|
{
|
||||||
BfAstNode* refNode = switchStmt->mSwitchToken;
|
|
||||||
Fail("Switch must be exhaustive, consider adding a default clause", switchStmt->mSwitchToken);
|
Fail("Switch must be exhaustive, consider adding a default clause", switchStmt->mSwitchToken);
|
||||||
if ((switchStmt->mCloseBrace) && (mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->CheckFixit((refNode))))
|
|
||||||
{
|
|
||||||
BfParserData* parser = refNode->GetSourceData()->ToParserData();
|
|
||||||
if (parser != NULL)
|
|
||||||
{
|
|
||||||
int fileLoc = switchStmt->mCloseBrace->GetSrcStart();
|
|
||||||
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("default:\tdefault:|%s|%d||default:", parser->mFileName.c_str(), fileLoc).c_str()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
isComprehensive = false;
|
isComprehensive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfAstNode* refNode = switchStmt->mSwitchToken;
|
||||||
|
if ((switchStmt->mCloseBrace) && (mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->CheckFixit((switchStmt->mSwitchToken))))
|
||||||
|
{
|
||||||
|
BfParserData* parser = refNode->GetSourceData()->ToParserData();
|
||||||
|
if (parser != NULL)
|
||||||
|
{
|
||||||
|
if (switchStmt->mDefaultCase == NULL)
|
||||||
|
{
|
||||||
|
int fileLoc = switchStmt->mCloseBrace->GetSrcStart();
|
||||||
|
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Add default case\tdefault:|%s|%d||default:", parser->mFileName.c_str(), fileLoc).c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((switchValue.mType->IsEnum()) && (!isComprehensive) || (switchStmt->mDefaultCase != NULL))
|
||||||
|
{
|
||||||
|
int fileLoc;
|
||||||
|
|
||||||
|
if ((handledCases.IsEmpty()) && (switchStmt->mOpenBrace != NULL))
|
||||||
|
fileLoc = switchStmt->mOpenBrace->GetSrcEnd() + 1;
|
||||||
|
else if (switchStmt->mDefaultCase != NULL)
|
||||||
|
fileLoc = switchStmt->mDefaultCase->GetSrcStart();
|
||||||
|
else
|
||||||
|
fileLoc = switchStmt->mCloseBrace->GetSrcStart();
|
||||||
|
|
||||||
|
String explicitInsertStr;
|
||||||
|
|
||||||
|
auto enumType = switchValue.mType->ToTypeInstance();
|
||||||
|
HashSet<int64> missingValues;
|
||||||
|
|
||||||
|
if (enumType->IsPayloadEnum())
|
||||||
|
{
|
||||||
|
for (auto& field : enumType->mFieldInstances)
|
||||||
|
{
|
||||||
|
auto fieldDef = field.GetFieldDef();
|
||||||
|
if (fieldDef == NULL)
|
||||||
|
continue;
|
||||||
|
if (!fieldDef->IsEnumCaseEntry())
|
||||||
|
continue;
|
||||||
|
if ((field.mDataIdx < 0))
|
||||||
|
{
|
||||||
|
auto key = -field.mDataIdx - 1;
|
||||||
|
if ((!handledCases.ContainsKey(key)) && (missingValues.Add(key)))
|
||||||
|
{
|
||||||
|
auto paramDecl = fieldDef->mTypeRef;
|
||||||
|
|
||||||
|
if ((field.mIsEnumPayloadCase) && (field.mResolvedType->IsTuple()))
|
||||||
|
{
|
||||||
|
auto payloadType = (BfTypeInstance*)field.mResolvedType;
|
||||||
|
if (!payloadType->mFieldInstances.empty())
|
||||||
|
{
|
||||||
|
String fieldsStr;
|
||||||
|
int count = 0;
|
||||||
|
for (auto& payloadField : payloadType->mFieldInstances)
|
||||||
|
{
|
||||||
|
auto payloadFieldDef = payloadField.GetFieldDef();
|
||||||
|
if (payloadFieldDef == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String fieldName = payloadFieldDef->mName;
|
||||||
|
if ((fieldName.IsEmpty()) || (fieldName.length() > 0) && (isdigit(fieldName[0])))
|
||||||
|
fieldName = StrFormat("p%d", count);
|
||||||
|
if (count > 0)
|
||||||
|
fieldsStr += ", ";
|
||||||
|
fieldsStr += StrFormat("let %s", fieldName.c_str());
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fieldsStr.IsEmpty())
|
||||||
|
{
|
||||||
|
explicitInsertStr += StrFormat("|case .%s(%s):", fieldDef->mName.c_str(), fieldsStr.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
explicitInsertStr += StrFormat("|case .%s:", fieldDef->mName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto& field : enumType->mFieldInstances)
|
||||||
|
{
|
||||||
|
auto fieldDef = field.GetFieldDef();
|
||||||
|
if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()))
|
||||||
|
{
|
||||||
|
if (field.mConstIdx != -1)
|
||||||
|
{
|
||||||
|
auto constant = enumType->mConstHolder->GetConstantById(field.mConstIdx);
|
||||||
|
if ((!handledCases.ContainsKey(constant->mInt64)) && (missingValues.Add(constant->mInt64)))
|
||||||
|
{
|
||||||
|
explicitInsertStr += StrFormat("|case .%s:", fieldDef->mName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingValues.GetCount() > 0)
|
||||||
|
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Add missing cases\tdefault:|%s|%d|%s", parser->mFileName.c_str(), fileLoc, explicitInsertStr.c_str()).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!hadConstMatch)
|
if (!hadConstMatch)
|
||||||
mBfIRBuilder->CreateBr(defaultBlock);
|
mBfIRBuilder->CreateBr(defaultBlock);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue