1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Start of anonymous 'using' field

This commit is contained in:
Brian Fiete 2022-02-19 07:38:05 -05:00
parent b886f3d3c3
commit 79e2ff5165
13 changed files with 859 additions and 498 deletions

View file

@ -992,7 +992,7 @@ public:
SizedArray(SizedArray&& val)
{
if (val.mVals == val.mInternalBuffer)
if (val.mVals == (T*)&val.mFirstVal)
{
this->mVals = (T*)&this->mFirstVal;
this->mSize = 0;

View file

@ -161,6 +161,11 @@ void BfStructuralVisitor::Visit(BfTokenPairNode* tokenPairNode)
Visit(tokenPairNode->ToBase());
}
void BfStructuralVisitor::Visit(BfUsingSpecifierNode* usingSpecifier)
{
Visit(usingSpecifier->ToBase());
}
void BfStructuralVisitor::Visit(BfLiteralExpression* literalExpr)
{
Visit(literalExpr->ToBase());

View file

@ -41,6 +41,7 @@ class BfSource;
class BfAstNode;
class BfTokenNode;
class BfTokenPairNode;
class BfUsingSpecifierNode;
class BfTypeReference;
class BfTypeDef;
class BfMethodDef;
@ -457,6 +458,7 @@ public:
virtual void Visit(BfEmptyStatement* emptyStmt);
virtual void Visit(BfTokenNode* tokenNode);
virtual void Visit(BfTokenPairNode* tokenPairNode);
virtual void Visit(BfUsingSpecifierNode* usingSpecifier);
virtual void Visit(BfLiteralExpression* literalExpr);
virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression);
virtual void Visit(BfIdentifierNode* identifierNode);
@ -3076,6 +3078,15 @@ public:
BfFieldDtorDeclaration* mNextFieldDtor;
}; BF_AST_DECL(BfFieldDtorDeclaration, BfAstNode);
class BfUsingSpecifierNode : public BfAstNode
{
public:
BF_AST_TYPE(BfUsingSpecifierNode, BfAstNode);
BfAstNode* mProtection;
BfTokenNode* mUsingToken;
}; BF_AST_DECL(BfUsingSpecifierNode, BfAstNode);
class BfFieldDeclaration : public BfMemberDeclaration
{
public:
@ -3083,7 +3094,7 @@ public:
BfCommentNode* mDocumentation;
BfTokenNode* mPrecedingComma;
BfTokenNode* mConstSpecifier;
BfAstNode* mConstSpecifier; // Could be 'const' or 'using'
BfTokenNode* mVolatileSpecifier;
BfTokenNode* mNewSpecifier;
BfTokenNode* mExternSpecifier;

View file

@ -907,7 +907,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
wantsBody = false;
}
if (propertyDeclaration->mConstSpecifier != NULL)
if ((propertyDeclaration->mConstSpecifier != NULL) && (propertyDeclaration->mConstSpecifier->mToken == BfToken_Const))
{
Fail("Const properties are not allowed", propertyDeclaration->mConstSpecifier);
}
@ -920,6 +920,14 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration)
propertyDef->mProtection = GetProtection(propertyDeclaration->mProtectionSpecifier);
propertyDef->mIdx = (int)mCurTypeDef->mProperties.size() - 1;
propertyDef->mIsConst = false;
propertyDef->mIsProperty = true;
if (auto usingSpecifier = BfNodeDynCast<BfUsingSpecifierNode>(propertyDeclaration->mConstSpecifier))
{
if (usingSpecifier->mProtection != NULL)
propertyDef->mUsingProtection = GetProtection(usingSpecifier->mProtection);
else
propertyDef->mUsingProtection = propertyDef->mProtection;
}
propertyDef->mIsStatic = propertyDeclaration->mStaticSpecifier != NULL;
propertyDef->mIsReadOnly = propertyDeclaration->mReadOnlySpecifier != NULL;
if (propertyDeclaration->mNameNode != NULL)
@ -1149,13 +1157,25 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration)
fieldDef->mIsReadOnly = fieldDeclaration->mReadOnlySpecifier != NULL;
fieldDef->mIsInline = (fieldDeclaration->mReadOnlySpecifier != NULL) && (fieldDeclaration->mReadOnlySpecifier->GetToken() == BfToken_Inline);
fieldDef->mIsExtern = (fieldDeclaration->mExternSpecifier != NULL);
fieldDef->mIsConst = (fieldDeclaration->mConstSpecifier != NULL) || (isEnumEntryDecl);
auto constSpecifierToken = BfNodeDynCast<BfTokenNode>(fieldDeclaration->mConstSpecifier);
fieldDef->mIsConst = ((constSpecifierToken != NULL) && (constSpecifierToken->mToken == BfToken_Const)) || (isEnumEntryDecl);
if (auto usingSpecifier = BfNodeDynCast<BfUsingSpecifierNode>(fieldDeclaration->mConstSpecifier))
{
if (usingSpecifier->mProtection != NULL)
fieldDef->mUsingProtection = GetProtection(usingSpecifier->mProtection);
else
fieldDef->mUsingProtection = fieldDef->mProtection;
}
fieldDef->mIsStatic = (fieldDeclaration->mStaticSpecifier != NULL) || fieldDef->mIsConst;
fieldDef->mIsVolatile = (fieldDeclaration->mVolatileSpecifier != NULL);
fieldDef->mTypeRef = fieldDeclaration->mTypeRef;
if (auto varType = BfNodeDynCast<BfLetTypeReference>(fieldDef->mTypeRef))
fieldDef->mIsReadOnly = true;
if (fieldDef->mUsingProtection != BfProtection_Hidden)
mCurTypeDef->mHasUsingFields = true;
if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (fieldDef->mTypeRef != NULL) && (!fieldDef->mIsStatic))
{
// This check is a bit of a hack to determine the difference between a "MemberType mMember" and a proper case entry of "mMember(TupleType)"

View file

@ -203,6 +203,14 @@ void BfElementVisitor::Visit(BfTokenPairNode* tokenPairNode)
VisitChild(tokenPairNode->mRight);
}
void BfElementVisitor::Visit(BfUsingSpecifierNode* usingSpecifier)
{
Visit(usingSpecifier->ToBase());
VisitChild(usingSpecifier->mProtection);
VisitChild(usingSpecifier->mUsingToken);
}
void BfElementVisitor::Visit(BfLiteralExpression* literalExpr)
{
Visit(literalExpr->ToBase());

View file

@ -36,6 +36,7 @@ public:
virtual void Visit(BfEmptyStatement* emptyStmt);
virtual void Visit(BfTokenNode* tokenNode);
virtual void Visit(BfTokenPairNode* tokenPairNode);
virtual void Visit(BfUsingSpecifierNode* usingSpecifier);
virtual void Visit(BfLiteralExpression* literalExpr);
virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression);
virtual void Visit(BfIdentifierNode* identifierNode);

File diff suppressed because it is too large Load diff

View file

@ -362,7 +362,9 @@ enum BfLookupFieldFlags
BfLookupFieldFlag_BaseLookup = 2,
BfLookupFieldFlag_CheckingOuter = 4,
BfLookupFieldFlag_IgnoreProtection = 8,
BfLookupFieldFlag_BindOnly = 0x10
BfLookupFieldFlag_BindOnly = 0x10,
BfLookupFieldFlag_IsFailurePass = 0x20,
BfLookupFieldFlag_IsAnonymous = 0x40
};
enum BfUnaryOpFlags
@ -449,6 +451,8 @@ public:
bool CheckIsBase(BfAstNode* checkNode);
bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false, bool emitWarning = false, bool skipCopyOnMutate = false);
bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc);
BfTypedValue LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInline);
BfTypedValue LoadField(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfFieldDef* fieldDef, BfLookupFieldFlags flags);
BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None);
void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode);
void LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError = false, bool* hadError = NULL);

View file

@ -4658,6 +4658,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
auto resolvedFieldType = fieldInstance->GetResolvedType();
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
{
if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsStruct()) && (!resolvedFieldType->IsObject()))
Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->mFieldDeclaration->mConstSpecifier);
if (fieldInstance->mIsEnumPayloadCase)
{
PopulateType(resolvedFieldType, BfPopulateType_Data);

View file

@ -6287,6 +6287,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
case BfToken_Explicit:
case BfToken_ReadOnly:
case BfToken_Inline:
case BfToken_Using:
case BfToken_Volatile:
break;
default:
@ -6335,7 +6336,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
auto fieldDecl = BfNodeDynCast<BfFieldDeclaration>(memberDecl);
if (fieldDecl != NULL)
{
if ((fieldDecl->mStaticSpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL))
if ((fieldDecl->mStaticSpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const))
Fail("Cannot use 'static' and 'const' together", fieldDecl);
}
@ -6347,6 +6348,15 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
(token == BfToken_Private) ||
(token == BfToken_Internal))
{
if (auto fieldDecl = BfNodeDynCast<BfFieldDeclaration>(memberDecl))
{
if (auto usingSpecifier = BfNodeDynCastExact<BfUsingSpecifierNode>(fieldDecl->mConstSpecifier))
{
SetProtection(memberDecl, usingSpecifier->mProtection, tokenNode);
return memberDecl;
}
}
SetProtection(memberDecl, memberDecl->mProtectionSpecifier, tokenNode);
return memberDecl;
}
@ -6463,10 +6473,36 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
if (token == BfToken_Const)
{
if ((fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Using))
{
Fail("Const cannot be used with 'using' specified", tokenNode);
}
else if (fieldDecl->mConstSpecifier != NULL)
{
Fail("Const already specified", tokenNode);
}
MEMBER_SET(fieldDecl, mConstSpecifier, tokenNode);
handled = true;
}
// if (token == BfToken_Using)
// {
// if ((fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const))
// {
// Fail("Const cannot be used with 'using' specified", tokenNode);
// }
// else if (fieldDecl->mConstSpecifier != NULL)
// {
// Fail("Using already specified", tokenNode);
// }
//
// auto usingSpecifier = mAlloc->Alloc<BfUsingSpecifierNode>();
// ReplaceNode(tokenNode, usingSpecifier);
// MEMBER_SET(usingSpecifier, mUsingToken, tokenNode);
// MEMBER_SET(fieldDecl, mConstSpecifier, usingSpecifier);
// handled = true;
// }
if (token == BfToken_ReadOnly)
{
if (fieldDecl->mReadOnlySpecifier == NULL)
@ -6504,13 +6540,13 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
handled = true;
}
if ((fieldDecl->mStaticSpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL))
if ((fieldDecl->mStaticSpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const))
Fail("Cannot use 'static' and 'const' together", fieldDecl);
if ((fieldDecl->mReadOnlySpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL))
if ((fieldDecl->mReadOnlySpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const))
Fail("Cannot use 'readonly' and 'const' together", fieldDecl);
if ((fieldDecl->mVolatileSpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL))
if ((fieldDecl->mVolatileSpecifier != NULL) && (fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const))
Fail("Cannot use 'volatile' and 'const' together", fieldDecl);
if (handled)

View file

@ -744,6 +744,13 @@ void BfTypeDef::PopulateMemberSets()
fieldDef->mNextWithSameName = (BfFieldDef*)entry->mMemberDef;
entry->mMemberDef = fieldDef;
}
if (fieldDef->mUsingProtection != BfProtection_Hidden)
{
if (mUsingFieldData == NULL)
mUsingFieldData = new BfUsingFieldData();
mUsingFieldData->mUsingFields.Add(fieldDef);
}
}
while (mPropertySet.mSourceSize < mProperties.mSize)
@ -757,6 +764,13 @@ void BfTypeDef::PopulateMemberSets()
propDef->mNextWithSameName = (BfPropertyDef*)entry->mMemberDef;
entry->mMemberDef = propDef;
}
if (propDef->mUsingProtection != BfProtection_Hidden)
{
if (mUsingFieldData == NULL)
mUsingFieldData = new BfUsingFieldData();
mUsingFieldData->mUsingFields.Add(propDef);
}
}
}
@ -769,6 +783,8 @@ void BfTypeDef::ClearMemberSets()
for (auto entry : mFieldSet)
((BfFieldDef*)entry.mMemberDef)->mNextWithSameName = NULL;
mFieldSet.Clear();
delete mUsingFieldData;
mUsingFieldData = NULL;
for (auto entry : mPropertySet)
((BfPropertyDef*)entry.mMemberDef)->mNextWithSameName = NULL;
@ -787,6 +803,7 @@ BfTypeDef::~BfTypeDef()
mSource->mRefCount--;
BF_ASSERT(mSource->mRefCount >= 0);
}
delete mUsingFieldData;
}
BfSource* BfTypeDef::GetLastSource()
@ -2899,6 +2916,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
typeDef->mHasCtorNoBody = nextTypeDef->mHasCtorNoBody;
typeDef->mHasOverrideMethods = nextTypeDef->mHasOverrideMethods;
typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods;
typeDef->mHasUsingFields = nextTypeDef->mHasUsingFields;
typeDef->mIsOpaque = nextTypeDef->mIsOpaque;
typeDef->mDupDetectedRevision = nextTypeDef->mDupDetectedRevision;
@ -2950,6 +2968,8 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
typeDef->mPartials = nextTypeDef->mPartials;
typeDef->mMethodSet.Clear();
typeDef->mFieldSet.Clear();
delete typeDef->mUsingFieldData;
typeDef->mUsingFieldData = NULL;
typeDef->mPropertySet.Clear();
delete nextTypeDef;
@ -3003,6 +3023,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
typeDef->mHasAppendCtor = partialTypeDef->mHasAppendCtor;
typeDef->mHasCtorNoBody = partialTypeDef->mHasCtorNoBody;
typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods;
typeDef->mHasUsingFields = partialTypeDef->mHasUsingFields;
typeDef->mHasOverrideMethods = partialTypeDef->mHasOverrideMethods;
typeDef->mIsAlwaysInclude = partialTypeDef->mIsAlwaysInclude;
typeDef->mHasCEOnCompile = partialTypeDef->mHasCEOnCompile;
@ -3042,6 +3063,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor;
typeDef->mHasCEOnCompile |= partialTypeDef->mHasCEOnCompile;
typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods;
typeDef->mHasUsingFields |= partialTypeDef->mHasUsingFields;
typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods;
typeDef->mProtection = BF_MIN(typeDef->mProtection, partialTypeDef->mProtection);
@ -3062,6 +3084,8 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
typeDef->mFields.push_back(newField);
}
typeDef->mFieldSet.Clear();
delete typeDef->mUsingFieldData;
typeDef->mUsingFieldData = NULL;
bool hadNoDeclMethod = false;
int startMethodIdx = (int)typeDef->mMethods.size();
@ -3413,6 +3437,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef)
typeDef->mHasCtorNoBody = fromTypeDef->mHasCtorNoBody;
typeDef->mHasOverrideMethods = fromTypeDef->mHasOverrideMethods;
typeDef->mHasExtensionMethods = fromTypeDef->mHasExtensionMethods;
typeDef->mHasUsingFields = fromTypeDef->mHasUsingFields;
typeDef->mIsOpaque = fromTypeDef->mIsOpaque;
typeDef->mDupDetectedRevision = fromTypeDef->mDupDetectedRevision;

View file

@ -564,9 +564,11 @@ class BfFieldDef : public BfMemberDef
public:
int mIdx;
bool mIsConst; // Note: Consts are also all considered Static
BfProtection mUsingProtection;
bool mIsInline;
bool mIsVolatile;
bool mIsExtern;
bool mIsProperty;
BfTypeReference* mTypeRef;
BfExpression* mInitializer;
BfFieldDeclaration* mFieldDeclaration;
@ -579,9 +581,11 @@ public:
{
mIdx = 0;
mIsConst = false;
mUsingProtection = BfProtection_Hidden;
mIsInline = false;
mIsExtern = false;
mIsVolatile = false;
mIsProperty = false;
mTypeRef = NULL;
mInitializer = NULL;
mFieldDeclaration = NULL;
@ -965,6 +969,38 @@ public:
}
};
class BfUsingFieldData
{
public:
struct FieldRef
{
BfTypeInstance* mTypeInstance;
BfFieldDef* mFieldDef;
FieldRef()
{
mTypeInstance = NULL;
mFieldDef = NULL;
}
FieldRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef)
{
mTypeInstance = typeInst;
mFieldDef = fieldDef;
}
};
struct Entry
{
Array<FieldRef> mConflicts;
SizedArray<FieldRef, 1> mLookup;
};
public:
Array<BfFieldDef*> mUsingFields;
Dictionary<String, Entry> mEntries;
};
// For partial classes, the first entry in the map will contain the combined data
class BfTypeDef
{
@ -1008,6 +1044,7 @@ public:
Array<BfTypeReference*> mStaticSearch;
Array<BfTypeReference*> mInternalAccessSet;
Array<BfFieldDef*> mFields;
BfUsingFieldData* mUsingFieldData; // Created during mFieldSet
Array<BfPropertyDef*> mProperties;
Array<BfMethodDef*> mMethods;
BfTypeDefMemberSet mMethodSet;
@ -1042,6 +1079,7 @@ public:
bool mHasCtorNoBody;
bool mHasExtensionMethods;
bool mHasOverrideMethods;
bool mHasUsingFields;
bool mIsOpaque;
bool mIsNextRevision;
bool mInDeleteQueue;
@ -1082,6 +1120,7 @@ public:
mHasCtorNoBody = false;
mHasExtensionMethods = false;
mHasOverrideMethods = false;
mHasUsingFields = false;
mIsOpaque = false;
mPartialUsed = false;
mIsNextRevision = false;
@ -1094,6 +1133,7 @@ public:
mTypeDeclaration = NULL;
mNextRevision = NULL;
mProtection = BfProtection_Public;
mUsingFieldData = NULL;
}
BfSource* GetLastSource();