mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Inline anonymous type declarations
This commit is contained in:
parent
f609062c2a
commit
958fc30310
20 changed files with 600 additions and 48 deletions
|
@ -236,6 +236,11 @@ void BfStructuralVisitor::Visit(BfTypeReference* typeRef)
|
||||||
Visit(typeRef->ToBase());
|
Visit(typeRef->ToBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfStructuralVisitor::Visit(BfInlineTypeReference* typeRef)
|
||||||
|
{
|
||||||
|
Visit(typeRef->ToBase());
|
||||||
|
}
|
||||||
|
|
||||||
void BfStructuralVisitor::Visit(BfNamedTypeReference* typeRef)
|
void BfStructuralVisitor::Visit(BfNamedTypeReference* typeRef)
|
||||||
{
|
{
|
||||||
Visit(typeRef->ToBase());
|
Visit(typeRef->ToBase());
|
||||||
|
@ -1233,14 +1238,21 @@ void BfBlock::SetSize(int wantSize)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool BfTypeDeclaration::IsAnonymous()
|
||||||
|
{
|
||||||
|
return (mAnonymousName != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool BfTypeReference::IsNamedTypeReference()
|
bool BfTypeReference::IsNamedTypeReference()
|
||||||
{
|
{
|
||||||
return IsA<BfNamedTypeReference>() || IsA<BfDirectStrTypeReference>();
|
return IsA<BfNamedTypeReference>() || IsA<BfDirectStrTypeReference>() || IsA<BfInlineTypeReference>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BfTypeReference::IsTypeDefTypeReference()
|
bool BfTypeReference::IsTypeDefTypeReference()
|
||||||
{
|
{
|
||||||
return IsA<BfNamedTypeReference>() || IsA<BfDirectStrTypeReference>() || IsA<BfDirectTypeDefReference>();
|
return IsA<BfNamedTypeReference>() || IsA<BfDirectStrTypeReference>() || IsA<BfInlineTypeReference>() || IsA<BfDirectTypeDefReference>();
|
||||||
}
|
}
|
||||||
|
|
||||||
String BfTypeReference::ToCleanAttributeString()
|
String BfTypeReference::ToCleanAttributeString()
|
||||||
|
@ -1657,6 +1669,11 @@ bool Beefy::BfTokenIsKeyword(BfToken token)
|
||||||
return (token >= BfToken_Abstract) && (token <= BfToken_Yield);
|
return (token >= BfToken_Abstract) && (token <= BfToken_Yield);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Beefy::BfTokenIsTypeDecl(BfToken token)
|
||||||
|
{
|
||||||
|
return (token == BfToken_Struct) || (token == BfToken_Class) || (token == BfToken_Interface) || (token == BfToken_Enum);
|
||||||
|
}
|
||||||
|
|
||||||
BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp)
|
BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp)
|
||||||
{
|
{
|
||||||
switch (assignmentOp)
|
switch (assignmentOp)
|
||||||
|
|
|
@ -381,6 +381,7 @@ class BfReturnStatement;
|
||||||
class BfYieldStatement;
|
class BfYieldStatement;
|
||||||
class BfUnaryOperatorExpression;
|
class BfUnaryOperatorExpression;
|
||||||
class BfBinaryOperatorExpression;
|
class BfBinaryOperatorExpression;
|
||||||
|
class BfInlineTypeReference;
|
||||||
class BfArrayTypeRef;
|
class BfArrayTypeRef;
|
||||||
class BfPointerTypeRef;
|
class BfPointerTypeRef;
|
||||||
class BfDotTypeReference;
|
class BfDotTypeReference;
|
||||||
|
@ -549,6 +550,7 @@ public:
|
||||||
virtual void Visit(BfInitializerExpression* collectionInitExpr);
|
virtual void Visit(BfInitializerExpression* collectionInitExpr);
|
||||||
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
|
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
|
||||||
virtual void Visit(BfTypeReference* typeRef);
|
virtual void Visit(BfTypeReference* typeRef);
|
||||||
|
virtual void Visit(BfInlineTypeReference* typeRef);
|
||||||
virtual void Visit(BfNamedTypeReference* typeRef);
|
virtual void Visit(BfNamedTypeReference* typeRef);
|
||||||
virtual void Visit(BfQualifiedTypeReference* qualifiedType);
|
virtual void Visit(BfQualifiedTypeReference* qualifiedType);
|
||||||
virtual void Visit(BfDotTypeReference* typeRef);
|
virtual void Visit(BfDotTypeReference* typeRef);
|
||||||
|
@ -2147,6 +2149,7 @@ public:
|
||||||
ASTREF(BfTokenNode*) mCtorCloseParen;
|
ASTREF(BfTokenNode*) mCtorCloseParen;
|
||||||
BfSizedArray<ASTREF(BfExpression*)> mArguments;
|
BfSizedArray<ASTREF(BfExpression*)> mArguments;
|
||||||
BfSizedArray<ASTREF(BfTokenNode*)> mCommas;
|
BfSizedArray<ASTREF(BfTokenNode*)> mCommas;
|
||||||
|
bool mIsMultiUse; // For anonymous types and also another use like a field decl
|
||||||
|
|
||||||
ASTREF(BfAttributeDirective*) mNextAttribute;
|
ASTREF(BfAttributeDirective*) mNextAttribute;
|
||||||
|
|
||||||
|
@ -2442,10 +2445,15 @@ public:
|
||||||
BfGenericParamsDeclaration* mGenericParams;
|
BfGenericParamsDeclaration* mGenericParams;
|
||||||
BfGenericConstraintsDeclaration* mGenericConstraintsDeclaration;
|
BfGenericConstraintsDeclaration* mGenericConstraintsDeclaration;
|
||||||
bool mIgnoreDeclaration;
|
bool mIgnoreDeclaration;
|
||||||
|
char* mAnonymousName;
|
||||||
|
|
||||||
BfTokenNode* mColonToken;
|
BfTokenNode* mColonToken;
|
||||||
BfSizedArray<ASTREF(BfTypeReference*)> mBaseClasses;
|
BfSizedArray<ASTREF(BfTypeReference*)> mBaseClasses;
|
||||||
BfSizedArray<ASTREF(BfAstNode*)> mBaseClassCommas;
|
BfSizedArray<ASTREF(BfAstNode*)> mBaseClassCommas;
|
||||||
|
BfSizedArray<BfTypeDeclaration*> mAnonymousTypes;
|
||||||
|
|
||||||
|
bool IsAnonymous();
|
||||||
|
|
||||||
}; BF_AST_DECL(BfTypeDeclaration, BfAstNode);
|
}; BF_AST_DECL(BfTypeDeclaration, BfAstNode);
|
||||||
|
|
||||||
class BfTypeAliasDeclaration : public BfTypeDeclaration
|
class BfTypeAliasDeclaration : public BfTypeDeclaration
|
||||||
|
@ -2468,6 +2476,14 @@ public:
|
||||||
String ToCleanAttributeString();
|
String ToCleanAttributeString();
|
||||||
}; BF_AST_DECL(BfTypeReference, BfAstNode);
|
}; BF_AST_DECL(BfTypeReference, BfAstNode);
|
||||||
|
|
||||||
|
class BfInlineTypeReference : public BfTypeReference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BF_AST_TYPE(BfInlineTypeReference, BfTypeReference);
|
||||||
|
|
||||||
|
BfTypeDeclaration* mTypeDeclaration;
|
||||||
|
}; BF_AST_DECL(BfInlineTypeReference, BfTypeReference);
|
||||||
|
|
||||||
class BfDirectTypeReference : public BfTypeReference
|
class BfDirectTypeReference : public BfTypeReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -3568,6 +3584,7 @@ public:
|
||||||
|
|
||||||
const char* BfTokenToString(BfToken token);
|
const char* BfTokenToString(BfToken token);
|
||||||
bool BfTokenIsKeyword(BfToken token);
|
bool BfTokenIsKeyword(BfToken token);
|
||||||
|
bool BfTokenIsTypeDecl(BfToken token);
|
||||||
BfBinaryOp BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp);
|
BfBinaryOp BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp);
|
||||||
BfBinaryOp BfGetOppositeBinaryOp(BfBinaryOp origOp);
|
BfBinaryOp BfGetOppositeBinaryOp(BfBinaryOp origOp);
|
||||||
BfBinaryOp BfGetFlippedBinaryOp(BfBinaryOp origOp);
|
BfBinaryOp BfGetFlippedBinaryOp(BfBinaryOp origOp);
|
||||||
|
|
|
@ -223,6 +223,7 @@ BfAutoComplete::BfAutoComplete(BfResolveType resolveType, bool doFuzzyAutoComple
|
||||||
BfAutoComplete::~BfAutoComplete()
|
BfAutoComplete::~BfAutoComplete()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
RemoveMethodMatchInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfAutoComplete::SetModule(BfModule* module)
|
void BfAutoComplete::SetModule(BfModule* module)
|
||||||
|
|
|
@ -795,8 +795,14 @@ void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef)
|
void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef, bool checkReturnType)
|
||||||
{
|
{
|
||||||
|
if (checkReturnType)
|
||||||
|
{
|
||||||
|
if (auto inlineTypeRef = BfNodeDynCast<BfInlineTypeReference>(methodDef->mReturnTypeRef))
|
||||||
|
ParseAttributes(inlineTypeRef->mTypeDeclaration->mAttributes, methodDef, false);
|
||||||
|
}
|
||||||
|
|
||||||
while (attributes != NULL)
|
while (attributes != NULL)
|
||||||
{
|
{
|
||||||
if (attributes->mAttributeTypeRef != NULL)
|
if (attributes->mAttributeTypeRef != NULL)
|
||||||
|
@ -1435,12 +1441,10 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
|
|
||||||
BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
|
BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
|
||||||
|
|
||||||
if ((typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mNameNode == NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*if (typeDeclaration->mNameNode != NULL)
|
/*if (typeDeclaration->mNameNode != NULL)
|
||||||
OutputDebugStrF("Decl: %s\n", typeDeclaration->mNameNode->ToString().c_str());*/
|
OutputDebugStrF("Decl: %s\n", typeDeclaration->mNameNode->ToString().c_str());*/
|
||||||
|
|
||||||
|
bool isAnonymous = typeDeclaration->IsAnonymous();
|
||||||
bool isAutoCompleteTempType = false;
|
bool isAutoCompleteTempType = false;
|
||||||
if (mResolvePassData != NULL)
|
if (mResolvePassData != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1511,10 +1515,17 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
}
|
}
|
||||||
if (typeDeclaration->mNameNode == NULL)
|
if (typeDeclaration->mNameNode == NULL)
|
||||||
{
|
{
|
||||||
// Global
|
if (typeDeclaration->mStaticSpecifier != NULL)
|
||||||
mCurTypeDef->mName = mSystem->mGlobalsAtom;
|
{
|
||||||
mCurTypeDef->mName->Ref();
|
// Global
|
||||||
BF_ASSERT(mCurTypeDef->mSystem != NULL);
|
mCurTypeDef->mName = mSystem->mGlobalsAtom;
|
||||||
|
mCurTypeDef->mName->Ref();
|
||||||
|
BF_ASSERT(mCurTypeDef->mSystem != NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCurTypeDef->mName = mSystem->GetAtom(typeDeclaration->mAnonymousName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1527,7 +1538,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
|
|
||||||
BfLogSys(mCurSource->mSystem, "DefBuilder %p %p TypeDecl:%s\n", mCurTypeDef, mCurSource, mCurTypeDef->mName->ToString().mPtr);
|
BfLogSys(mCurSource->mSystem, "DefBuilder %p %p TypeDecl:%s\n", mCurTypeDef, mCurSource, mCurTypeDef->mName->ToString().mPtr);
|
||||||
|
|
||||||
mCurTypeDef->mProtection = (outerTypeDef == NULL) ? BfProtection_Public : BfProtection_Private;
|
mCurTypeDef->mProtection = ((outerTypeDef == NULL) || (isAnonymous)) ? BfProtection_Public : BfProtection_Private;
|
||||||
if (typeDeclaration->mProtectionSpecifier != NULL)
|
if (typeDeclaration->mProtectionSpecifier != NULL)
|
||||||
{
|
{
|
||||||
if ((outerTypeDef == NULL) &&
|
if ((outerTypeDef == NULL) &&
|
||||||
|
@ -1956,6 +1967,11 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& anonTypeDecl : typeDeclaration->mAnonymousTypes)
|
||||||
|
{
|
||||||
|
VisitChildNoRef(anonTypeDecl);
|
||||||
|
}
|
||||||
|
|
||||||
FinishTypeDef(mCurTypeDef->mTypeCode == BfTypeCode_Enum);
|
FinishTypeDef(mCurTypeDef->mTypeCode == BfTypeCode_Enum);
|
||||||
|
|
||||||
// Map methods into the correct index from previous revision
|
// Map methods into the correct index from previous revision
|
||||||
|
|
|
@ -56,7 +56,7 @@ public:
|
||||||
static void AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName);
|
static void AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName);
|
||||||
BfTypeDef* ComparePrevTypeDef(BfTypeDef* prevTypeDef, BfTypeDef* checkTypeDef);
|
BfTypeDef* ComparePrevTypeDef(BfTypeDef* prevTypeDef, BfTypeDef* checkTypeDef);
|
||||||
void FinishTypeDef(bool wantsToString);
|
void FinishTypeDef(bool wantsToString);
|
||||||
void ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef);
|
void ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef, bool checkReturnType = true);
|
||||||
void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef);
|
void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef);
|
||||||
BfMethodDef* CreateMethodDef(BfMethodDeclaration* methodDecl, BfMethodDef* outerMethodDef = NULL);
|
BfMethodDef* CreateMethodDef(BfMethodDeclaration* methodDecl, BfMethodDef* outerMethodDef = NULL);
|
||||||
BfError* Fail(const StringImpl& errorStr, BfAstNode* refNode);
|
BfError* Fail(const StringImpl& errorStr, BfAstNode* refNode);
|
||||||
|
|
|
@ -325,6 +325,13 @@ void BfElementVisitor::Visit(BfTypeReference* typeRef)
|
||||||
Visit(typeRef->ToBase());
|
Visit(typeRef->ToBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfElementVisitor::Visit(BfInlineTypeReference* typeRef)
|
||||||
|
{
|
||||||
|
Visit(typeRef->ToBase());
|
||||||
|
|
||||||
|
VisitChild(typeRef->mTypeDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfNamedTypeReference* typeRef)
|
void BfElementVisitor::Visit(BfNamedTypeReference* typeRef)
|
||||||
{
|
{
|
||||||
Visit(typeRef->ToBase());
|
Visit(typeRef->ToBase());
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
virtual void Visit(BfInitializerExpression* initExpr);
|
virtual void Visit(BfInitializerExpression* initExpr);
|
||||||
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
|
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
|
||||||
virtual void Visit(BfTypeReference* typeRef);
|
virtual void Visit(BfTypeReference* typeRef);
|
||||||
|
virtual void Visit(BfInlineTypeReference* typeRef);
|
||||||
virtual void Visit(BfNamedTypeReference* typeRef);
|
virtual void Visit(BfNamedTypeReference* typeRef);
|
||||||
virtual void Visit(BfQualifiedTypeReference* qualifiedType);
|
virtual void Visit(BfQualifiedTypeReference* qualifiedType);
|
||||||
virtual void Visit(BfDotTypeReference* typeRef);
|
virtual void Visit(BfDotTypeReference* typeRef);
|
||||||
|
|
|
@ -2350,7 +2350,7 @@ bool BfModule::TryLocalVariableInit(BfLocalVariable* localVar)
|
||||||
void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
|
void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
|
||||||
{
|
{
|
||||||
BfAstNode* localNameNode = localVar->mNameNode;
|
BfAstNode* localNameNode = localVar->mNameNode;
|
||||||
if (localVar->mIsThis)
|
if ((localVar->mIsThis) && (mCurMethodInstance != NULL))
|
||||||
{
|
{
|
||||||
localNameNode = mCurMethodInstance->mMethodDef->GetRefNode();
|
localNameNode = mCurMethodInstance->mMethodDef->GetRefNode();
|
||||||
}
|
}
|
||||||
|
@ -12137,7 +12137,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
||||||
return mBfIRBuilder->CreateConst(constant, constHolder);
|
return mBfIRBuilder->CreateConst(constant, constHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget)
|
void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget, bool force)
|
||||||
{
|
{
|
||||||
if (attrTarget == BfAttributeTargets_SkipValidate)
|
if (attrTarget == BfAttributeTargets_SkipValidate)
|
||||||
return;
|
return;
|
||||||
|
@ -12149,6 +12149,9 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf
|
||||||
|
|
||||||
if ((customAttribute.mType->mAttributeData->mAttributeTargets & attrTarget) == 0)
|
if ((customAttribute.mType->mAttributeData->mAttributeTargets & attrTarget) == 0)
|
||||||
{
|
{
|
||||||
|
if ((customAttribute.mIsMultiUse) && (!force))
|
||||||
|
continue;
|
||||||
|
|
||||||
Fail(StrFormat("Attribute '%s' is not valid on this declaration type. It is only valid on %s.",
|
Fail(StrFormat("Attribute '%s' is not valid on this declaration type. It is only valid on %s.",
|
||||||
customAttribute.GetRefNode()->ToString().c_str(), GetAttributesTargetListString(customAttribute.mType->mAttributeData->mAttributeTargets).c_str()), customAttribute.mRef->mAttributeTypeRef); // CS0592
|
customAttribute.GetRefNode()->ToString().c_str(), GetAttributesTargetListString(customAttribute.mType->mAttributeData->mAttributeTargets).c_str()), customAttribute.mRef->mAttributeTypeRef); // CS0592
|
||||||
}
|
}
|
||||||
|
@ -12222,6 +12225,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
customAttribute.mAwaitingValidation = true;
|
customAttribute.mAwaitingValidation = true;
|
||||||
customAttribute.mDeclaringType = activeTypeDef;
|
customAttribute.mDeclaringType = activeTypeDef;
|
||||||
customAttribute.mRef = attributesDirective;
|
customAttribute.mRef = attributesDirective;
|
||||||
|
customAttribute.mIsMultiUse = attributesDirective->mIsMultiUse;
|
||||||
|
|
||||||
if (attributesDirective->mAttrOpenToken != NULL)
|
if (attributesDirective->mAttrOpenToken != NULL)
|
||||||
targetOverride = (BfAttributeTargets)0;
|
targetOverride = (BfAttributeTargets)0;
|
||||||
|
@ -23458,7 +23462,7 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance)
|
||||||
|
|
||||||
if ((methodInstance == methodInstance->mMethodInstanceGroup->mDefault) && (methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes != NULL))
|
if ((methodInstance == methodInstance->mMethodInstanceGroup->mDefault) && (methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes != NULL))
|
||||||
{
|
{
|
||||||
// Take over prevoiusly-generated custom attributes
|
// Take over previously-generated custom attributes
|
||||||
methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes;
|
methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes;
|
||||||
methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes = NULL;
|
methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes = NULL;
|
||||||
}
|
}
|
||||||
|
@ -23479,6 +23483,54 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (methodDeclaration != NULL)
|
||||||
|
{
|
||||||
|
if (auto inlineTypeRef = BfNodeDynCast<BfInlineTypeReference>(methodDeclaration->mReturnType))
|
||||||
|
{
|
||||||
|
if (inlineTypeRef->mTypeDeclaration->mAttributes != NULL)
|
||||||
|
{
|
||||||
|
// Apply multiuse attributes from anonymous return type
|
||||||
|
auto returnType = ResolveTypeRef(inlineTypeRef);
|
||||||
|
if ((returnType != NULL) && (returnType->ToTypeInstance()))
|
||||||
|
{
|
||||||
|
auto returnTypeInst = returnType->ToTypeInstance();
|
||||||
|
if ((returnTypeInst->IsAnonymous()) && (returnTypeInst->mCustomAttributes != NULL))
|
||||||
|
{
|
||||||
|
bool hasPendingAttributes = false;
|
||||||
|
for (const auto& customAttribute : returnTypeInst->mCustomAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
if (customAttribute.mAwaitingValidation)
|
||||||
|
{
|
||||||
|
hasPendingAttributes = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasPendingAttributes)
|
||||||
|
{
|
||||||
|
if (methodInstance->GetMethodInfoEx()->mMethodCustomAttributes == NULL)
|
||||||
|
methodInstance->mMethodInfoEx->mMethodCustomAttributes = new BfMethodCustomAttributes();
|
||||||
|
|
||||||
|
if (methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes == NULL)
|
||||||
|
methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = new BfCustomAttributes();
|
||||||
|
|
||||||
|
for (const auto& customAttribute : returnTypeInst->mCustomAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
if (!customAttribute.mAwaitingValidation)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BfCustomAttribute copiedCustomAttribute = customAttribute;
|
||||||
|
copiedCustomAttribute.mIsMultiUse = false;
|
||||||
|
methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->mAttributes.Add(copiedCustomAttribute);
|
||||||
|
}
|
||||||
|
ValidateCustomAttributes(methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes, attrTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
customAttributes = methodInstance->GetCustomAttributes();
|
customAttributes = methodInstance->GetCustomAttributes();
|
||||||
if (customAttributes == NULL)
|
if (customAttributes == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1676,7 +1676,7 @@ public:
|
||||||
bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder);
|
bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder);
|
||||||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false);
|
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false);
|
||||||
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget, bool force = false);
|
||||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL);
|
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL);
|
||||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL);
|
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL);
|
||||||
BfCustomAttributes* GetCustomAttributes(BfTypeDef* typeDef);
|
BfCustomAttributes* GetCustomAttributes(BfTypeDef* typeDef);
|
||||||
|
|
|
@ -5079,8 +5079,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
|
SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
|
||||||
|
|
||||||
fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->GetFieldDeclaration()->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
|
fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->GetFieldDeclaration()->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldInstance->mCustomAttributes != NULL)
|
||||||
|
{
|
||||||
for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
|
for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes)
|
||||||
{
|
{
|
||||||
if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
|
if (TypeToString(customAttr.mType) == "System.ThreadStaticAttribute")
|
||||||
|
@ -5094,6 +5097,38 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((fieldInstance->mResolvedType != NULL) && (fieldInstance->mResolvedType->IsTypeInstance()) && (fieldInstance->mResolvedType->ToTypeInstance()->IsAnonymous()))
|
||||||
|
{
|
||||||
|
auto fieldTypeInst = fieldInstance->mResolvedType->ToTypeInstance();
|
||||||
|
if ((fieldTypeInst->IsAnonymous()) && (fieldTypeInst->mCustomAttributes != NULL))
|
||||||
|
{
|
||||||
|
bool hasPendingAttributes = false;
|
||||||
|
for (const auto& customAttribute : fieldTypeInst->mCustomAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
if (customAttribute.mAwaitingValidation)
|
||||||
|
{
|
||||||
|
hasPendingAttributes = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasPendingAttributes)
|
||||||
|
{
|
||||||
|
fieldInstance->mCustomAttributes = new BfCustomAttributes();
|
||||||
|
for (const auto& customAttribute : fieldTypeInst->mCustomAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
if (!customAttribute.mAwaitingValidation)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BfCustomAttribute copiedCustomAttribute = customAttribute;
|
||||||
|
copiedCustomAttribute.mIsMultiUse = false;
|
||||||
|
fieldInstance->mCustomAttributes->mAttributes.Add(copiedCustomAttribute);
|
||||||
|
}
|
||||||
|
ValidateCustomAttributes(fieldInstance->mCustomAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (resolvedFieldType == NULL)
|
if (resolvedFieldType == NULL)
|
||||||
{
|
{
|
||||||
if ((underlyingType != NULL) || (typeInstance->IsPayloadEnum()))
|
if ((underlyingType != NULL) || (typeInstance->IsPayloadEnum()))
|
||||||
|
@ -8445,6 +8480,7 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu
|
||||||
BfNamedTypeReference* namedTypeRef = NULL;
|
BfNamedTypeReference* namedTypeRef = NULL;
|
||||||
BfGenericInstanceTypeRef* genericTypeRef = NULL;
|
BfGenericInstanceTypeRef* genericTypeRef = NULL;
|
||||||
BfDirectStrTypeReference* directStrTypeRef = NULL;
|
BfDirectStrTypeReference* directStrTypeRef = NULL;
|
||||||
|
BfInlineTypeReference* inlineTypeRef = NULL;
|
||||||
BfIdentifierNode* identifierNode = NULL;
|
BfIdentifierNode* identifierNode = NULL;
|
||||||
if ((namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef)))
|
if ((namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef)))
|
||||||
{
|
{
|
||||||
|
@ -8463,17 +8499,24 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
else if ((inlineTypeRef = BfNodeDynCastExact<BfInlineTypeReference>(typeRef)))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
BF_ASSERT((identifierNode != NULL) || (namedTypeRef != NULL) || (directStrTypeRef != NULL));
|
BF_ASSERT((identifierNode != NULL) || (namedTypeRef != NULL) || (directStrTypeRef != NULL) || (inlineTypeRef != NULL));
|
||||||
|
|
||||||
auto usedOuterType = outerType;
|
auto usedOuterType = outerType;
|
||||||
if (nestedTypeDef == NULL)
|
if (nestedTypeDef == NULL)
|
||||||
{
|
{
|
||||||
|
String tempStr;
|
||||||
StringView findName;
|
StringView findName;
|
||||||
if (namedTypeRef != NULL)
|
if (namedTypeRef != NULL)
|
||||||
findName = namedTypeRef->mNameNode->ToStringView();
|
findName = namedTypeRef->mNameNode->ToStringView();
|
||||||
else if (identifierNode != NULL)
|
else if (identifierNode != NULL)
|
||||||
findName = identifierNode->ToStringView();
|
findName = identifierNode->ToStringView();
|
||||||
|
else if (inlineTypeRef != NULL)
|
||||||
|
findName = inlineTypeRef->mTypeDeclaration->mAnonymousName;
|
||||||
else
|
else
|
||||||
findName = directStrTypeRef->mTypeName;
|
findName = directStrTypeRef->mTypeName;
|
||||||
|
|
||||||
|
@ -10468,7 +10511,7 @@ BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeI
|
||||||
if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
|
if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))
|
||||||
return FindTypeDef(elementedType->mElementType, typeInstanceOverride, error);
|
return FindTypeDef(elementedType->mElementType, typeInstanceOverride, error);
|
||||||
|
|
||||||
BF_ASSERT(typeRef->IsA<BfNamedTypeReference>() || typeRef->IsA<BfQualifiedTypeReference>() || typeRef->IsA<BfDirectStrTypeReference>());
|
BF_ASSERT(typeRef->IsA<BfNamedTypeReference>() || typeRef->IsA<BfQualifiedTypeReference>() || typeRef->IsA<BfDirectStrTypeReference>() || typeRef->IsA<BfInlineTypeReference>());
|
||||||
auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
|
auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef);
|
||||||
|
|
||||||
StringView findNameStr;
|
StringView findNameStr;
|
||||||
|
@ -10476,9 +10519,10 @@ BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeI
|
||||||
findNameStr = namedTypeRef->mNameNode->ToStringView();
|
findNameStr = namedTypeRef->mNameNode->ToStringView();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
|
if (auto directStrTypeDef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef))
|
||||||
if (directStrTypeDef != NULL)
|
|
||||||
findNameStr = directStrTypeDef->mTypeName;
|
findNameStr = directStrTypeDef->mTypeName;
|
||||||
|
else if (auto inlineTypeRef = BfNodeDynCastExact<BfInlineTypeReference>(typeRef))
|
||||||
|
findNameStr = inlineTypeRef->mTypeDeclaration->mAnonymousName;
|
||||||
else
|
else
|
||||||
BFMODULE_FATAL(this, "Error?");
|
BFMODULE_FATAL(this, "Error?");
|
||||||
}
|
}
|
||||||
|
@ -10989,13 +11033,16 @@ BfType* BfModule::ResolveTypeRef_Ref(BfTypeReference* typeRef, BfPopulateType po
|
||||||
// Check generics first
|
// Check generics first
|
||||||
auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef);
|
auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(typeRef);
|
||||||
auto directStrTypeRef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
|
auto directStrTypeRef = BfNodeDynCastExact<BfDirectStrTypeReference>(typeRef);
|
||||||
if (((namedTypeRef != NULL) && (namedTypeRef->mNameNode != NULL)) || (directStrTypeRef != NULL))
|
auto inlineStrTypeRef = BfNodeDynCastExact<BfInlineTypeReference>(typeRef);
|
||||||
|
if (((namedTypeRef != NULL) && (namedTypeRef->mNameNode != NULL)) || (directStrTypeRef != NULL) || (inlineStrTypeRef != NULL))
|
||||||
{
|
{
|
||||||
StringView findName;
|
StringView findName;
|
||||||
if (namedTypeRef != NULL)
|
if (namedTypeRef != NULL)
|
||||||
findName = namedTypeRef->mNameNode->ToStringView();
|
findName = namedTypeRef->mNameNode->ToStringView();
|
||||||
else
|
else if (directStrTypeRef != NULL)
|
||||||
findName = directStrTypeRef->mTypeName;
|
findName = directStrTypeRef->mTypeName;
|
||||||
|
else
|
||||||
|
findName = inlineStrTypeRef->mTypeDeclaration->mAnonymousName;
|
||||||
if (findName == "Self")
|
if (findName == "Self")
|
||||||
{
|
{
|
||||||
BfType* selfType = mCurTypeInstance;
|
BfType* selfType = mCurTypeInstance;
|
||||||
|
|
|
@ -105,6 +105,38 @@ return 0;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static CritSect gParseFileDataCrit;
|
||||||
|
static Array<int> gFreeIds;
|
||||||
|
static int gCurFreeId;
|
||||||
|
|
||||||
|
int BfParseFileData::GetUniqueId(int idx)
|
||||||
|
{
|
||||||
|
AutoCrit autoCrit(gParseFileDataCrit);
|
||||||
|
while (idx >= mUniqueIDList.size())
|
||||||
|
{
|
||||||
|
if (!gFreeIds.IsEmpty())
|
||||||
|
{
|
||||||
|
mUniqueIDList.Add(gFreeIds.back());
|
||||||
|
gFreeIds.pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mUniqueIDList.Add(gCurFreeId++);
|
||||||
|
}
|
||||||
|
return mUniqueIDList[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
BfParseFileData::~BfParseFileData()
|
||||||
|
{
|
||||||
|
if (!mUniqueIDList.IsEmpty())
|
||||||
|
{
|
||||||
|
AutoCrit autoCrit(gParseFileDataCrit);
|
||||||
|
for (auto id : mUniqueIDList)
|
||||||
|
gFreeIds.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BfParserCache* Beefy::gBfParserCache = NULL;
|
BfParserCache* Beefy::gBfParserCache = NULL;
|
||||||
|
|
||||||
bool BfParserCache::DataEntry::operator==(const LookupEntry& lookup) const
|
bool BfParserCache::DataEntry::operator==(const LookupEntry& lookup) const
|
||||||
|
@ -201,14 +233,39 @@ BfParserData::BfParserData()
|
||||||
mCharIdData = NULL;
|
mCharIdData = NULL;
|
||||||
mUniqueParser = NULL;
|
mUniqueParser = NULL;
|
||||||
mDidReduce = false;
|
mDidReduce = false;
|
||||||
|
mParseFileData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfParserData::~BfParserData()
|
BfParserData::~BfParserData()
|
||||||
{
|
{
|
||||||
|
if (mParseFileData != NULL)
|
||||||
|
{
|
||||||
|
BF_ASSERT(mParseFileData->mRefCount >= 0);
|
||||||
|
mParseFileData->mRefCount--;
|
||||||
|
if (mParseFileData->mRefCount == 0)
|
||||||
|
{
|
||||||
|
delete mParseFileData;
|
||||||
|
gBfParserCache->mParseFileDataMap.Remove(mFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete[] mJumpTable;
|
delete[] mJumpTable;
|
||||||
delete[] mCharIdData;
|
delete[] mCharIdData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfParserData::InitFileData()
|
||||||
|
{
|
||||||
|
BF_ASSERT(mParseFileData == NULL);
|
||||||
|
|
||||||
|
BfParseFileData** valuePtr = NULL;
|
||||||
|
if (gBfParserCache->mParseFileDataMap.TryAdd(mFileName, NULL, &valuePtr))
|
||||||
|
{
|
||||||
|
*valuePtr = new BfParseFileData();
|
||||||
|
}
|
||||||
|
mParseFileData = *valuePtr;
|
||||||
|
mParseFileData->mRefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
int BfParserData::GetCharIdAtIndex(int findIndex)
|
int BfParserData::GetCharIdAtIndex(int findIndex)
|
||||||
{
|
{
|
||||||
if (mCharIdData == NULL)
|
if (mCharIdData == NULL)
|
||||||
|
@ -413,6 +470,8 @@ BfParser::~BfParser()
|
||||||
}
|
}
|
||||||
else if (mParserData->mRefCount == 0)
|
else if (mParserData->mRefCount == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Just never got added to the cache
|
// Just never got added to the cache
|
||||||
delete mParserData;
|
delete mParserData;
|
||||||
}
|
}
|
||||||
|
@ -510,6 +569,7 @@ void BfParser::Init(uint64 cacheHash)
|
||||||
mParserData = new BfParserData();
|
mParserData = new BfParserData();
|
||||||
mSourceData = mParserData;
|
mSourceData = mParserData;
|
||||||
mParserData->mFileName = mFileName;
|
mParserData->mFileName = mFileName;
|
||||||
|
mParserData->InitFileData();
|
||||||
if (mDataId != -1)
|
if (mDataId != -1)
|
||||||
mParserData->mDataId = mDataId;
|
mParserData->mDataId = mDataId;
|
||||||
else
|
else
|
||||||
|
|
|
@ -62,6 +62,22 @@ enum MaybeBool
|
||||||
MaybeBool_True = 1,
|
MaybeBool_True = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BfParseFileData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Array<int> mUniqueIDList;
|
||||||
|
int mRefCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BfParseFileData()
|
||||||
|
{
|
||||||
|
mRefCount = 0;
|
||||||
|
}
|
||||||
|
~BfParseFileData();
|
||||||
|
|
||||||
|
int GetUniqueId(int idx);
|
||||||
|
};
|
||||||
|
|
||||||
class BfParserData : public BfSourceData
|
class BfParserData : public BfSourceData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -81,6 +97,7 @@ public:
|
||||||
OwnedVector<String> mStringLiterals;
|
OwnedVector<String> mStringLiterals;
|
||||||
Dictionary<int, BfParserWarningEnabledChange> mWarningEnabledChanges;
|
Dictionary<int, BfParserWarningEnabledChange> mWarningEnabledChanges;
|
||||||
std::set<int> mUnwarns;
|
std::set<int> mUnwarns;
|
||||||
|
BfParseFileData* mParseFileData;
|
||||||
bool mFailed; // Don't cache if there's a warning or an error
|
bool mFailed; // Don't cache if there's a warning or an error
|
||||||
bool mDidReduce;
|
bool mDidReduce;
|
||||||
|
|
||||||
|
@ -94,6 +111,7 @@ public:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitFileData();
|
||||||
virtual BfParser* ToParser() override;
|
virtual BfParser* ToParser() override;
|
||||||
int GetCharIdAtIndex(int findIndex);
|
int GetCharIdAtIndex(int findIndex);
|
||||||
void GetLineCharAtIdx(int idx, int& line, int& lineChar);
|
void GetLineCharAtIdx(int idx, int& line, int& lineChar);
|
||||||
|
@ -130,6 +148,7 @@ public:
|
||||||
int mRefCount;
|
int mRefCount;
|
||||||
BfAstAllocManager mAstAllocManager;
|
BfAstAllocManager mAstAllocManager;
|
||||||
HashSet<DataEntry> mEntries;
|
HashSet<DataEntry> mEntries;
|
||||||
|
Dictionary<String, BfParseFileData*> mParseFileDataMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfParserCache();
|
BfParserCache();
|
||||||
|
|
|
@ -47,6 +47,7 @@ BfReducer::BfReducer()
|
||||||
mSystem = NULL;
|
mSystem = NULL;
|
||||||
mResolvePassData = NULL;
|
mResolvePassData = NULL;
|
||||||
mMethodDepth = 0;
|
mMethodDepth = 0;
|
||||||
|
mCurUniqueIdx = 0;
|
||||||
mDocumentCheckIdx = 0;
|
mDocumentCheckIdx = 0;
|
||||||
mTypeMemberNodeStart = NULL;
|
mTypeMemberNodeStart = NULL;
|
||||||
}
|
}
|
||||||
|
@ -403,6 +404,39 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int
|
||||||
mVisitorPos.mReadPos = startNode;
|
mVisitorPos.mReadPos = startNode;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if ((checkToken == BfToken_Struct) || (checkToken == BfToken_Class) || (checkToken == BfToken_Interface) || (checkToken == BfToken_Enum))
|
||||||
|
{
|
||||||
|
checkIdx++;
|
||||||
|
auto nextNode = mVisitorPos.Get(checkIdx);
|
||||||
|
if (auto block = BfNodeDynCast<BfBlock>(nextNode))
|
||||||
|
{
|
||||||
|
if (outEndNode != NULL)
|
||||||
|
*outEndNode = checkIdx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||||
|
{
|
||||||
|
if (tokenNode->mToken == BfToken_Colon)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
checkIdx++;
|
||||||
|
auto checkNode = mVisitorPos.Get(checkIdx);
|
||||||
|
if (checkNode == NULL)
|
||||||
|
return false;
|
||||||
|
if (auto block = BfNodeDynCast<BfBlock>(checkNode))
|
||||||
|
{
|
||||||
|
if (outEndNode != NULL)
|
||||||
|
*outEndNode = checkIdx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4360,6 +4394,7 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
|
||||||
ReplaceNode(typeRef, methodDecl);
|
ReplaceNode(typeRef, methodDecl);
|
||||||
methodDecl->mDocumentation = FindDocumentation(methodDecl);
|
methodDecl->mDocumentation = FindDocumentation(methodDecl);
|
||||||
methodDecl->mReturnType = typeRef;
|
methodDecl->mReturnType = typeRef;
|
||||||
|
CheckMultiuseAttributeTypeRef(methodDecl->mReturnType);
|
||||||
|
|
||||||
BfDeferredAstSizedArray<BfParameterDeclaration*> params(methodDecl->mParams, mAlloc);
|
BfDeferredAstSizedArray<BfParameterDeclaration*> params(methodDecl->mParams, mAlloc);
|
||||||
BfDeferredAstSizedArray<BfTokenNode*> commas(methodDecl->mCommas, mAlloc);
|
BfDeferredAstSizedArray<BfTokenNode*> commas(methodDecl->mCommas, mAlloc);
|
||||||
|
@ -5105,6 +5140,71 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
if ((createTypeRefFlags & CreateTypeRefFlags_EarlyExit) != 0)
|
if ((createTypeRefFlags & CreateTypeRefFlags_EarlyExit) != 0)
|
||||||
return delegateTypeRef;
|
return delegateTypeRef;
|
||||||
}
|
}
|
||||||
|
else if ((BfTokenIsTypeDecl(token)) || (token == BfToken_LBracket))
|
||||||
|
{
|
||||||
|
BfAttributeDirective* attributes = NULL;
|
||||||
|
if (token == BfToken_LBracket)
|
||||||
|
{
|
||||||
|
attributes = CreateAttributeDirective(tokenNode);
|
||||||
|
if (attributes == NULL)
|
||||||
|
return NULL;
|
||||||
|
mVisitorPos.MoveNext();
|
||||||
|
bool isValid = false;
|
||||||
|
|
||||||
|
auto nextNode = mVisitorPos.GetCurrent();
|
||||||
|
tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
|
||||||
|
if (tokenNode != NULL)
|
||||||
|
{
|
||||||
|
token = tokenNode->mToken;
|
||||||
|
if (BfTokenIsTypeDecl(token))
|
||||||
|
isValid = true;
|
||||||
|
}
|
||||||
|
if (!isValid)
|
||||||
|
{
|
||||||
|
AddErrorNode(attributes);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool attribsApply = false;
|
||||||
|
if ((mTypeMemberNodeStart != NULL) && (mTypeMemberNodeStart->mSrcEnd == tokenNode->mTriviaStart))
|
||||||
|
attribsApply = true;
|
||||||
|
auto typeDeclNode = CreateTopLevelObject(tokenNode, attributes, attribsApply ? mTypeMemberNodeStart : NULL, true);
|
||||||
|
if (typeDeclNode == NULL)
|
||||||
|
{
|
||||||
|
if (attributes != NULL)
|
||||||
|
AddErrorNode(attributes);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto typeDecl = BfNodeDynCast<BfTypeDeclaration>(typeDeclNode);
|
||||||
|
if (typeDecl == NULL)
|
||||||
|
{
|
||||||
|
if (attributes != NULL)
|
||||||
|
AddErrorNode(attributes);
|
||||||
|
AddErrorNode(typeDeclNode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
String name;
|
||||||
|
auto parserData = typeDecl->GetParserData();
|
||||||
|
name = "Anon_";
|
||||||
|
|
||||||
|
auto parseFileData = parserData->mParseFileData;
|
||||||
|
int uniqueId = parseFileData->GetUniqueId(mCurUniqueIdx++);
|
||||||
|
name += StrFormat("%d", uniqueId);
|
||||||
|
|
||||||
|
int len = (int)name.length() + 1;
|
||||||
|
typeDecl->mAnonymousName = (char*)mAlloc->AllocBytes(len);
|
||||||
|
memcpy(typeDecl->mAnonymousName, name.c_str(), len);
|
||||||
|
|
||||||
|
if (mCurTypeState != NULL)
|
||||||
|
mCurTypeState->mAnonymousTypeDecls.Add(typeDecl);
|
||||||
|
auto typeRef = mAlloc->Alloc<BfInlineTypeReference>();
|
||||||
|
ReplaceNode(typeDecl, typeRef);
|
||||||
|
typeRef->mTypeDeclaration = typeDecl;
|
||||||
|
return typeRef;
|
||||||
|
}
|
||||||
else if ((token == BfToken_Comptype) || (token == BfToken_Decltype))
|
else if ((token == BfToken_Comptype) || (token == BfToken_Decltype))
|
||||||
{
|
{
|
||||||
auto declTypeRef = mAlloc->Alloc<BfExprModTypeRef>();
|
auto declTypeRef = mAlloc->Alloc<BfExprModTypeRef>();
|
||||||
|
@ -5881,6 +5981,12 @@ BfStatement* BfReducer::CreateAttributedStatement(BfTokenNode* tokenNode, Create
|
||||||
(checkNode->IsA<BfStringInterpolationExpression>()) ||
|
(checkNode->IsA<BfStringInterpolationExpression>()) ||
|
||||||
(checkNode->IsA<BfBlock>()))
|
(checkNode->IsA<BfBlock>()))
|
||||||
{
|
{
|
||||||
|
if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(checkNode))
|
||||||
|
{
|
||||||
|
if (CheckInlineTypeRefAttribute(varDecl->mTypeRef, attrib))
|
||||||
|
return BfNodeDynCast<BfStatement>(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
BfAttributedStatement* attribStmt = mAlloc->Alloc<BfAttributedStatement>();
|
BfAttributedStatement* attribStmt = mAlloc->Alloc<BfAttributedStatement>();
|
||||||
ReplaceNode(attrib, attribStmt);
|
ReplaceNode(attrib, attribStmt);
|
||||||
attribStmt->mAttributes = attrib;
|
attribStmt->mAttributes = attrib;
|
||||||
|
@ -6169,6 +6275,8 @@ BfFieldDeclaration* BfReducer::CreateFieldDeclaration(BfTokenNode* tokenNode, Bf
|
||||||
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
|
MoveNode(fieldDeclaration->mNameNode, fieldDeclaration);
|
||||||
//mVisitorPos.MoveNext();
|
//mVisitorPos.MoveNext();
|
||||||
}
|
}
|
||||||
|
CheckMultiuseAttributeTypeRef(fieldDeclaration->mTypeRef);
|
||||||
|
|
||||||
BfToken token = tokenNode->GetToken();
|
BfToken token = tokenNode->GetToken();
|
||||||
if (token == BfToken_AssignEquals)
|
if (token == BfToken_AssignEquals)
|
||||||
{
|
{
|
||||||
|
@ -6274,6 +6382,26 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
|
||||||
return memberNode;
|
return memberNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memberNode->mTriviaStart = attributes->mTriviaStart;
|
||||||
|
memberNode->mSrcStart = attributes->mSrcStart;
|
||||||
|
|
||||||
|
if (auto fieldDecl = BfNodeDynCast<BfFieldDeclaration>(member))
|
||||||
|
{
|
||||||
|
if (CheckInlineTypeRefAttribute(fieldDecl->mTypeRef, attributes))
|
||||||
|
{
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(member))
|
||||||
|
{
|
||||||
|
if (CheckInlineTypeRefAttribute(methodDecl->mReturnType, attributes))
|
||||||
|
{
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ReplaceNode(attributes, member);
|
ReplaceNode(attributes, member);
|
||||||
member->mAttributes = attributes;
|
member->mAttributes = attributes;
|
||||||
return member;
|
return member;
|
||||||
|
@ -6291,6 +6419,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
|
||||||
if (typeRef == NULL)
|
if (typeRef == NULL)
|
||||||
return operatorDecl;
|
return operatorDecl;
|
||||||
MEMBER_SET_CHECKED(operatorDecl, mReturnType, typeRef);
|
MEMBER_SET_CHECKED(operatorDecl, mReturnType, typeRef);
|
||||||
|
CheckMultiuseAttributeTypeRef(operatorDecl->mReturnType);
|
||||||
operatorDecl->mIsConvOperator = true;
|
operatorDecl->mIsConvOperator = true;
|
||||||
|
|
||||||
ParseMethod(operatorDecl, ¶ms, &commas);
|
ParseMethod(operatorDecl, ¶ms, &commas);
|
||||||
|
@ -7061,10 +7190,19 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((token == BfToken_Struct) || (token == BfToken_Class) || (token == BfToken_Interface) || (token == BfToken_Enum))
|
||||||
|
{
|
||||||
|
int endNodeIdx = -1;
|
||||||
|
if (IsTypeReference(node, BfToken_None, -1, &endNodeIdx))
|
||||||
|
{
|
||||||
|
isTypeRef = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((token == BfToken_LBracket) && (depth > 0))
|
if ((token == BfToken_LBracket) && (depth > 0))
|
||||||
{
|
{
|
||||||
Fail("Unexpected custom attribute", node);
|
// The only valid option is an attributed type reference
|
||||||
return NULL;
|
isTypeRef = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTypeRef)
|
if (isTypeRef)
|
||||||
|
@ -7218,6 +7356,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
ReplaceNode(nameIdentifier, methodDeclaration);
|
ReplaceNode(nameIdentifier, methodDeclaration);
|
||||||
methodDeclaration->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
methodDeclaration->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||||
MEMBER_SET(methodDeclaration, mReturnType, typeRef);
|
MEMBER_SET(methodDeclaration, mReturnType, typeRef);
|
||||||
|
CheckMultiuseAttributeTypeRef(methodDeclaration->mReturnType);
|
||||||
MEMBER_SET(methodDeclaration, mExplicitInterface, explicitInterface);
|
MEMBER_SET(methodDeclaration, mExplicitInterface, explicitInterface);
|
||||||
MEMBER_SET(methodDeclaration, mExplicitInterfaceDotToken, explicitInterfaceDot);
|
MEMBER_SET(methodDeclaration, mExplicitInterfaceDotToken, explicitInterfaceDot);
|
||||||
return methodDeclaration;
|
return methodDeclaration;
|
||||||
|
@ -7235,6 +7374,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
BfDeferredAstSizedArray<BfTokenNode*> commas(operatorDecl->mCommas, mAlloc);
|
BfDeferredAstSizedArray<BfTokenNode*> commas(operatorDecl->mCommas, mAlloc);
|
||||||
ReplaceNode(typeRef, operatorDecl);
|
ReplaceNode(typeRef, operatorDecl);
|
||||||
operatorDecl->mReturnType = typeRef;
|
operatorDecl->mReturnType = typeRef;
|
||||||
|
CheckMultiuseAttributeTypeRef(operatorDecl->mReturnType);
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
||||||
MEMBER_SET(operatorDecl, mOperatorToken, nextToken);
|
MEMBER_SET(operatorDecl, mOperatorToken, nextToken);
|
||||||
|
@ -7394,6 +7534,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
ReplaceNode(typeRef, propDecl);
|
ReplaceNode(typeRef, propDecl);
|
||||||
propDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
propDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||||
propDecl->mTypeRef = typeRef;
|
propDecl->mTypeRef = typeRef;
|
||||||
|
CheckMultiuseAttributeTypeRef(propDecl->mTypeRef);
|
||||||
|
|
||||||
if (explicitInterface != NULL)
|
if (explicitInterface != NULL)
|
||||||
{
|
{
|
||||||
|
@ -7553,6 +7694,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
ReplaceNode(typeRef, fieldDecl);
|
ReplaceNode(typeRef, fieldDecl);
|
||||||
fieldDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
fieldDecl->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||||
fieldDecl->mTypeRef = typeRef;
|
fieldDecl->mTypeRef = typeRef;
|
||||||
|
CheckMultiuseAttributeTypeRef(fieldDecl->mTypeRef);
|
||||||
return fieldDecl;
|
return fieldDecl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7584,6 +7726,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
|
||||||
}
|
}
|
||||||
|
|
||||||
methodDeclaration->mReturnType = typeRef;
|
methodDeclaration->mReturnType = typeRef;
|
||||||
|
CheckMultiuseAttributeTypeRef(methodDeclaration->mReturnType);
|
||||||
MEMBER_SET_CHECKED(methodDeclaration, mNameNode, nameIdentifier);
|
MEMBER_SET_CHECKED(methodDeclaration, mNameNode, nameIdentifier);
|
||||||
mCurMethodDecl = methodDeclaration;
|
mCurMethodDecl = methodDeclaration;
|
||||||
ParseMethod(methodDeclaration, ¶ms, &commas);
|
ParseMethod(methodDeclaration, ¶ms, &commas);
|
||||||
|
@ -7990,6 +8133,47 @@ BfScopedInvocationTarget* BfReducer::CreateScopedInvocationTarget(BfAstNode*& ta
|
||||||
return scopedInvocationTarget;
|
return scopedInvocationTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfReducer::CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes)
|
||||||
|
{
|
||||||
|
if (attributes == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto inlineTypeRef = BfNodeDynCast<BfInlineTypeReference>(typeRef))
|
||||||
|
{
|
||||||
|
auto checkAttribute = attributes;
|
||||||
|
while (checkAttribute != NULL)
|
||||||
|
{
|
||||||
|
checkAttribute->mIsMultiUse = true;
|
||||||
|
checkAttribute = checkAttribute->mNextAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto typeDecl = inlineTypeRef->mTypeDeclaration;
|
||||||
|
typeDecl->mTriviaStart = attributes->mTriviaStart;
|
||||||
|
typeDecl->mSrcStart = attributes->mSrcStart;
|
||||||
|
typeDecl->mAttributes = attributes;
|
||||||
|
|
||||||
|
if ((typeDecl->mIgnoreDeclaration) && (IsNodeRelevant(typeDecl)))
|
||||||
|
typeDecl->mIgnoreDeclaration = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfReducer::CheckMultiuseAttributeTypeRef(BfAstNode* typeRef)
|
||||||
|
{
|
||||||
|
if (auto inlineTypeRef = BfNodeDynCast<BfInlineTypeReference>(typeRef))
|
||||||
|
{
|
||||||
|
auto checkAttribute = inlineTypeRef->mTypeDeclaration->mAttributes;
|
||||||
|
while (checkAttribute != NULL)
|
||||||
|
{
|
||||||
|
checkAttribute->mIsMultiUse = true;
|
||||||
|
checkAttribute = checkAttribute->mNextAttribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool BfReducer::SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode)
|
bool BfReducer::SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode)
|
||||||
{
|
{
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
|
@ -8648,7 +8832,7 @@ BfAstNode* BfReducer::HandleTopLevel(BfBlock* node)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode)
|
BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode, bool isAnonymous)
|
||||||
{
|
{
|
||||||
AssertCurrentNode(tokenNode);
|
AssertCurrentNode(tokenNode);
|
||||||
|
|
||||||
|
@ -8994,7 +9178,10 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi
|
||||||
case BfToken_Function:
|
case BfToken_Function:
|
||||||
{
|
{
|
||||||
auto typeDeclaration = mAlloc->Alloc<BfTypeDeclaration>();
|
auto typeDeclaration = mAlloc->Alloc<BfTypeDeclaration>();
|
||||||
|
|
||||||
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDeclaration);
|
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDeclaration);
|
||||||
|
CurTypeState curTypeState(typeDeclaration, mAlloc);
|
||||||
|
SetAndRestoreValue<CurTypeState*> prevTypeState(mCurTypeState, &curTypeState);
|
||||||
|
|
||||||
ReplaceNode(tokenNode, typeDeclaration);
|
ReplaceNode(tokenNode, typeDeclaration);
|
||||||
typeDeclaration->mDocumentation = FindDocumentation(typeDeclaration);
|
typeDeclaration->mDocumentation = FindDocumentation(typeDeclaration);
|
||||||
|
@ -9006,6 +9193,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi
|
||||||
|
|
||||||
auto methodDecl = mAlloc->Alloc<BfMethodDeclaration>();
|
auto methodDecl = mAlloc->Alloc<BfMethodDeclaration>();
|
||||||
MEMBER_SET(methodDecl, mReturnType, retType);
|
MEMBER_SET(methodDecl, mReturnType, retType);
|
||||||
|
CheckMultiuseAttributeTypeRef(methodDecl->mReturnType);
|
||||||
BfDeferredAstSizedArray<BfParameterDeclaration*> params(methodDecl->mParams, mAlloc);
|
BfDeferredAstSizedArray<BfParameterDeclaration*> params(methodDecl->mParams, mAlloc);
|
||||||
BfDeferredAstSizedArray<BfTokenNode*> commas(methodDecl->mCommas, mAlloc);
|
BfDeferredAstSizedArray<BfTokenNode*> commas(methodDecl->mCommas, mAlloc);
|
||||||
methodDecl->mDocumentation = FindDocumentation(methodDecl);
|
methodDecl->mDocumentation = FindDocumentation(methodDecl);
|
||||||
|
@ -9121,11 +9309,16 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi
|
||||||
if ((tokenNode->GetToken() == BfToken_Enum) && (isSimpleEnum))
|
if ((tokenNode->GetToken() == BfToken_Enum) && (isSimpleEnum))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto identifierNode = ExpectIdentifierAfter(tokenNode);
|
BfIdentifierNode* identifierNode = NULL;
|
||||||
if (identifierNode == NULL)
|
|
||||||
|
if (!isAnonymous)
|
||||||
{
|
{
|
||||||
AddErrorNode(tokenNode);
|
identifierNode = ExpectIdentifierAfter(tokenNode);
|
||||||
return NULL;
|
if (identifierNode == NULL)
|
||||||
|
{
|
||||||
|
AddErrorNode(tokenNode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We put extra effort in here to continue after failure, since 'return NULL' failure
|
// We put extra effort in here to continue after failure, since 'return NULL' failure
|
||||||
|
@ -9138,7 +9331,8 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi
|
||||||
typeDeclaration->mTypeNode = tokenNode;
|
typeDeclaration->mTypeNode = tokenNode;
|
||||||
typeDeclaration->mNameNode = identifierNode;
|
typeDeclaration->mNameNode = identifierNode;
|
||||||
ReplaceNode(tokenNode, typeDeclaration);
|
ReplaceNode(tokenNode, typeDeclaration);
|
||||||
MoveNode(identifierNode, typeDeclaration);
|
if (identifierNode != NULL)
|
||||||
|
MoveNode(identifierNode, typeDeclaration);
|
||||||
typeDeclaration->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
typeDeclaration->mDocumentation = FindDocumentation(mTypeMemberNodeStart);
|
||||||
|
|
||||||
auto nextNode = mVisitorPos.GetNext();
|
auto nextNode = mVisitorPos.GetNext();
|
||||||
|
@ -10645,6 +10839,8 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
|
||||||
void BfReducer::HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode)
|
void BfReducer::HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDecl);
|
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDecl);
|
||||||
|
CurTypeState curTypeState(typeDecl, mAlloc);
|
||||||
|
SetAndRestoreValue<CurTypeState*> prevTypeState(mCurTypeState, &curTypeState);
|
||||||
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(BfNodeDynCast<BfBlock>(typeDecl->mDefineNode)));
|
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(BfNodeDynCast<BfBlock>(typeDecl->mDefineNode)));
|
||||||
|
|
||||||
if (attributes != NULL)
|
if (attributes != NULL)
|
||||||
|
|
|
@ -129,6 +129,39 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CurTypeState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BfTypeDeclaration* mTypeDeclaration;
|
||||||
|
BfAstAllocator* mAlloc;
|
||||||
|
Array<BfTypeDeclaration*> mAnonymousTypeDecls;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CurTypeState()
|
||||||
|
{
|
||||||
|
mTypeDeclaration = NULL;
|
||||||
|
mAlloc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurTypeState(BfTypeDeclaration* typeDecl, BfAstAllocator* alloc)
|
||||||
|
{
|
||||||
|
mTypeDeclaration = typeDecl;
|
||||||
|
mAlloc = alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CurTypeState()
|
||||||
|
{
|
||||||
|
if ((mTypeDeclaration != NULL) && (mAnonymousTypeDecls.mSize > 0))
|
||||||
|
{
|
||||||
|
BF_ASSERT(mTypeDeclaration->mAnonymousTypes.mSize == 0);
|
||||||
|
mTypeDeclaration->mAnonymousTypes.mSize = (int)mAnonymousTypeDecls.size();
|
||||||
|
mTypeDeclaration->mAnonymousTypes.mVals = (BfTypeDeclaration**)mAlloc->AllocBytes(mAnonymousTypeDecls.mSize * sizeof(BfTypeDeclaration*), sizeof(BfTypeDeclaration*));
|
||||||
|
for (int i = 0; i < mAnonymousTypeDecls.mSize; i++)
|
||||||
|
mTypeDeclaration->mAnonymousTypes.mVals[i] = mAnonymousTypeDecls[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfAstAllocator* mAlloc;
|
BfAstAllocator* mAlloc;
|
||||||
BfSystem* mSystem;
|
BfSystem* mSystem;
|
||||||
|
@ -138,7 +171,9 @@ public:
|
||||||
BfAstNode* mTypeMemberNodeStart;
|
BfAstNode* mTypeMemberNodeStart;
|
||||||
int mClassDepth;
|
int mClassDepth;
|
||||||
int mMethodDepth;
|
int mMethodDepth;
|
||||||
|
int mCurUniqueIdx;
|
||||||
BfTypeDeclaration* mCurTypeDecl;
|
BfTypeDeclaration* mCurTypeDecl;
|
||||||
|
CurTypeState* mCurTypeState;
|
||||||
BfTypeDeclaration* mLastTypeDecl;
|
BfTypeDeclaration* mLastTypeDecl;
|
||||||
BfMethodDeclaration* mCurMethodDecl;
|
BfMethodDeclaration* mCurMethodDecl;
|
||||||
BfAstNode* mLastBlockNode;
|
BfAstNode* mLastBlockNode;
|
||||||
|
@ -180,6 +215,8 @@ public:
|
||||||
void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
|
void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
|
||||||
void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
|
void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
|
||||||
|
|
||||||
|
bool CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes);
|
||||||
|
void CheckMultiuseAttributeTypeRef(BfAstNode* typeRef);
|
||||||
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
|
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
|
||||||
BfAstNode* CreateAllocNode(BfTokenNode* newNode);
|
BfAstNode* CreateAllocNode(BfTokenNode* newNode);
|
||||||
BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false);
|
BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false);
|
||||||
|
@ -238,7 +275,7 @@ public:
|
||||||
BfWhileStatement* CreateWhileStatement(BfAstNode* node);
|
BfWhileStatement* CreateWhileStatement(BfAstNode* node);
|
||||||
BfDoStatement* CreateDoStatement(BfAstNode* node);
|
BfDoStatement* CreateDoStatement(BfAstNode* node);
|
||||||
BfRepeatStatement* CreateRepeatStatement(BfAstNode* node);
|
BfRepeatStatement* CreateRepeatStatement(BfAstNode* node);
|
||||||
BfAstNode* CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL);
|
BfAstNode* CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL, bool isAnonymous = false);
|
||||||
BfAstNode* HandleTopLevel(BfBlock* node);
|
BfAstNode* HandleTopLevel(BfBlock* node);
|
||||||
BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
|
BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
|
||||||
|
|
||||||
|
|
|
@ -2450,6 +2450,11 @@ bool BfTypeInstance::GetResultInfo(BfType*& valueType, int& okTagId)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfTypeInstance::IsAnonymous()
|
||||||
|
{
|
||||||
|
return (mTypeDef->mTypeDeclaration != NULL) && (mTypeDef->mTypeDeclaration->IsAnonymous());
|
||||||
|
}
|
||||||
|
|
||||||
void BfTypeInstance::ReportMemory(MemReporter* memReporter)
|
void BfTypeInstance::ReportMemory(MemReporter* memReporter)
|
||||||
{
|
{
|
||||||
if (mGenericTypeInfo != NULL)
|
if (mGenericTypeInfo != NULL)
|
||||||
|
@ -4249,6 +4254,13 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa
|
||||||
}
|
}
|
||||||
return nameHash ^ HASH_TAG;
|
return nameHash ^ HASH_TAG;
|
||||||
}
|
}
|
||||||
|
// else if (auto inlineTypeRef = BfNodeDynCastExact<BfInlineTypeReference>(typeRef))
|
||||||
|
// {
|
||||||
|
// String name;
|
||||||
|
// inlineTypeRef->mTypeDeclaration->GetAnonymousName(name);
|
||||||
|
// int nameHash = (int)Hash64(name.c_str(), (int)name.length());
|
||||||
|
// return nameHash ^ HASH_TAG;
|
||||||
|
// }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BF_FATAL("Not handled");
|
BF_FATAL("Not handled");
|
||||||
|
@ -5552,6 +5564,8 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode)
|
||||||
}
|
}
|
||||||
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
|
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
|
||||||
return directStrTypeName->mTypeName;
|
return directStrTypeName->mTypeName;
|
||||||
|
if (auto inlineTypeRef = BfNodeDynCast<BfInlineTypeReference>(typeRef))
|
||||||
|
return inlineTypeRef->mTypeDeclaration->mAnonymousName;
|
||||||
|
|
||||||
if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
|
if (auto tupleTypeRef = BfNodeDynCast<BfTupleTypeRef>(typeRef))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2205,6 +2205,7 @@ public:
|
||||||
bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
|
bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); }
|
||||||
bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
|
bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); }
|
||||||
bool DefineStateAllowsStaticMethods() { return mDefineState >= BfTypeDefineState_HasInterfaces_Direct; }
|
bool DefineStateAllowsStaticMethods() { return mDefineState >= BfTypeDefineState_HasInterfaces_Direct; }
|
||||||
|
bool IsAnonymous();
|
||||||
|
|
||||||
virtual void ReportMemory(MemReporter* memReporter) override;
|
virtual void ReportMemory(MemReporter* memReporter) override;
|
||||||
};
|
};
|
||||||
|
@ -2669,6 +2670,7 @@ public:
|
||||||
Array<BfCustomAttributeSetProperty> mSetProperties;
|
Array<BfCustomAttributeSetProperty> mSetProperties;
|
||||||
Array<BfCustomAttributeSetField> mSetField;
|
Array<BfCustomAttributeSetField> mSetField;
|
||||||
bool mAwaitingValidation;
|
bool mAwaitingValidation;
|
||||||
|
bool mIsMultiUse;
|
||||||
|
|
||||||
BfAstNode* GetRefNode()
|
BfAstNode* GetRefNode()
|
||||||
{
|
{
|
||||||
|
|
|
@ -662,7 +662,7 @@ void BfSourceClassifier::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
|
|
||||||
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, typeDeclaration);
|
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, typeDeclaration);
|
||||||
|
|
||||||
if (mSkipTypeDeclarations)
|
if ((mSkipTypeDeclarations) && (!typeDeclaration->IsAnonymous()))
|
||||||
{
|
{
|
||||||
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
|
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1984,6 +1984,8 @@ BfSystem::BfSystem()
|
||||||
gPerfManager = new PerfManager();
|
gPerfManager = new PerfManager();
|
||||||
//gPerfManager->StartRecording();
|
//gPerfManager->StartRecording();
|
||||||
|
|
||||||
|
mAnonymousAtomCount = 0;
|
||||||
|
mCurUniqueId = 0;
|
||||||
mAtomUpdateIdx = 0;
|
mAtomUpdateIdx = 0;
|
||||||
mAtomCreateIdx = 0;
|
mAtomCreateIdx = 0;
|
||||||
mTypeMapVersion = 1;
|
mTypeMapVersion = 1;
|
||||||
|
@ -2094,7 +2096,7 @@ BfSystem::~BfSystem()
|
||||||
typeDef->mHash = typeCode + 1000; \
|
typeDef->mHash = typeCode + 1000; \
|
||||||
mSystemTypeDefs[name] = typeDef;
|
mSystemTypeDefs[name] = typeDef;
|
||||||
|
|
||||||
BfAtom* BfSystem::GetAtom(const StringImpl& string)
|
BfAtom* BfSystem::GetAtom(const StringImpl& string, BfAtom::Kind kind)
|
||||||
{
|
{
|
||||||
StringView* stringPtr = NULL;
|
StringView* stringPtr = NULL;
|
||||||
BfAtom* atom = NULL;
|
BfAtom* atom = NULL;
|
||||||
|
@ -2111,6 +2113,7 @@ BfAtom* BfSystem::GetAtom(const StringImpl& string)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
mAtomCreateIdx++;
|
mAtomCreateIdx++;
|
||||||
|
atom->mKind = kind;
|
||||||
atom->mIsSystemType = false;
|
atom->mIsSystemType = false;
|
||||||
atom->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
atom->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
||||||
atom->mString = *stringPtr;
|
atom->mString = *stringPtr;
|
||||||
|
@ -2121,6 +2124,9 @@ BfAtom* BfSystem::GetAtom(const StringImpl& string)
|
||||||
for (char c : string)
|
for (char c : string)
|
||||||
atom->mHash = ((atom->mHash ^ c) << 5) - atom->mHash;
|
atom->mHash = ((atom->mHash ^ c) << 5) - atom->mHash;
|
||||||
|
|
||||||
|
if (kind == BfAtom::Kind_Anon)
|
||||||
|
mAnonymousAtomCount++;
|
||||||
|
|
||||||
BfLogSys(this, "Atom Allocated %p %s\n", atom, string.c_str());
|
BfLogSys(this, "Atom Allocated %p %s\n", atom, string.c_str());
|
||||||
|
|
||||||
return atom;
|
return atom;
|
||||||
|
@ -2152,6 +2158,12 @@ void BfSystem::ReleaseAtom(BfAtom* atom)
|
||||||
{
|
{
|
||||||
if (--atom->mRefCount == 0)
|
if (--atom->mRefCount == 0)
|
||||||
{
|
{
|
||||||
|
if (atom->mKind == BfAtom::Kind_Anon)
|
||||||
|
{
|
||||||
|
mAnonymousAtomCount--;
|
||||||
|
BF_ASSERT(mAnonymousAtomCount >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
mAtomGraveyard.push_back(atom);
|
mAtomGraveyard.push_back(atom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,16 @@ typedef HashSet<BfProject*> BfProjectSet;
|
||||||
|
|
||||||
class BfAtom
|
class BfAtom
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
enum Kind
|
||||||
|
{
|
||||||
|
Kind_Normal,
|
||||||
|
Kind_Anon
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StringView mString;
|
StringView mString;
|
||||||
|
Kind mKind;
|
||||||
int mRefCount;
|
int mRefCount;
|
||||||
int mPendingDerefCount;
|
int mPendingDerefCount;
|
||||||
int mHash;
|
int mHash;
|
||||||
|
@ -1783,6 +1791,8 @@ public:
|
||||||
Array<BfAtom*> mAtomGraveyard;
|
Array<BfAtom*> mAtomGraveyard;
|
||||||
uint32 mAtomUpdateIdx;
|
uint32 mAtomUpdateIdx;
|
||||||
int32 mTypeMapVersion; // Increment when we add any new types or namespaces
|
int32 mTypeMapVersion; // Increment when we add any new types or namespaces
|
||||||
|
int32 mAnonymousAtomCount;
|
||||||
|
int32 mCurUniqueId;
|
||||||
|
|
||||||
OwnedVector<BfMethodDef> mMethodGraveyard;
|
OwnedVector<BfMethodDef> mMethodGraveyard;
|
||||||
OwnedVector<BfFieldDef> mFieldGraveyard;
|
OwnedVector<BfFieldDef> mFieldGraveyard;
|
||||||
|
@ -1830,7 +1840,7 @@ public:
|
||||||
BfSystem();
|
BfSystem();
|
||||||
~BfSystem();
|
~BfSystem();
|
||||||
|
|
||||||
BfAtom* GetAtom(const StringImpl& string);
|
BfAtom* GetAtom(const StringImpl& string, BfAtom::Kind kind = BfAtom::Kind_Normal);
|
||||||
BfAtom* FindAtom(const StringImpl& string); // Doesn't create a ref
|
BfAtom* FindAtom(const StringImpl& string); // Doesn't create a ref
|
||||||
BfAtom* FindAtom(const StringView& string); // Doesn't create a ref
|
BfAtom* FindAtom(const StringView& string); // Doesn't create a ref
|
||||||
void ReleaseAtom(BfAtom* atom);
|
void ReleaseAtom(BfAtom* atom);
|
||||||
|
|
44
IDEHelper/Tests/src/Anonymous.bf
Normal file
44
IDEHelper/Tests/src/Anonymous.bf
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
class Anonymous
|
||||||
|
{
|
||||||
|
struct StructA
|
||||||
|
{
|
||||||
|
public [Union] struct { public int mX, mY; } mVals;
|
||||||
|
|
||||||
|
[CRepr, SkipCall] struct { public int mA, mB; } GetVals()
|
||||||
|
{
|
||||||
|
decltype(GetVals()) retVals;
|
||||||
|
retVals.mA = 1;
|
||||||
|
retVals.mB = 2;
|
||||||
|
return retVals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructB
|
||||||
|
{
|
||||||
|
[Union]
|
||||||
|
public using struct
|
||||||
|
{
|
||||||
|
public int mX;
|
||||||
|
public int mY;
|
||||||
|
} mCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestBasics()
|
||||||
|
{
|
||||||
|
StructA sa = default;
|
||||||
|
sa.mVals.mX = 123;
|
||||||
|
Test.Assert(sa.mVals.mY == 123);
|
||||||
|
|
||||||
|
var val = sa.[Friend]GetVals();
|
||||||
|
Test.Assert(val.mA == 0);
|
||||||
|
Test.Assert(val.mB == 0);
|
||||||
|
|
||||||
|
StructB sb = default;
|
||||||
|
sb.mX = 345;
|
||||||
|
Test.Assert(sb.mY == 345);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue