mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 20:42:21 +02:00
Fixed constExprs with ints, hover for enum values, _ for enums
This commit is contained in:
parent
4087bf8e2a
commit
4dcd7f9c6a
21 changed files with 293 additions and 142 deletions
|
@ -1543,7 +1543,7 @@ const char* Beefy::BfGetOpName(BfBinaryOp binOp)
|
|||
case BfBinaryOp_Add: return "+";
|
||||
case BfBinaryOp_Subtract: return "-";
|
||||
case BfBinaryOp_Multiply: return "*";
|
||||
case BfBinaryOp_Divide: return "\\";
|
||||
case BfBinaryOp_Divide: return "/";
|
||||
case BfBinaryOp_Modulus: return "%";
|
||||
case BfBinaryOp_BitwiseAnd: return "&";
|
||||
case BfBinaryOp_BitwiseOr: return "|";
|
||||
|
|
|
@ -460,6 +460,9 @@ void BfAutoComplete::AddMethod(BfMethodDeclaration* methodDecl, const StringImpl
|
|||
|
||||
void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute)
|
||||
{
|
||||
if (typeDef->mTypeDeclaration == NULL)
|
||||
return;
|
||||
|
||||
StringT<64> name(typeDef->mName->ToString());
|
||||
if (name == "@")
|
||||
return;
|
||||
|
@ -576,6 +579,11 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo
|
|||
|
||||
auto activeTypeDef = mModule->GetActiveTypeDef();
|
||||
|
||||
if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum()))
|
||||
{
|
||||
AddEntry(AutoCompleteEntry("valuetype", "_"), filter);
|
||||
}
|
||||
|
||||
#define CHECK_STATIC(staticVal) ((staticVal && addStatic) || (!staticVal && addNonStatic))
|
||||
|
||||
mModule->PopulateType(typeInst, BfPopulateType_Data);
|
||||
|
@ -2178,13 +2186,41 @@ void BfAutoComplete::CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedT
|
|||
}
|
||||
}
|
||||
|
||||
if (mResolveType == BfResolveType_GetVarType)
|
||||
if (mResolveType == BfResolveType_GetResultString)
|
||||
{
|
||||
mVarTypeName = mModule->TypeToString(resolvedType);
|
||||
mResultString = ":";
|
||||
mResultString += mModule->TypeToString(resolvedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BfAutoComplete::CheckResult(BfAstNode* node, const BfTypedValue& typedValue)
|
||||
{
|
||||
if (mResolveType != BfResolveType_GetResultString)
|
||||
return;
|
||||
|
||||
if (!IsAutocompleteNode(node))
|
||||
return;
|
||||
|
||||
if (!typedValue.mValue.IsConst())
|
||||
return;
|
||||
|
||||
if (typedValue.mType->IsPointer())
|
||||
return;
|
||||
if (typedValue.mType->IsObject())
|
||||
return;
|
||||
|
||||
auto constant = mModule->mBfIRBuilder->GetConstant(typedValue.mValue);
|
||||
if (BfIRConstHolder::IsInt(constant->mTypeCode))
|
||||
{
|
||||
mResultString = StrFormat("%lld", constant->mInt64);
|
||||
}
|
||||
else if (BfIRConstHolder::IsFloat(constant->mTypeCode))
|
||||
{
|
||||
mResultString = StrFormat("%f", constant->mDouble);
|
||||
}
|
||||
}
|
||||
|
||||
void BfAutoComplete::CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl)
|
||||
{
|
||||
CheckLocalRef(identifierNode, varDecl);
|
||||
|
|
|
@ -170,7 +170,7 @@ public:
|
|||
MethodMatchInfo* mMethodMatchInfo;
|
||||
bool mIsCapturingMethodMatchInfo;
|
||||
String mDefaultSelection;
|
||||
String mVarTypeName;
|
||||
String mResultString;
|
||||
String mDocumentationEntryName;
|
||||
BfAstNode* mGetDefinitionNode;
|
||||
BfResolveType mResolveType;
|
||||
|
@ -238,6 +238,7 @@ public:
|
|||
void CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod);
|
||||
void CheckProperty(BfPropertyDeclaration* propertyDeclaration);
|
||||
void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef);
|
||||
void CheckResult(BfAstNode* node, const BfTypedValue& typedValue);
|
||||
void CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl);
|
||||
void CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl);
|
||||
void CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst);
|
||||
|
@ -246,6 +247,7 @@ public:
|
|||
bool CheckFixit(BfAstNode* node);
|
||||
|
||||
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom);
|
||||
|
||||
};
|
||||
|
||||
NS_BF_END
|
|
@ -3393,7 +3393,7 @@ void BfCompiler::VisitSourceExteriorNodes()
|
|||
|
||||
auto _CheckParser = [&](BfParser* parser)
|
||||
{
|
||||
if (parser->mNextRevision != NULL)
|
||||
while (parser->mNextRevision != NULL)
|
||||
parser = parser->mNextRevision;
|
||||
if (parser->mAwaitingDelete)
|
||||
return;
|
||||
|
@ -3819,19 +3819,34 @@ void BfCompiler::ProcessAutocompleteTempType()
|
|||
}
|
||||
}
|
||||
|
||||
if ((autoComplete->mIsGetDefinition) && (fieldDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(fieldDef->mFieldDeclaration->mNameNode)))
|
||||
if (((autoComplete->mIsGetDefinition) || (autoComplete->mResolveType == BfResolveType_GetResultString)) &&
|
||||
(fieldDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(fieldDef->mFieldDeclaration->mNameNode)))
|
||||
{
|
||||
for (int i = 0; i < (int)actualTypeDef->mFields.size(); i++)
|
||||
{
|
||||
auto actualFieldDef = actualTypeDef->mFields[i];
|
||||
if (actualFieldDef->mName == fieldDef->mName)
|
||||
{
|
||||
autoComplete->mDefType = actualTypeDef;
|
||||
autoComplete->mDefField = actualFieldDef;
|
||||
if (autoComplete->mIsGetDefinition)
|
||||
{
|
||||
autoComplete->mDefType = actualTypeDef;
|
||||
autoComplete->mDefField = actualFieldDef;
|
||||
|
||||
autoComplete->SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
|
||||
autoComplete->mInsertStartIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcStart();
|
||||
autoComplete->mInsertEndIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcEnd();
|
||||
autoComplete->SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode);
|
||||
autoComplete->mInsertStartIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcStart();
|
||||
autoComplete->mInsertEndIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcEnd();
|
||||
}
|
||||
else if (autoComplete->mResolveType == BfResolveType_GetResultString)
|
||||
{
|
||||
auto fieldInstance = &typeInst->mFieldInstances[actualFieldDef->mIdx];
|
||||
if (fieldInstance->mConstIdx != -1)
|
||||
{
|
||||
auto constant = typeInst->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
auto retVal = module->ConstantToCurrent(constant, typeInst->mConstHolder, typeInst);
|
||||
BfTypedValue typedValue = BfTypedValue(retVal, typeInst);
|
||||
autoComplete->CheckResult(fieldDef->GetRefNode(), typedValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3847,7 +3862,7 @@ void BfCompiler::ProcessAutocompleteTempType()
|
|||
{
|
||||
module->ResolveConstField(typeInst, NULL, fieldDef);
|
||||
}
|
||||
|
||||
|
||||
if (fieldDef->mInitializer == NULL)
|
||||
{
|
||||
if (BfNodeIsA<BfVarTypeReference>(fieldDef->mTypeRef))
|
||||
|
@ -6682,9 +6697,9 @@ void BfCompiler::GenerateAutocompleteInfo()
|
|||
if (autoComplete->mResolveType == BfResolveType_GetNavigationData)
|
||||
return; // Already handled
|
||||
|
||||
if (autoComplete->mResolveType == BfResolveType_GetVarType)
|
||||
if (autoComplete->mResolveType == BfResolveType_GetResultString)
|
||||
{
|
||||
autoCompleteResultString = autoComplete->mVarTypeName;
|
||||
autoCompleteResultString = autoComplete->mResultString;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2940,6 +2940,40 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
|||
}
|
||||
}
|
||||
|
||||
if ((mModule->mCurMethodInstance == NULL) && (mModule->mCurTypeInstance->IsEnum()))
|
||||
{
|
||||
if (findName == "_")
|
||||
{
|
||||
BfFieldDef* resolvingFieldDef = NULL;
|
||||
auto checkTypeState = mModule->mContext->mCurTypeState;
|
||||
while (checkTypeState != NULL)
|
||||
{
|
||||
if (checkTypeState->mCurFieldDef != NULL)
|
||||
{
|
||||
if (checkTypeState->mTypeInstance == mModule->mCurTypeInstance)
|
||||
resolvingFieldDef = checkTypeState->mCurFieldDef;
|
||||
}
|
||||
checkTypeState = checkTypeState->mPrevState;
|
||||
}
|
||||
|
||||
if ((resolvingFieldDef != NULL) && (resolvingFieldDef->mIdx > 0))
|
||||
{
|
||||
auto enumType = mModule->mCurTypeInstance;
|
||||
if (!enumType->mFieldInstances.IsEmpty())
|
||||
{
|
||||
auto fieldInstance = &mModule->mCurTypeInstance->mFieldInstances[resolvingFieldDef->mIdx - 1];
|
||||
if ((fieldInstance->mConstIdx != -1) &&
|
||||
(fieldInstance->mResolvedType == mModule->mCurTypeInstance))
|
||||
{
|
||||
auto foreignConst = enumType->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
auto retVal = mModule->ConstantToCurrent(foreignConst, enumType->mConstHolder, enumType);
|
||||
return BfTypedValue(retVal, enumType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BfTypedValue thisValue = mModule->GetThis();
|
||||
|
||||
bool forcedIFaceLookup = false;
|
||||
|
|
|
@ -3523,14 +3523,26 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
|||
else if (fieldDef->mIsConst)
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mTypeInstance = mCurTypeInstance;
|
||||
typeState.mCurTypeDef = fieldDef->mDeclaringType;
|
||||
typeState.mCurFieldDef = fieldDef;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
BfConstResolver constResolver(this);
|
||||
if (fieldType->IsVar())
|
||||
return constResolver.Resolve(initializer);
|
||||
else
|
||||
return constResolver.Resolve(initializer, fieldType);
|
||||
{
|
||||
BfConstResolveFlags resolveFlags = BfConstResolveFlag_None;
|
||||
if ((mCompiler->mResolvePassData != NULL) && (mCurTypeInstance->IsEnum()) && (fieldDef->IsEnumCaseEntry()) &&
|
||||
(mCompiler->mResolvePassData->mAutoCompleteTempTypes.Contains(fieldDef->mDeclaringType)))
|
||||
{
|
||||
// We avoid doing the cast here because the value we're typing may not be in the range of the current
|
||||
// auto-created underlying type and it will cause an 'error flash'. We defer errors until the full resolve for that purpose
|
||||
resolveFlags = BfConstResolveFlag_NoCast;
|
||||
}
|
||||
return constResolver.Resolve(initializer, fieldType, resolveFlags);
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldType->IsVar())
|
||||
|
|
|
@ -2964,18 +2964,40 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
}
|
||||
}
|
||||
|
||||
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
||||
///
|
||||
{
|
||||
auto fieldInstance = &fieldInstanceRef;
|
||||
if (!fieldInstance->mFieldIncluded)
|
||||
continue;
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
if (fieldDef == NULL)
|
||||
continue;
|
||||
if ((fieldInstance->mConstIdx == -1) && (fieldDef->mIsConst))
|
||||
{
|
||||
SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
|
||||
typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef);
|
||||
Dictionary<int64, BfFieldDef*> valueMap;
|
||||
|
||||
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
|
||||
{
|
||||
auto fieldInstance = &fieldInstanceRef;
|
||||
if (!fieldInstance->mFieldIncluded)
|
||||
continue;
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
if (fieldDef == NULL)
|
||||
continue;
|
||||
if ((fieldInstance->mConstIdx == -1) && (fieldDef->mIsConst))
|
||||
{
|
||||
SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
|
||||
typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef);
|
||||
|
||||
auto underlyingType = fieldInstance->mResolvedType->GetUnderlyingType();
|
||||
if ((fieldDef->IsEnumCaseEntry()) && (fieldInstance->mConstIdx != -1) && (underlyingType->IsIntegral()))
|
||||
{
|
||||
auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
BfFieldDef** fieldDefPtr;
|
||||
if (valueMap.TryAdd(foreignConst->mInt64, NULL, &fieldDefPtr))
|
||||
{
|
||||
*fieldDefPtr = fieldDef;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto error = Warn(0, StrFormat("Enum value '%lld' for field '%s' is not unique", foreignConst->mInt64, fieldDef->mName.c_str()), fieldDef->GetRefNode(), true);
|
||||
if (error != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(StrFormat("This value was previously used for field '%s'", (*fieldDefPtr)->mName.c_str()), (*fieldDefPtr)->GetRefNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8997,7 +9019,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
if (explicitCast)
|
||||
{
|
||||
// TypedPrimitive -> Primitive
|
||||
if ((typedVal.mType->IsTypedPrimitive()) && (toType->IsPrimitiveType()))
|
||||
if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsPrimitiveType()))
|
||||
{
|
||||
auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance();
|
||||
auto primTypedVal = BfTypedValue(typedVal.mValue, fromTypedPrimitiveType->mFieldInstances.back().mResolvedType, typedVal.IsAddr());
|
||||
|
@ -9006,7 +9028,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
}
|
||||
|
||||
// TypedPrimitive -> TypedPrimitive
|
||||
if ((typedVal.mType->IsTypedPrimitive()) && (toType->IsTypedPrimitive()))
|
||||
if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsTypedPrimitive()))
|
||||
{
|
||||
auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance();
|
||||
auto toTypedPrimitiveType = toType->ToTypeInstance();
|
||||
|
|
|
@ -20,7 +20,7 @@ enum BfResolveType
|
|||
BfResolveType_GetFixits,
|
||||
BfResolveType_GetTypeDefList,
|
||||
BfResolveType_GetTypeDefInto,
|
||||
BfResolveType_GetVarType,
|
||||
BfResolveType_GetResultString,
|
||||
};
|
||||
|
||||
class BfLocalVariable;
|
||||
|
|
|
@ -2198,7 +2198,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
else if (type->IsConstExprValue())
|
||||
{
|
||||
BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
|
||||
int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE;
|
||||
int hashVal = (constExprValueType->mValue.mInt32 << 17) ^ HASH_CONSTTYPE;
|
||||
int elemHash = Hash(constExprValueType->mType, ctx);
|
||||
hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
|
||||
return hashVal;
|
||||
|
@ -2897,8 +2897,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
|||
BfConstExprValueType* lhsConstExprValueType = (BfConstExprValueType*)lhs;
|
||||
BfConstExprValueType* rhsConstExprValueType = (BfConstExprValueType*)rhs;
|
||||
|
||||
return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) &&
|
||||
(lhsConstExprValueType->mValue.mTypeCode == rhsConstExprValueType->mValue.mTypeCode) &&
|
||||
return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) &&
|
||||
(lhsConstExprValueType->mValue.mInt64 == rhsConstExprValueType->mValue.mInt64);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1404,11 +1404,8 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
|||
{
|
||||
unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef));
|
||||
if (unresolvedType == NULL)
|
||||
unresolvedType = mContext->mBfObjectType; // Fake an object
|
||||
//resolvedType = ResolveGenericType(unresolvedType);
|
||||
resolvedType = unresolvedType;
|
||||
if (unresolvedType == NULL)
|
||||
resolvedType = mContext->mBfObjectType; // Fake an object
|
||||
unresolvedType = GetPrimitiveType(BfTypeCode_Var);
|
||||
resolvedType = unresolvedType;
|
||||
}
|
||||
|
||||
auto _CheckConst = [&]
|
||||
|
@ -1417,7 +1414,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
|||
{
|
||||
auto constant = mBfIRBuilder->GetConstant(initValue.mValue);
|
||||
|
||||
// NullPtr is standin for GlobalVar during autocomplete
|
||||
// NullPtr is stand-in for GlobalVar during autocomplete
|
||||
if ((constant->mConstType == BfConstType_GlobalVar) ||
|
||||
(constant->mTypeCode == BfTypeCode_NullPtr))
|
||||
{
|
||||
|
@ -3114,7 +3111,7 @@ void BfModule::VisitCodeBlock(BfBlock* block)
|
|||
if ((!autoComplete->mIsAutoComplete) ||
|
||||
(autoComplete->mResolveType == BfResolveType_GetCurrentLocation) ||
|
||||
(autoComplete->mResolveType == BfResolveType_GetFixits) ||
|
||||
(autoComplete->mResolveType == BfResolveType_GetVarType) ||
|
||||
(autoComplete->mResolveType == BfResolveType_GetResultString) ||
|
||||
(autoComplete->mResolveType == BfResolveType_GetSymbolInfo) ||
|
||||
(autoComplete->mResolveType == BfResolveType_ShowFileSymbolReferences))
|
||||
wantsAllLocalMethods = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue