mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Anonymous subclassing in initializer blocks
This commit is contained in:
parent
01c2c35fc3
commit
a5e9a33f64
25 changed files with 1111 additions and 608 deletions
|
@ -1243,6 +1243,11 @@ bool BfTypeDeclaration::IsAnonymous()
|
||||||
return (mAnonymousName != NULL);
|
return (mAnonymousName != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfTypeDeclaration::IsAnonymousInitializerType()
|
||||||
|
{
|
||||||
|
return (mAnonymousName != NULL) && (mTypeNode == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool BfTypeReference::IsNamedTypeReference()
|
bool BfTypeReference::IsNamedTypeReference()
|
||||||
|
|
|
@ -358,6 +358,7 @@ class BfAttributedIdentifierNode;
|
||||||
class BfQualifiedNameNode;
|
class BfQualifiedNameNode;
|
||||||
class BfNamespaceDeclaration;
|
class BfNamespaceDeclaration;
|
||||||
class BfTypeDeclaration;
|
class BfTypeDeclaration;
|
||||||
|
class BfInitializerTypeDeclaration;
|
||||||
class BfTypeAliasDeclaration;
|
class BfTypeAliasDeclaration;
|
||||||
class BfMethodDeclaration;
|
class BfMethodDeclaration;
|
||||||
class BfOperatorDeclaration;
|
class BfOperatorDeclaration;
|
||||||
|
@ -1809,6 +1810,7 @@ public:
|
||||||
ASTREF(BfTokenNode*) mCloseBrace;
|
ASTREF(BfTokenNode*) mCloseBrace;
|
||||||
//BfDebugArray<BfAstNode*> mChildArr;
|
//BfDebugArray<BfAstNode*> mChildArr;
|
||||||
BfSizedArray<ASTREF(BfAstNode*)> mChildArr;
|
BfSizedArray<ASTREF(BfAstNode*)> mChildArr;
|
||||||
|
int mParserBlockId;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using BfAstNode::Init;
|
using BfAstNode::Init;
|
||||||
|
@ -2282,6 +2284,7 @@ public:
|
||||||
|
|
||||||
BfAstNode* mTarget;
|
BfAstNode* mTarget;
|
||||||
BfTokenNode* mOpenBrace;
|
BfTokenNode* mOpenBrace;
|
||||||
|
BfInlineTypeReference* mInlineTypeRef;
|
||||||
BfSizedArray<BfExpression*> mValues;
|
BfSizedArray<BfExpression*> mValues;
|
||||||
BfSizedArray<BfTokenNode*> mCommas;
|
BfSizedArray<BfTokenNode*> mCommas;
|
||||||
BfTokenNode* mCloseBrace;
|
BfTokenNode* mCloseBrace;
|
||||||
|
@ -2453,9 +2456,16 @@ public:
|
||||||
BfSizedArray<BfTypeDeclaration*> mAnonymousTypes;
|
BfSizedArray<BfTypeDeclaration*> mAnonymousTypes;
|
||||||
|
|
||||||
bool IsAnonymous();
|
bool IsAnonymous();
|
||||||
|
bool IsAnonymousInitializerType();
|
||||||
|
|
||||||
}; BF_AST_DECL(BfTypeDeclaration, BfAstNode);
|
}; BF_AST_DECL(BfTypeDeclaration, BfAstNode);
|
||||||
|
|
||||||
|
class BfInitializerTypeDeclaration : public BfTypeDeclaration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BF_AST_TYPE(BfInitializerTypeDeclaration, BfTypeDeclaration);
|
||||||
|
}; BF_AST_DECL(BfInitializerTypeDeclaration, BfTypeDeclaration);
|
||||||
|
|
||||||
class BfTypeAliasDeclaration : public BfTypeDeclaration
|
class BfTypeAliasDeclaration : public BfTypeDeclaration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2965,6 +2975,14 @@ public:
|
||||||
BfSizedArray<BfTokenNode*> mCommas;
|
BfSizedArray<BfTokenNode*> mCommas;
|
||||||
}; BF_AST_DECL(BfObjectCreateExpression, BfMethodBoundExpression);
|
}; BF_AST_DECL(BfObjectCreateExpression, BfMethodBoundExpression);
|
||||||
|
|
||||||
|
class BfExtendExpression : public BfExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BF_AST_TYPE(BfExtendExpression, BfExpression);
|
||||||
|
BfAstNode* mTarget;
|
||||||
|
BfTypeDeclaration* mTypeDecl;
|
||||||
|
}; BF_AST_DECL(BfExtendExpression, BfExpression);
|
||||||
|
|
||||||
class BfBoxExpression : public BfExpression
|
class BfBoxExpression : public BfExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -2759,7 +2759,7 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfAutoComplete::AddOverrides(const StringImpl& filter)
|
void BfAutoComplete::AddOverrides(const StringImpl& filter, bool forceAll)
|
||||||
{
|
{
|
||||||
if (!mIsAutoComplete)
|
if (!mIsAutoComplete)
|
||||||
return;
|
return;
|
||||||
|
@ -2780,7 +2780,7 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter)
|
||||||
if (curType == mModule->mCurTypeInstance)
|
if (curType == mModule->mCurTypeInstance)
|
||||||
{
|
{
|
||||||
// The "normal" case, and only case for types without extensions
|
// The "normal" case, and only case for types without extensions
|
||||||
if (methodDef->mDeclaringType == activeTypeDef)
|
if ((methodDef->mDeclaringType == activeTypeDef) && (!forceAll))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((methodDef->mDeclaringType->IsExtension()) && (methodDef->mDeclaringType->mProject == activeTypeDef->mProject))
|
if ((methodDef->mDeclaringType->IsExtension()) && (methodDef->mDeclaringType->mProject == activeTypeDef->mProject))
|
||||||
|
@ -2812,7 +2812,7 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter)
|
||||||
(methodDef->mMethodType != BfMethodType_PropertySetter))
|
(methodDef->mMethodType != BfMethodType_PropertySetter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((methodInst->mVirtualTableIdx >= 0) && (methodInst->mVirtualTableIdx < mModule->mCurTypeInstance->mVirtualMethodTable.size()))
|
if ((methodInst->mVirtualTableIdx >= 0) && (methodInst->mVirtualTableIdx < mModule->mCurTypeInstance->mVirtualMethodTable.size()) && (!forceAll))
|
||||||
{
|
{
|
||||||
auto& vEntry = mModule->mCurTypeInstance->mVirtualMethodTable[methodInst->mVirtualTableIdx];
|
auto& vEntry = mModule->mCurTypeInstance->mVirtualMethodTable[methodInst->mVirtualTableIdx];
|
||||||
if (vEntry.mImplementingMethod.mTypeInstance == mModule->mCurTypeInstance)
|
if (vEntry.mImplementingMethod.mTypeInstance == mModule->mCurTypeInstance)
|
||||||
|
|
|
@ -236,7 +236,7 @@ public:
|
||||||
void AddExtensionMethods(BfTypeInstance* targetType, BfTypeInstance* extensionContainer, const StringImpl& filter, bool allowProtected, bool allowPrivate);
|
void AddExtensionMethods(BfTypeInstance* targetType, BfTypeInstance* extensionContainer, const StringImpl& filter, bool allowProtected, bool allowPrivate);
|
||||||
void AddTopLevelNamespaces(BfAstNode* identifierNode);
|
void AddTopLevelNamespaces(BfAstNode* identifierNode);
|
||||||
void AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute = false);
|
void AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute = false);
|
||||||
void AddOverrides(const StringImpl& filter);
|
void AddOverrides(const StringImpl& filter, bool forceAll = false);
|
||||||
void AddCtorPassthroughs();
|
void AddCtorPassthroughs();
|
||||||
void UpdateReplaceData();
|
void UpdateReplaceData();
|
||||||
void AddTypeInstanceEntry(BfTypeInstance* typeInst);
|
void AddTypeInstanceEntry(BfTypeInstance* typeInst);
|
||||||
|
|
|
@ -4442,7 +4442,7 @@ void BfCompiler::ProcessAutocompleteTempType()
|
||||||
{
|
{
|
||||||
auto checkTypeDef = *actualTypeDefItr;
|
auto checkTypeDef = *actualTypeDefItr;
|
||||||
if ((!checkTypeDef->mIsPartial) /*&& (checkTypeDef->mTypeCode != BfTypeCode_Extension)*/ &&
|
if ((!checkTypeDef->mIsPartial) /*&& (checkTypeDef->mTypeCode != BfTypeCode_Extension)*/ &&
|
||||||
((checkTypeDef->mTypeCode == tempTypeDef->mTypeCode) || (tempTypeDef->mTypeCode == BfTypeCode_Extension)))
|
((checkTypeDef->mTypeCode == tempTypeDef->mTypeCode) || (tempTypeDef->mTypeCode == BfTypeCode_Extension) || (tempTypeDef->mTypeCode == BfTypeCode_Inferred)))
|
||||||
{
|
{
|
||||||
if ((checkTypeDef->NameEquals(tempTypeDef)) && (checkTypeDef->mIsCombinedPartial) &&
|
if ((checkTypeDef->NameEquals(tempTypeDef)) && (checkTypeDef->mIsCombinedPartial) &&
|
||||||
(checkTypeDef->mGenericParamDefs.size() == tempTypeDef->mGenericParamDefs.size()) &&
|
(checkTypeDef->mGenericParamDefs.size() == tempTypeDef->mGenericParamDefs.size()) &&
|
||||||
|
@ -4831,8 +4831,8 @@ void BfCompiler::ProcessAutocompleteTempType()
|
||||||
{
|
{
|
||||||
for (auto baseType : checkTypeDef->mBaseTypes)
|
for (auto baseType : checkTypeDef->mBaseTypes)
|
||||||
{
|
{
|
||||||
autoComplete->CheckTypeRef(baseType, false);
|
autoComplete->CheckTypeRef(BfNodeDynCast<BfTypeReference>(baseType), false);
|
||||||
module->ResolveTypeRef(baseType);
|
module->ResolveTypeRef_Ref(baseType, BfPopulateType_Identity);
|
||||||
}
|
}
|
||||||
checkTypeDef = checkTypeDef->mOuterType;
|
checkTypeDef = checkTypeDef->mOuterType;
|
||||||
}
|
}
|
||||||
|
@ -5055,6 +5055,9 @@ void BfCompiler::ProcessAutocompleteTempType()
|
||||||
|
|
||||||
BfType* BfCompiler::CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef)
|
BfType* BfCompiler::CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef)
|
||||||
{
|
{
|
||||||
|
if (typeRef == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
//auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration,
|
//auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration,
|
||||||
//(BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue | BfResolveTypeRefFlag_AllowGenericTypeParamConstValue));
|
//(BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue | BfResolveTypeRefFlag_AllowGenericTypeParamConstValue));
|
||||||
auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowRef);
|
auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowRef);
|
||||||
|
@ -5271,7 +5274,7 @@ void BfCompiler::GetSymbolReferences()
|
||||||
SetAndRestoreValue<BfTypeState*> prevTypeState(module->mContext->mCurTypeState, &typeState);
|
SetAndRestoreValue<BfTypeState*> prevTypeState(module->mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
for (auto baseTypeRef : checkTypeDef->mBaseTypes)
|
for (auto baseTypeRef : checkTypeDef->mBaseTypes)
|
||||||
CheckSymbolReferenceTypeRef(module, baseTypeRef);
|
CheckSymbolReferenceTypeRef(module, BfNodeDynCast<BfTypeReference>(baseTypeRef));
|
||||||
|
|
||||||
for (auto genericParam : checkTypeDef->mGenericParamDefs)
|
for (auto genericParam : checkTypeDef->mGenericParamDefs)
|
||||||
{
|
{
|
||||||
|
@ -5343,7 +5346,7 @@ void BfCompiler::GetSymbolReferences()
|
||||||
if (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type)
|
if (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type)
|
||||||
{
|
{
|
||||||
for (auto baseTypeRef : typeDef->mBaseTypes)
|
for (auto baseTypeRef : typeDef->mBaseTypes)
|
||||||
CheckSymbolReferenceTypeRef(module, baseTypeRef);
|
CheckSymbolReferenceTypeRef(module, BfNodeDynCast<BfTypeReference>(baseTypeRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeState typeState;
|
BfTypeState typeState;
|
||||||
|
|
|
@ -166,6 +166,7 @@ public:
|
||||||
ResolveKind mResolveKind;
|
ResolveKind mResolveKind;
|
||||||
BfAstNode* mCurVarInitializer;
|
BfAstNode* mCurVarInitializer;
|
||||||
int mArrayInitializerSize;
|
int mArrayInitializerSize;
|
||||||
|
BfTypeInstance* mInitializerBaseType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypeState()
|
BfTypeState()
|
||||||
|
@ -185,6 +186,7 @@ public:
|
||||||
mCurVarInitializer = NULL;
|
mCurVarInitializer = NULL;
|
||||||
mArrayInitializerSize = -1;
|
mArrayInitializerSize = -1;
|
||||||
mResolveKind = ResolveKind_None;
|
mResolveKind = ResolveKind_None;
|
||||||
|
mInitializerBaseType = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeState(BfType* type, BfTypeState* prevState = NULL)
|
BfTypeState(BfType* type, BfTypeState* prevState = NULL)
|
||||||
|
@ -203,6 +205,7 @@ public:
|
||||||
mCurVarInitializer = NULL;
|
mCurVarInitializer = NULL;
|
||||||
mArrayInitializerSize = -1;
|
mArrayInitializerSize = -1;
|
||||||
mResolveKind = ResolveKind_None;
|
mResolveKind = ResolveKind_None;
|
||||||
|
mInitializerBaseType = NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1508,7 +1508,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
mCurTypeDef->mProject = mCurSource->mProject;
|
mCurTypeDef->mProject = mCurSource->mProject;
|
||||||
mCurTypeDef->mNamespace = mNamespace;
|
mCurTypeDef->mNamespace = mNamespace;
|
||||||
mSystem->AddNamespaceUsage(mCurTypeDef->mNamespace, mCurTypeDef->mProject);
|
mSystem->AddNamespaceUsage(mCurTypeDef->mNamespace, mCurTypeDef->mProject);
|
||||||
if (typeDeclaration->mTypeNode == NULL)
|
if ((typeDeclaration->mTypeNode == NULL) && (!isAnonymous))
|
||||||
{
|
{
|
||||||
mCurTypeDef->mIsPartial = true;
|
mCurTypeDef->mIsPartial = true;
|
||||||
mCurTypeDef->mIsExplicitPartial = true;
|
mCurTypeDef->mIsExplicitPartial = true;
|
||||||
|
@ -1750,7 +1750,11 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
if (typeDeclaration->mTypeNode != NULL)
|
if (typeDeclaration->mTypeNode != NULL)
|
||||||
typeToken = typeDeclaration->mTypeNode->GetToken();
|
typeToken = typeDeclaration->mTypeNode->GetToken();
|
||||||
|
|
||||||
if (typeDeclaration->mTypeNode == NULL)
|
if (typeDeclaration->IsAnonymousInitializerType())
|
||||||
|
{
|
||||||
|
mCurTypeDef->mTypeCode = BfTypeCode_Inferred;
|
||||||
|
}
|
||||||
|
else if (typeDeclaration->mTypeNode == NULL)
|
||||||
{
|
{
|
||||||
// Globals
|
// Globals
|
||||||
mCurTypeDef->mTypeCode = BfTypeCode_Struct;
|
mCurTypeDef->mTypeCode = BfTypeCode_Struct;
|
||||||
|
@ -1852,6 +1856,9 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
(checkTypeDef->mIsFunction == mCurTypeDef->mIsFunction) &&
|
(checkTypeDef->mIsFunction == mCurTypeDef->mIsFunction) &&
|
||||||
(checkTypeDef->mOuterType == actualOuterTypeDef);
|
(checkTypeDef->mOuterType == actualOuterTypeDef);
|
||||||
|
|
||||||
|
if ((mCurTypeDef->mTypeCode == BfTypeCode_Inferred) && (checkTypeDef->mTypeDeclaration->IsAnonymousInitializerType()))
|
||||||
|
isCompatible = true;
|
||||||
|
|
||||||
if (isCompatible)
|
if (isCompatible)
|
||||||
{
|
{
|
||||||
if (prevRevisionTypeDef == NULL)
|
if (prevRevisionTypeDef == NULL)
|
||||||
|
@ -1977,7 +1984,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
// Map methods into the correct index from previous revision
|
// Map methods into the correct index from previous revision
|
||||||
if (prevRevisionTypeDef != NULL)
|
if (prevRevisionTypeDef != NULL)
|
||||||
{
|
{
|
||||||
BF_ASSERT(mCurTypeDef->mTypeCode == prevRevisionTypeDef->mTypeCode);
|
BF_ASSERT((mCurTypeDef->mTypeCode == prevRevisionTypeDef->mTypeCode) || (mCurTypeDef->mTypeCode == BfTypeCode_Inferred));
|
||||||
|
|
||||||
if (mCurTypeDef->mFullHash == prevRevisionTypeDef->mFullHash)
|
if (mCurTypeDef->mFullHash == prevRevisionTypeDef->mFullHash)
|
||||||
{
|
{
|
||||||
|
@ -2280,7 +2287,8 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
needsDynamicCastMethod = false;
|
needsDynamicCastMethod = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic) && (ctorClear == NULL))
|
if (((mCurTypeDef->mTypeCode == BfTypeCode_Object) || (mCurTypeDef->mTypeCode == BfTypeCode_Inferred)) &&
|
||||||
|
(!mCurTypeDef->mIsStatic) && (ctorClear == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "", mIsComptime);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "", mIsComptime);
|
||||||
methodDef->mIsMutating = true;
|
methodDef->mIsMutating = true;
|
||||||
|
|
|
@ -301,6 +301,7 @@ void BfElementVisitor::Visit(BfInitializerExpression* initExpr)
|
||||||
|
|
||||||
VisitChild(initExpr->mTarget);
|
VisitChild(initExpr->mTarget);
|
||||||
VisitChild(initExpr->mOpenBrace);
|
VisitChild(initExpr->mOpenBrace);
|
||||||
|
VisitChild(initExpr->mInlineTypeRef);
|
||||||
for (auto& val : initExpr->mValues)
|
for (auto& val : initExpr->mValues)
|
||||||
VisitChild(val);
|
VisitChild(val);
|
||||||
for (auto& val : initExpr->mCommas)
|
for (auto& val : initExpr->mCommas)
|
||||||
|
|
|
@ -4184,7 +4184,7 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
|
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete));
|
||||||
CreateObject(NULL, stringInterpolationExpression->mAllocNode, stringType);
|
CreateObject(NULL, stringInterpolationExpression->mAllocNode, stringType, NULL);
|
||||||
}
|
}
|
||||||
BfTypedValue newString = mResult;
|
BfTypedValue newString = mResult;
|
||||||
BF_ASSERT(newString);
|
BF_ASSERT(newString);
|
||||||
|
@ -8159,6 +8159,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (refNode == NULL)
|
||||||
|
refNode = methodInstance->GetOwner()->mTypeDef->GetRefNode();
|
||||||
|
|
||||||
if ((autoComplete != NULL) && (prevNode != NULL))
|
if ((autoComplete != NULL) && (prevNode != NULL))
|
||||||
autoComplete->CheckEmptyStart(prevNode, wantType);
|
autoComplete->CheckEmptyStart(prevNode, wantType);
|
||||||
|
|
||||||
|
@ -10128,6 +10131,8 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
|
|
||||||
if (resolvedTypeInstance != NULL)
|
if (resolvedTypeInstance != NULL)
|
||||||
{
|
{
|
||||||
|
auto origTypeInstance = resolvedTypeInstance;
|
||||||
|
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0)
|
||||||
{
|
{
|
||||||
if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive()))
|
if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive()))
|
||||||
|
@ -10173,10 +10178,12 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
structInst = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeInstance, true);
|
structInst = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeInstance, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool doBind = false;
|
||||||
|
|
||||||
mResultLocalVar = NULL;
|
mResultLocalVar = NULL;
|
||||||
mResultFieldInstance = NULL;
|
mResultFieldInstance = NULL;
|
||||||
mResultLocalVarRefNode = NULL;
|
mResultLocalVarRefNode = NULL;
|
||||||
auto result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(), resolvedTypeInstance->IsObject());
|
BfTypedValue result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(), resolvedTypeInstance->IsObject());
|
||||||
if ((result) && (!result.mType->IsVoid()))
|
if ((result) && (!result.mType->IsVoid()))
|
||||||
return result;
|
return result;
|
||||||
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
||||||
|
@ -11297,7 +11304,7 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode,
|
||||||
{
|
{
|
||||||
BfType* type = NULL;
|
BfType* type = NULL;
|
||||||
{
|
{
|
||||||
type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
|
type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_IgnoreLookupError));
|
||||||
mModule->CheckTypeRefFixit(nameNode->mLeft);
|
mModule->CheckTypeRefFixit(nameNode->mLeft);
|
||||||
}
|
}
|
||||||
if (type != NULL)
|
if (type != NULL)
|
||||||
|
@ -11690,6 +11697,10 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (auto objCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(initExpr->mTarget))
|
||||||
|
{
|
||||||
|
CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL, initExpr->mInlineTypeRef);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
VisitChild(initExpr->mTarget);
|
VisitChild(initExpr->mTarget);
|
||||||
if (!mResult)
|
if (!mResult)
|
||||||
|
@ -11789,6 +11800,37 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
BfBlock* block = BfNodeDynCast<BfBlock>(elementExpr);
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
BfScopeData newScope;
|
||||||
|
|
||||||
|
if (block != NULL)
|
||||||
|
{
|
||||||
|
newScope.mInnerIsConditional = true;
|
||||||
|
newScope.mCloseNode = block;
|
||||||
|
if (block->mCloseBrace != NULL)
|
||||||
|
newScope.mCloseNode = block->mCloseBrace;
|
||||||
|
mModule->mCurMethodState->AddScope(&newScope);
|
||||||
|
mModule->NewScopeState();
|
||||||
|
|
||||||
|
BfLocalVariable* localDef = new BfLocalVariable();
|
||||||
|
localDef->mName = "_";
|
||||||
|
localDef->mResolvedType = initValue.mType;
|
||||||
|
localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
|
||||||
|
if (initValue.IsAddr())
|
||||||
|
{
|
||||||
|
localDef->mAddr = initValue.mValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localDef->mValue = initValue.mValue;
|
||||||
|
localDef->mIsSplat = initValue.IsSplat();
|
||||||
|
}
|
||||||
|
if (!localDef->mResolvedType->IsVar())
|
||||||
|
mModule->AddLocalVariableDef(localDef, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
auto autoComplete = GetAutoComplete();
|
auto autoComplete = GetAutoComplete();
|
||||||
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(elementExpr)))
|
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(elementExpr)))
|
||||||
{
|
{
|
||||||
|
@ -11804,6 +11846,12 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((block != NULL) && (!block->IsExpression()))
|
||||||
|
{
|
||||||
|
mModule->VisitCodeBlock(block);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
BfExprEvaluator exprEvaluator(mModule);
|
BfExprEvaluator exprEvaluator(mModule);
|
||||||
SizedArray<BfExpression*, 2> argExprs;
|
SizedArray<BfExpression*, 2> argExprs;
|
||||||
argExprs.push_back(elementExpr);
|
argExprs.push_back(elementExpr);
|
||||||
|
@ -11811,6 +11859,13 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
BfResolvedArgs argValues(&sizedArgExprs);
|
BfResolvedArgs argValues(&sizedArgExprs);
|
||||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||||
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
|
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block != NULL)
|
||||||
|
{
|
||||||
|
mModule->RestoreScopeState();
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
wasValidInitKind = true;
|
wasValidInitKind = true;
|
||||||
}
|
}
|
||||||
|
@ -11821,6 +11876,53 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (initExpr->mValues.IsEmpty())
|
||||||
|
{
|
||||||
|
// When we are first typing out 'override', we
|
||||||
|
if (initExpr->mInlineTypeRef != NULL)
|
||||||
|
{
|
||||||
|
if (auto defineBlock = BfNodeDynCast<BfBlock>(initExpr->mInlineTypeRef->mTypeDeclaration->mDefineNode))
|
||||||
|
{
|
||||||
|
if (defineBlock->mChildArr.mSize == 1)
|
||||||
|
{
|
||||||
|
auto lastNode = defineBlock->mChildArr[0];
|
||||||
|
if (lastNode->Equals("override"))
|
||||||
|
{
|
||||||
|
auto autoComplete = mModule->mCompiler->GetAutoComplete();
|
||||||
|
if (autoComplete != NULL)
|
||||||
|
{
|
||||||
|
int cursorIdx = autoComplete->GetCursorIdx(lastNode);
|
||||||
|
if ((autoComplete->IsAutocompleteNode(lastNode, 1)) && (cursorIdx == lastNode->GetSrcEnd()))
|
||||||
|
{
|
||||||
|
auto typeInst = initValue.mType->ToTypeInstance();
|
||||||
|
if (typeInst != NULL)
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInst(mModule->mCurTypeInstance, typeInst);
|
||||||
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInst(mModule->mCurMethodInstance, NULL);
|
||||||
|
autoComplete->AddOverrides("", true);
|
||||||
|
autoComplete->mInsertStartIdx = lastNode->mSrcStart;
|
||||||
|
autoComplete->mInsertEndIdx = lastNode->mSrcEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto lastNode = initExpr->mValues.back();
|
||||||
|
if (auto lastIdentifier = BfNodeDynCast<BfIdentifierNode>(lastNode))
|
||||||
|
{
|
||||||
|
auto autoComplete = mModule->mCompiler->GetAutoComplete();
|
||||||
|
if (autoComplete != NULL)
|
||||||
|
{
|
||||||
|
autoComplete->CheckIdentifier(lastIdentifier, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (unassignedFieldFlags != 0)
|
if (unassignedFieldFlags != 0)
|
||||||
{
|
{
|
||||||
auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
auto curBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
||||||
|
@ -15500,10 +15602,10 @@ void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode*
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
{
|
{
|
||||||
CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL);
|
CreateObject(objCreateExpr, objCreateExpr->mNewNode, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* wantAllocType)
|
void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* wantAllocType, BfInlineTypeReference* inlineTypeRef)
|
||||||
{
|
{
|
||||||
auto autoComplete = GetAutoComplete();
|
auto autoComplete = GetAutoComplete();
|
||||||
if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mTypeRef != NULL))
|
if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mTypeRef != NULL))
|
||||||
|
@ -15744,6 +15846,16 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
resolvedTypeRef = unresolvedTypeRef;
|
resolvedTypeRef = unresolvedTypeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inlineTypeRef != NULL)
|
||||||
|
{
|
||||||
|
auto inlineType = mModule->ResolveTypeRef(inlineTypeRef);
|
||||||
|
if (inlineType != NULL)
|
||||||
|
{
|
||||||
|
unresolvedTypeRef = inlineType;
|
||||||
|
resolvedTypeRef = inlineType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (resolvedTypeRef == NULL)
|
if (resolvedTypeRef == NULL)
|
||||||
{
|
{
|
||||||
unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var);
|
unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
@ -16346,7 +16458,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
BfAstNode* refNode = objCreateExpr->mTypeRef;
|
BfAstNode* refNode = objCreateExpr->mTypeRef;
|
||||||
if ((objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
|
if ((objCreateExpr->mCtorExplicit != NULL) && (objCreateExpr->mCtorExplicit->mThisToken != NULL))
|
||||||
refNode = objCreateExpr->mCtorExplicit->mThisToken;
|
refNode = objCreateExpr->mCtorExplicit->mThisToken;
|
||||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, methodGenericArguments, true);
|
auto checkTypeInst = typeInstance;
|
||||||
|
if (checkTypeInst->IsAnonymousInitializerType())
|
||||||
|
checkTypeInst = checkTypeInst->mBaseType;
|
||||||
|
MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, true);
|
||||||
if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
|
if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
|
||||||
{
|
{
|
||||||
if (autoComplete->mMethodMatchInfo != NULL)
|
if (autoComplete->mMethodMatchInfo != NULL)
|
||||||
|
@ -16360,7 +16475,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
auto refNode = allocNode;
|
auto refNode = allocNode;
|
||||||
if (objCreateExpr != NULL)
|
if (objCreateExpr != NULL)
|
||||||
refNode = objCreateExpr->mTypeRef;
|
refNode = objCreateExpr->mTypeRef;
|
||||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, methodGenericArguments, true);
|
|
||||||
|
auto checkTypeInst = typeInstance;
|
||||||
|
if (checkTypeInst->IsAnonymousInitializerType())
|
||||||
|
checkTypeInst = checkTypeInst->mBaseType;
|
||||||
|
MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, true);
|
||||||
}
|
}
|
||||||
if (objCreateExpr != NULL)
|
if (objCreateExpr != NULL)
|
||||||
mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
|
mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
|
||||||
|
@ -16470,11 +16589,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
//mModule->mBfIRBuilder->CreateMemSet(mResult.mValue, mModule->GetConstValue8(0), mModule->GetConstValue(resolvedTypeRef->mSize), resolvedTypeRef->mAlign);
|
//mModule->mBfIRBuilder->CreateMemSet(mResult.mValue, mModule->GetConstValue8(0), mModule->GetConstValue(resolvedTypeRef->mSize), resolvedTypeRef->mAlign);
|
||||||
}
|
}
|
||||||
else if (bindResult.mFunc)
|
else if (bindResult.mFunc)
|
||||||
{
|
|
||||||
if (typeInstance->IsObject())
|
|
||||||
{
|
{
|
||||||
bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime());
|
bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime());
|
||||||
|
if ((typeInstance->IsObject()) || (typeInstance->IsAnonymousInitializerType()))
|
||||||
|
{
|
||||||
bool wantsCtorClear = true;
|
bool wantsCtorClear = true;
|
||||||
if (hasRealtimeLeakCheck)
|
if (hasRealtimeLeakCheck)
|
||||||
{
|
{
|
||||||
|
@ -16497,7 +16615,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
CreateCall(objCreateExpr, ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
|
CreateCall(objCreateExpr, ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeInstance->IsObject())
|
||||||
|
{
|
||||||
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (hasRealtimeLeakCheck))
|
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (hasRealtimeLeakCheck))
|
||||||
{
|
{
|
||||||
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
||||||
|
@ -16560,23 +16681,56 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto origThisTypedValue = mResult;
|
||||||
|
auto thisTypedValue = mResult;
|
||||||
|
if (inlineTypeRef != NULL)
|
||||||
|
{
|
||||||
|
BfType* wantType = bindResult.mMethodInstance->GetOwner();
|
||||||
|
if (thisTypedValue.mType->IsPointer())
|
||||||
|
wantType = mModule->CreatePointerType(wantType);
|
||||||
|
thisTypedValue = mModule->Cast(allocNode, thisTypedValue, wantType);
|
||||||
|
}
|
||||||
|
|
||||||
if ((bindResult.mMethodInstance->mMethodDef->mHasAppend) && (mResult.mType->IsObject()))
|
if ((bindResult.mMethodInstance->mMethodDef->mHasAppend) && (mResult.mType->IsObject()))
|
||||||
{
|
{
|
||||||
BF_ASSERT(bindResult.mIRArgs[0].IsFake());
|
BF_ASSERT(bindResult.mIRArgs[0].IsFake());
|
||||||
auto typeInst = mResult.mType->ToTypeInstance();
|
auto typeInst = mResult.mType->ToTypeInstance();
|
||||||
auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
auto thisVal = mResult;
|
|
||||||
BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType);
|
BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType);
|
||||||
auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisVal.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64);
|
auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisTypedValue.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64);
|
||||||
auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(typeInst->mInstSize, intPtrType));
|
auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(typeInst->mInstSize, intPtrType));
|
||||||
mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal);
|
mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal);
|
||||||
bindResult.mIRArgs[0] = intPtrVal;
|
bindResult.mIRArgs[0] = intPtrVal;
|
||||||
}
|
}
|
||||||
if (!typeInstance->IsValuelessType())
|
if (!typeInstance->IsValuelessType())
|
||||||
bindResult.mIRArgs.Insert(0, mResult.mValue);
|
bindResult.mIRArgs.Insert(0, thisTypedValue.mValue);
|
||||||
auto result = CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
|
auto result = CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
|
||||||
if ((result) && (!result.mType->IsVoid()))
|
if ((result) && (!result.mType->IsVoid()))
|
||||||
mResult = result;
|
mResult = result;
|
||||||
|
|
||||||
|
if (origThisTypedValue.mType != thisTypedValue.mType)
|
||||||
|
{
|
||||||
|
auto origThisType = origThisTypedValue.mType;
|
||||||
|
if (origThisType->IsPointer())
|
||||||
|
origThisType = origThisType->GetUnderlyingType();
|
||||||
|
auto origThisTypeInst = origThisType->ToTypeInstance();
|
||||||
|
if (origThisTypeInst != NULL)
|
||||||
|
{
|
||||||
|
BF_ASSERT(origThisTypeInst->IsAnonymousInitializerType());
|
||||||
|
|
||||||
|
auto ctorMethod = mModule->GetMethodByName(origThisTypeInst, "__BfCtor", 0);
|
||||||
|
if (!ctorMethod)
|
||||||
|
{
|
||||||
|
mModule->AssertErrorState();
|
||||||
|
}
|
||||||
|
else if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) == 0)
|
||||||
|
{
|
||||||
|
SizedArray<BfIRValue, 1> irArgs;
|
||||||
|
irArgs.push_back(origThisTypedValue.mValue);
|
||||||
|
CreateCall(objCreateExpr, ctorMethod.mMethodInstance, ctorMethod.mFunc, false, irArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19114,6 +19268,11 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
|
void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
|
||||||
|
{
|
||||||
|
DoInvocation(invocationExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfExprEvaluator::DoInvocation(BfInvocationExpression* invocationExpr)
|
||||||
{
|
{
|
||||||
BfAutoParentNodeEntry autoParentNodeEntry(mModule, invocationExpr);
|
BfAutoParentNodeEntry autoParentNodeEntry(mModule, invocationExpr);
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,7 @@ public:
|
||||||
BfModuleMethodInstance GetSelectedMethod(BfMethodMatcher& methodMatcher);
|
BfModuleMethodInstance GetSelectedMethod(BfMethodMatcher& methodMatcher);
|
||||||
bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail);
|
bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail);
|
||||||
bool HasVariableDeclaration(BfAstNode* checkNode);
|
bool HasVariableDeclaration(BfAstNode* checkNode);
|
||||||
|
void DoInvocation(BfInvocationExpression* invocationExpr);
|
||||||
void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue = NULL);
|
void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue = NULL);
|
||||||
int GetMixinVariable();
|
int GetMixinVariable();
|
||||||
void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType);
|
void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType);
|
||||||
|
@ -538,7 +539,7 @@ public:
|
||||||
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
||||||
void CheckDotToken(BfTokenNode* tokenNode);
|
void CheckDotToken(BfTokenNode* tokenNode);
|
||||||
void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue);
|
void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue);
|
||||||
void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType);
|
void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType, BfInlineTypeReference* inlineTypeRef);
|
||||||
void HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target);
|
void HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -118,7 +118,8 @@ enum BfTypeCode : uint8
|
||||||
BfTypeCode_Int64X2,
|
BfTypeCode_Int64X2,
|
||||||
BfTypeCode_Int64X3,
|
BfTypeCode_Int64X3,
|
||||||
BfTypeCode_Int64X4,
|
BfTypeCode_Int64X4,
|
||||||
BfTypeCode_Length
|
BfTypeCode_Length,
|
||||||
|
BfTypeCode_Inferred
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfConstType
|
enum BfConstType
|
||||||
|
|
|
@ -18230,7 +18230,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero out memory for default ctor
|
// Zero out memory for default ctor
|
||||||
if ((methodDeclaration == NULL) && (mCurTypeInstance->IsStruct()) && (methodInstance->mChainType != BfMethodChainType_ChainMember) &&
|
if ((methodDeclaration == NULL) && (mCurTypeInstance->IsStruct()) && (!mCurTypeInstance->IsAnonymousInitializerType()) && (methodInstance->mChainType != BfMethodChainType_ChainMember) &&
|
||||||
(!mCurMethodState->mLocals.IsEmpty()))
|
(!mCurMethodState->mLocals.IsEmpty()))
|
||||||
{
|
{
|
||||||
if (mCurTypeInstance->IsTypedPrimitive())
|
if (mCurTypeInstance->IsTypedPrimitive())
|
||||||
|
@ -18593,6 +18593,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
targetRefNode = ctorDeclaration->mInitializer;
|
targetRefNode = ctorDeclaration->mInitializer;
|
||||||
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(targetRefNode))
|
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(targetRefNode))
|
||||||
targetRefNode = invocationExpr->mTarget;
|
targetRefNode = invocationExpr->mTarget;
|
||||||
|
if (targetRefNode == NULL)
|
||||||
|
targetRefNode = mCurTypeInstance->mTypeDef->GetRefNode();
|
||||||
|
|
||||||
if (baseCtorNode != NULL)
|
if (baseCtorNode != NULL)
|
||||||
{
|
{
|
||||||
|
@ -18687,7 +18689,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
targetType = mCurTypeInstance->mBaseType;
|
targetType = mCurTypeInstance->mBaseType;
|
||||||
if (ctorDeclaration != NULL)
|
if (ctorDeclaration != NULL)
|
||||||
targetRefNode = ctorDeclaration->mThisToken;
|
targetRefNode = ctorDeclaration->mThisToken;
|
||||||
else if (typeDef->mTypeDeclaration != NULL)
|
else if ((typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mNameNode != NULL))
|
||||||
targetRefNode = typeDef->mTypeDeclaration->mNameNode;
|
targetRefNode = typeDef->mTypeDeclaration->mNameNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18717,7 +18719,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto autoComplete = mCompiler->GetAutoComplete();
|
auto autoComplete = mCompiler->GetAutoComplete();
|
||||||
if (targetType != NULL)
|
if ((targetType != NULL) && (!mCurTypeInstance->IsAnonymousInitializerType()))
|
||||||
{
|
{
|
||||||
BfAstNode* refNode = methodDeclaration;
|
BfAstNode* refNode = methodDeclaration;
|
||||||
if (refNode == NULL)
|
if (refNode == NULL)
|
||||||
|
@ -20615,9 +20617,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
||||||
if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (methodDef->mBody != NULL) && (!mCurTypeInstance->IsBoxed()))
|
if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (methodDef->mBody != NULL) && (!mCurTypeInstance->IsBoxed()))
|
||||||
{
|
{
|
||||||
if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(methodDef->mBody))
|
if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(methodDef->mBody))
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<bool> prevSkipAnonTypes(sourceClassifier->mSkipAnonymousTypes, true);
|
||||||
sourceClassifier->VisitChildNoRef(methodDef->mBody);
|
sourceClassifier->VisitChildNoRef(methodDef->mBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BfHotDataReferenceBuilder hotDataReferenceBuilder;
|
BfHotDataReferenceBuilder hotDataReferenceBuilder;
|
||||||
BfMethodState methodState;
|
BfMethodState methodState;
|
||||||
|
@ -21733,7 +21738,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
||||||
PopulateType(mCurTypeInstance, BfPopulateType_Data);
|
PopulateType(mCurTypeInstance, BfPopulateType_Data);
|
||||||
auto thisVal = GetThis();
|
auto thisVal = GetThis();
|
||||||
int prevSize = 0;
|
int prevSize = 0;
|
||||||
if (mContext->mBfObjectType != NULL)
|
if ((mContext->mBfObjectType != NULL) && (mCurTypeInstance->IsObject()))
|
||||||
{
|
{
|
||||||
prevSize = mContext->mBfObjectType->mInstSize;
|
prevSize = mContext->mBfObjectType->mInstSize;
|
||||||
PopulateType(mContext->mBfObjectType);
|
PopulateType(mContext->mBfObjectType);
|
||||||
|
|
|
@ -1981,6 +1981,7 @@ public:
|
||||||
BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, bool resolveGenericParam = true);
|
BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, bool resolveGenericParam = true);
|
||||||
BfType* ResolveTypeRef_Type(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags& resolveFlags);
|
BfType* ResolveTypeRef_Type(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags& resolveFlags);
|
||||||
BfType* ResolveTypeRef_Ref(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags& resolveFlags);
|
BfType* ResolveTypeRef_Ref(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags& resolveFlags);
|
||||||
|
BfType* ResolveTypeRef_Ref(BfAstNode* astNode, BfPopulateType populateType);
|
||||||
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
||||||
|
|
||||||
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||||
|
|
|
@ -1660,6 +1660,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
case BfTypeCode_Interface:
|
case BfTypeCode_Interface:
|
||||||
case BfTypeCode_Enum:
|
case BfTypeCode_Enum:
|
||||||
case BfTypeCode_TypeAlias:
|
case BfTypeCode_TypeAlias:
|
||||||
|
case BfTypeCode_Inferred:
|
||||||
// Implemented below
|
// Implemented below
|
||||||
break;
|
break;
|
||||||
case BfTypeCode_Extension:
|
case BfTypeCode_Extension:
|
||||||
|
@ -4179,6 +4180,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
{
|
{
|
||||||
baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
|
baseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef, BfPopulateType_Data)->ToTypeInstance();
|
||||||
}
|
}
|
||||||
|
else if (typeDef->mTypeCode == BfTypeCode_Inferred)
|
||||||
|
baseType = mContext->mBfObjectType;
|
||||||
|
|
||||||
if (baseType != NULL)
|
if (baseType != NULL)
|
||||||
defaultBaseTypeInst = baseType->ToTypeInstance();
|
defaultBaseTypeInst = baseType->ToTypeInstance();
|
||||||
|
@ -4193,7 +4196,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
bool wantPopulateInterfaces = false;
|
bool wantPopulateInterfaces = false;
|
||||||
|
|
||||||
BfTypeReference* baseTypeRef = NULL;
|
BfAstNode* baseTypeRef = NULL;
|
||||||
if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
|
if ((typeDef->mIsDelegate) && (!typeInstance->IsClosure()))
|
||||||
{
|
{
|
||||||
if (mCompiler->mDelegateTypeDef == NULL)
|
if (mCompiler->mDelegateTypeDef == NULL)
|
||||||
|
@ -4229,7 +4232,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
|
SetAndRestoreValue<BfTypeDefineState> prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType);
|
||||||
|
|
||||||
bool populateBase = !typeInstance->mTypeFailed;
|
bool populateBase = !typeInstance->mTypeFailed;
|
||||||
BfType* checkType = checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration);
|
BfType* checkType = checkType = ResolveTypeRef_Ref(checkTypeRef, BfPopulateType_Declaration);
|
||||||
|
|
||||||
if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase))
|
if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase))
|
||||||
{
|
{
|
||||||
|
@ -4415,6 +4418,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (baseType != NULL)
|
if (baseType != NULL)
|
||||||
{
|
{
|
||||||
baseTypeInst = baseType->ToTypeInstance();
|
baseTypeInst = baseType->ToTypeInstance();
|
||||||
|
if ((baseTypeInst != NULL) && (typeDef->mTypeCode == BfTypeCode_Inferred))
|
||||||
|
typeDef->mTypeCode = baseTypeInst->mTypeDef->mTypeCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeInstance->mBaseType != NULL)
|
if (typeInstance->mBaseType != NULL)
|
||||||
|
@ -12967,6 +12972,9 @@ BfType* BfModule::ResolveTypeRef_Ref(BfAstNode* astNode, const BfSizedArray<BfAs
|
||||||
if (auto typeRef = BfNodeDynCast<BfTypeReference>(astNode))
|
if (auto typeRef = BfNodeDynCast<BfTypeReference>(astNode))
|
||||||
return ResolveTypeRef_Ref(typeRef, populateType, resolveFlags, 0);
|
return ResolveTypeRef_Ref(typeRef, populateType, resolveFlags, 0);
|
||||||
|
|
||||||
|
if (astNode->IsTemporary())
|
||||||
|
return ResolveTypeRef((BfTypeReference*)astNode, populateType, resolveFlags);
|
||||||
|
|
||||||
if ((resolveFlags & BfResolveTypeRefFlag_AllowImplicitConstExpr) != 0)
|
if ((resolveFlags & BfResolveTypeRefFlag_AllowImplicitConstExpr) != 0)
|
||||||
{
|
{
|
||||||
if (auto expr = BfNodeDynCast<BfExpression>(astNode))
|
if (auto expr = BfNodeDynCast<BfExpression>(astNode))
|
||||||
|
@ -12993,6 +13001,12 @@ BfType* BfModule::ResolveTypeRef_Ref(BfAstNode* astNode, const BfSizedArray<BfAs
|
||||||
return ResolveTypeRef_Type(astNode, genericArgs, populateType, resolveFlags);
|
return ResolveTypeRef_Type(astNode, genericArgs, populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfType* BfModule::ResolveTypeRef_Ref(BfAstNode* astNode, BfPopulateType populateType)
|
||||||
|
{
|
||||||
|
BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
|
||||||
|
return ResolveTypeRef_Ref(astNode, NULL, populateType, resolveFlags);
|
||||||
|
}
|
||||||
|
|
||||||
// This flow should mirror CastToValue
|
// This flow should mirror CastToValue
|
||||||
bool BfModule::CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
bool BfModule::CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -112,17 +112,19 @@ static int gCurFreeId;
|
||||||
int BfParseFileData::GetUniqueId(int idx)
|
int BfParseFileData::GetUniqueId(int idx)
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(gParseFileDataCrit);
|
AutoCrit autoCrit(gParseFileDataCrit);
|
||||||
while (idx >= mUniqueIDList.size())
|
|
||||||
|
int* valuePtr = NULL;
|
||||||
|
if (mUniqueIDList.TryAdd(idx, NULL, &valuePtr))
|
||||||
{
|
{
|
||||||
if (!gFreeIds.IsEmpty())
|
if (!gFreeIds.IsEmpty())
|
||||||
{
|
{
|
||||||
mUniqueIDList.Add(gFreeIds.back());
|
*valuePtr = gFreeIds.back();
|
||||||
gFreeIds.pop_back();
|
gFreeIds.pop_back();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mUniqueIDList.Add(gCurFreeId++);
|
*valuePtr = gCurFreeId++;
|
||||||
}
|
}
|
||||||
return mUniqueIDList[idx];
|
return *valuePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfParseFileData::~BfParseFileData()
|
BfParseFileData::~BfParseFileData()
|
||||||
|
@ -130,8 +132,8 @@ BfParseFileData::~BfParseFileData()
|
||||||
if (!mUniqueIDList.IsEmpty())
|
if (!mUniqueIDList.IsEmpty())
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(gParseFileDataCrit);
|
AutoCrit autoCrit(gParseFileDataCrit);
|
||||||
for (auto id : mUniqueIDList)
|
for (auto kv : mUniqueIDList)
|
||||||
gFreeIds.Add(id);
|
gFreeIds.Add(kv.mValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +444,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem
|
||||||
mTriviaStart = 0;
|
mTriviaStart = 0;
|
||||||
mParsingFailed = false;
|
mParsingFailed = false;
|
||||||
mInAsmBlock = false;
|
mInAsmBlock = false;
|
||||||
|
mCurBlockId = 0;
|
||||||
mPreprocessorIgnoredSectionNode = NULL;
|
mPreprocessorIgnoredSectionNode = NULL;
|
||||||
mPreprocessorIgnoreDepth = 0;
|
mPreprocessorIgnoreDepth = 0;
|
||||||
mAddedDependsDefines = false;
|
mAddedDependsDefines = false;
|
||||||
|
@ -856,7 +859,10 @@ BfBlock* BfParser::ParseInlineBlock(int spaceIdx, int endIdx)
|
||||||
if (startNode == NULL)
|
if (startNode == NULL)
|
||||||
startNode = childNode;
|
startNode = childNode;
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
|
{
|
||||||
block = mAlloc->Alloc<BfBlock>();
|
block = mAlloc->Alloc<BfBlock>();
|
||||||
|
block->mParserBlockId = ++mCurBlockId;
|
||||||
|
}
|
||||||
block->Add(childNode);
|
block->Add(childNode);
|
||||||
childArr.push_back(childNode);
|
childArr.push_back(childNode);
|
||||||
//block->mChildArr.Add(childNode, &mAlloc);
|
//block->mChildArr.Add(childNode, &mAlloc);
|
||||||
|
@ -3644,6 +3650,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate)
|
||||||
else*/
|
else*/
|
||||||
{
|
{
|
||||||
genBlock = mAlloc->Alloc<BfBlock>();
|
genBlock = mAlloc->Alloc<BfBlock>();
|
||||||
|
genBlock->mParserBlockId = ++mCurBlockId;
|
||||||
genBlock->mOpenBrace = (BfTokenNode*)CreateNode();
|
genBlock->mOpenBrace = (BfTokenNode*)CreateNode();
|
||||||
newBlock = genBlock;
|
newBlock = genBlock;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ enum MaybeBool
|
||||||
class BfParseFileData
|
class BfParseFileData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Array<int> mUniqueIDList;
|
Dictionary<int, int> mUniqueIDList;
|
||||||
int mRefCount;
|
int mRefCount;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -198,6 +198,7 @@ public:
|
||||||
int mLineStart;
|
int mLineStart;
|
||||||
int mLineNum;
|
int mLineNum;
|
||||||
bool mInAsmBlock;
|
bool mInAsmBlock;
|
||||||
|
int mCurBlockId;
|
||||||
|
|
||||||
BfParserFlag mParserFlags;
|
BfParserFlag mParserFlags;
|
||||||
int mCursorIdx;
|
int mCursorIdx;
|
||||||
|
|
|
@ -47,7 +47,6 @@ BfReducer::BfReducer()
|
||||||
mSystem = NULL;
|
mSystem = NULL;
|
||||||
mResolvePassData = NULL;
|
mResolvePassData = NULL;
|
||||||
mMethodDepth = 0;
|
mMethodDepth = 0;
|
||||||
mCurUniqueIdx = 0;
|
|
||||||
mDocumentCheckIdx = 0;
|
mDocumentCheckIdx = 0;
|
||||||
mTypeMemberNodeStart = NULL;
|
mTypeMemberNodeStart = NULL;
|
||||||
}
|
}
|
||||||
|
@ -110,6 +109,20 @@ bool BfReducer::IsNodeRelevant(BfAstNode* astNode)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfReducer::IsCursorInside(BfAstNode* astNode)
|
||||||
|
{
|
||||||
|
BfParser* bfParser = astNode->GetSourceData()->ToParser();
|
||||||
|
if (bfParser == NULL)
|
||||||
|
return false;
|
||||||
|
int cursorPos = bfParser->mCursorIdx;
|
||||||
|
if (cursorPos == -1)
|
||||||
|
return false;
|
||||||
|
if (astNode->Contains(cursorPos, 1, 0))
|
||||||
|
return true;
|
||||||
|
BF_ASSERT(bfParser->mParserData->mRefCount == -1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool BfReducer::IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode)
|
bool BfReducer::IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode)
|
||||||
{
|
{
|
||||||
if (startNode == NULL)
|
if (startNode == NULL)
|
||||||
|
@ -988,11 +1001,11 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int
|
||||||
hadUnexpectedIdentifier = true;
|
hadUnexpectedIdentifier = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (checkNode->Equals("tag"))
|
// if (checkNode->Equals("tag"))
|
||||||
// {
|
// {
|
||||||
// // Keep looking for tag name
|
// // Keep looking for tag name
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
{
|
{
|
||||||
hadIdentifier = true;
|
hadIdentifier = true;
|
||||||
identifierExpected = false;
|
identifierExpected = false;
|
||||||
|
@ -1837,6 +1850,45 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
exprLeft = TryCreateInitializerExpression(typeRef);
|
exprLeft = TryCreateInitializerExpression(typeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(endNodeIdx)))
|
||||||
|
{
|
||||||
|
if (tokenNode->mToken == BfToken_LParen)
|
||||||
|
{
|
||||||
|
int openCount = 1;
|
||||||
|
int checkIdx = endNodeIdx + 1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto checkNode = mVisitorPos.Get(checkIdx);
|
||||||
|
if (checkNode == NULL)
|
||||||
|
break;
|
||||||
|
if (auto checkTokenNode = BfNodeDynCast<BfTokenNode>(checkNode))
|
||||||
|
{
|
||||||
|
if (checkTokenNode->mToken == BfToken_LParen)
|
||||||
|
openCount++;
|
||||||
|
if (checkTokenNode->mToken == BfToken_RParen)
|
||||||
|
{
|
||||||
|
openCount--;
|
||||||
|
if (openCount == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto blockNode = BfNodeDynCast<BfBlock>(mVisitorPos.Get(checkIdx + 1)))
|
||||||
|
{
|
||||||
|
// If we have 'A() { ... }', that can either be an invocation with an initializer block or a
|
||||||
|
// create expression with an inline type declaration + initializer block
|
||||||
|
if (InitializerBlockHasInlineTypeDecl(blockNode))
|
||||||
|
{
|
||||||
|
exprLeft = CreateObjectCreateExpression(NULL, exprLeft);
|
||||||
|
if (auto initExpr = TryCreateInitializerExpression(exprLeft))
|
||||||
|
exprLeft = initExpr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5186,20 +5238,8 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
String name;
|
InitAnonymousType(typeDecl);
|
||||||
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>();
|
auto typeRef = mAlloc->Alloc<BfInlineTypeReference>();
|
||||||
ReplaceNode(typeDecl, typeRef);
|
ReplaceNode(typeDecl, typeRef);
|
||||||
typeRef->mTypeDeclaration = typeDecl;
|
typeRef->mTypeDeclaration = typeDecl;
|
||||||
|
@ -5297,18 +5337,18 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
|
||||||
BfTypeReference* typeRef = BfNodeDynCast<BfTypeReference>(firstNode);
|
BfTypeReference* typeRef = BfNodeDynCast<BfTypeReference>(firstNode);
|
||||||
if (typeRef == NULL)
|
if (typeRef == NULL)
|
||||||
{
|
{
|
||||||
// if (identifierNode->Equals("tag"))
|
// if (identifierNode->Equals("tag"))
|
||||||
// {
|
// {
|
||||||
// auto rightIdentifer = ExpectIdentifierAfter(identifierNode);
|
// auto rightIdentifer = ExpectIdentifierAfter(identifierNode);
|
||||||
// if (rightIdentifer != NULL)
|
// if (rightIdentifer != NULL)
|
||||||
// {
|
// {
|
||||||
// auto tagTypeRef = mAlloc->Alloc<BfTagTypeRef>();
|
// auto tagTypeRef = mAlloc->Alloc<BfTagTypeRef>();
|
||||||
// ReplaceNode(identifierNode, tagTypeRef);
|
// ReplaceNode(identifierNode, tagTypeRef);
|
||||||
// tagTypeRef->mTagNode = identifierNode;
|
// tagTypeRef->mTagNode = identifierNode;
|
||||||
// MEMBER_SET(tagTypeRef, mNameNode, rightIdentifer);
|
// MEMBER_SET(tagTypeRef, mNameNode, rightIdentifer);
|
||||||
// return tagTypeRef;
|
// return tagTypeRef;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
typeRef = DoCreateNamedTypeRef(identifierNode);
|
typeRef = DoCreateNamedTypeRef(identifierNode);
|
||||||
}
|
}
|
||||||
|
@ -7167,9 +7207,9 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf
|
||||||
|
|
||||||
BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int depth, BfAstNode* deferredHeadNode)
|
BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int depth, BfAstNode* deferredHeadNode)
|
||||||
{
|
{
|
||||||
// SetAndRestoreValue<BfAstNode*> prevTypeMemberNodeStart(mTypeMemberNodeStart, node, false);
|
// SetAndRestoreValue<BfAstNode*> prevTypeMemberNodeStart(mTypeMemberNodeStart, node, false);
|
||||||
// if (depth == 0)
|
// if (depth == 0)
|
||||||
// prevTypeMemberNodeStart.Set();
|
// prevTypeMemberNodeStart.Set();
|
||||||
|
|
||||||
if (mCurTypeDecl != NULL)
|
if (mCurTypeDecl != NULL)
|
||||||
AssertCurrentNode(node);
|
AssertCurrentNode(node);
|
||||||
|
@ -7826,6 +7866,11 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta
|
||||||
if (block == NULL)
|
if (block == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
bool allowInitializerStatement = false;
|
||||||
|
auto objectCreateExpr = BfNodeDynCast<BfObjectCreateExpression>(target);
|
||||||
|
if (objectCreateExpr != NULL)
|
||||||
|
allowInitializerStatement = true;
|
||||||
|
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
||||||
auto initializerExpr = mAlloc->Alloc<BfInitializerExpression>();
|
auto initializerExpr = mAlloc->Alloc<BfInitializerExpression>();
|
||||||
|
@ -7840,12 +7885,43 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta
|
||||||
BfDeferredAstNodeSizedArray<BfExpression*> values(initializerExpr, initializerExpr->mValues, mAlloc);
|
BfDeferredAstNodeSizedArray<BfExpression*> values(initializerExpr, initializerExpr->mValues, mAlloc);
|
||||||
BfDeferredAstNodeSizedArray<BfTokenNode*> commas(initializerExpr, initializerExpr->mCommas, mAlloc);
|
BfDeferredAstNodeSizedArray<BfTokenNode*> commas(initializerExpr, initializerExpr->mCommas, mAlloc);
|
||||||
|
|
||||||
|
int initializerStartIdx = 0;
|
||||||
|
int minTypeDeclEnd = 0;
|
||||||
|
|
||||||
BfAstNode* nextNode = NULL;
|
BfAstNode* nextNode = NULL;
|
||||||
while (!isDone)
|
while (!isDone)
|
||||||
{
|
{
|
||||||
BfAstNode* node = mVisitorPos.GetCurrent();
|
BfAstNode* node = mVisitorPos.GetCurrent();
|
||||||
|
if (node == NULL)
|
||||||
|
break;
|
||||||
initializerExpr->mSrcEnd = node->mSrcEnd;
|
initializerExpr->mSrcEnd = node->mSrcEnd;
|
||||||
|
|
||||||
|
if ((values.IsEmpty()) && (initializerExpr->mInlineTypeRef == NULL))
|
||||||
|
{
|
||||||
|
if ((allowInitializerStatement) && (!IsInitializerStatement(node)))
|
||||||
|
{
|
||||||
|
auto typeDecl = mAlloc->Alloc<BfInitializerTypeDeclaration>();
|
||||||
|
ReplaceNode(node, typeDecl);
|
||||||
|
block->mOpenBrace = NULL;
|
||||||
|
MEMBER_SET(typeDecl, mDefineNode, block);
|
||||||
|
InitAnonymousType(typeDecl);
|
||||||
|
HandleTypeDeclaration(typeDecl, NULL, NULL, true);
|
||||||
|
initializerStartIdx = mVisitorPos.mWritePos;
|
||||||
|
auto typeRef = mAlloc->Alloc<BfInlineTypeReference>();
|
||||||
|
ReplaceNode(typeDecl, typeRef);
|
||||||
|
typeRef->mTypeDeclaration = typeDecl;
|
||||||
|
MEMBER_SET(initializerExpr, mInlineTypeRef, typeRef);
|
||||||
|
|
||||||
|
if (objectCreateExpr != NULL)
|
||||||
|
{
|
||||||
|
BfDeferredAstSizedArray<BfTypeReference*> baseClasses(typeDecl->mBaseClasses, mAlloc);
|
||||||
|
baseClasses.Add(objectCreateExpr->mTypeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto expr = CreateExpression(node, BfReducer::CreateExprFlags_AllowAnonymousIndexer);
|
auto expr = CreateExpression(node, BfReducer::CreateExprFlags_AllowAnonymousIndexer);
|
||||||
isDone = !mVisitorPos.MoveNext();
|
isDone = !mVisitorPos.MoveNext();
|
||||||
if (expr != NULL)
|
if (expr != NULL)
|
||||||
|
@ -7878,6 +7954,24 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta
|
||||||
|
|
||||||
mVisitorPos.Trim();
|
mVisitorPos.Trim();
|
||||||
|
|
||||||
|
if (initializerExpr->mInlineTypeRef != NULL)
|
||||||
|
{
|
||||||
|
auto typeDecl = initializerExpr->mInlineTypeRef->mTypeDeclaration;
|
||||||
|
|
||||||
|
if (initializerStartIdx != 0)
|
||||||
|
{
|
||||||
|
block->SetSize(initializerStartIdx);
|
||||||
|
int srcEnd = block->mSrcEnd;
|
||||||
|
if (initializerStartIdx > 0)
|
||||||
|
srcEnd = block->mChildArr[initializerStartIdx - 1]->mSrcEnd;
|
||||||
|
block->mSrcEnd = srcEnd;
|
||||||
|
typeDecl->mSrcEnd = srcEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeDecl->mSrcEnd = BF_MAX(typeDecl->mSrcEnd, minTypeDeclEnd);
|
||||||
|
initializerExpr->mInlineTypeRef->mSrcEnd = typeDecl->mSrcEnd;
|
||||||
|
}
|
||||||
|
|
||||||
if (block->mCloseBrace != NULL)
|
if (block->mCloseBrace != NULL)
|
||||||
MEMBER_SET(initializerExpr, mCloseBrace, block->mCloseBrace);
|
MEMBER_SET(initializerExpr, mCloseBrace, block->mCloseBrace);
|
||||||
|
|
||||||
|
@ -8036,7 +8130,7 @@ BfCollectionInitializerExpression* BfReducer::CreateCollectionInitializerExpress
|
||||||
return arrayInitializerExpression;
|
return arrayInitializerExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfCollectionInitializerExpression * BfReducer::CreateCollectionInitializerExpression(BfTokenNode* openToken)
|
BfCollectionInitializerExpression* BfReducer::CreateCollectionInitializerExpression(BfTokenNode* openToken)
|
||||||
{
|
{
|
||||||
auto arrayInitializerExpression = mAlloc->Alloc<BfCollectionInitializerExpression>();
|
auto arrayInitializerExpression = mAlloc->Alloc<BfCollectionInitializerExpression>();
|
||||||
BfDeferredAstSizedArray<BfExpression*> values(arrayInitializerExpression->mValues, mAlloc);
|
BfDeferredAstSizedArray<BfExpression*> values(arrayInitializerExpression->mValues, mAlloc);
|
||||||
|
@ -8133,6 +8227,26 @@ BfScopedInvocationTarget* BfReducer::CreateScopedInvocationTarget(BfAstNode*& ta
|
||||||
return scopedInvocationTarget;
|
return scopedInvocationTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfReducer::InitAnonymousType(BfTypeDeclaration* typeDecl)
|
||||||
|
{
|
||||||
|
auto block = BfNodeDynCast<BfBlock>(typeDecl->mDefineNode);
|
||||||
|
|
||||||
|
String name;
|
||||||
|
auto parserData = typeDecl->GetParserData();
|
||||||
|
name = "_Anon_";
|
||||||
|
|
||||||
|
auto parseFileData = parserData->mParseFileData;
|
||||||
|
int uniqueId = parseFileData->GetUniqueId(block->mParserBlockId);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
bool BfReducer::CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes)
|
bool BfReducer::CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes)
|
||||||
{
|
{
|
||||||
if (attributes == NULL)
|
if (attributes == NULL)
|
||||||
|
@ -8410,16 +8524,6 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
|
||||||
|
|
||||||
BfTokenNode* tokenNode;
|
BfTokenNode* tokenNode;
|
||||||
|
|
||||||
// Why did we want this syntax?
|
|
||||||
// if (tokenNode = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
|
||||||
// {
|
|
||||||
// if (tokenNode->GetToken() == BfToken_Star)
|
|
||||||
// {
|
|
||||||
// MEMBER_SET(objectCreateExpr, mStarToken, tokenNode);
|
|
||||||
// mVisitorPos.MoveNext();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (typeRef == NULL)
|
if (typeRef == NULL)
|
||||||
typeRef = CreateTypeRefAfter(objectCreateExpr);
|
typeRef = CreateTypeRefAfter(objectCreateExpr);
|
||||||
if (typeRef == NULL)
|
if (typeRef == NULL)
|
||||||
|
@ -9743,7 +9847,7 @@ BfTokenNode* BfReducer::BreakQuestionLBracket(BfTokenNode* tokenNode)
|
||||||
return firstToken;
|
return firstToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfCommentNode * BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode* defNodeEnd, bool checkDocAfter)
|
BfCommentNode* BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode* defNodeEnd, bool checkDocAfter)
|
||||||
{
|
{
|
||||||
if (defNodeEnd == NULL)
|
if (defNodeEnd == NULL)
|
||||||
defNodeEnd = defNodeHead;
|
defNodeEnd = defNodeHead;
|
||||||
|
@ -10554,55 +10658,55 @@ BfGenericConstraintsDeclaration* BfReducer::CreateGenericConstraintsDeclaration(
|
||||||
bool isDone = false;
|
bool isDone = false;
|
||||||
for (int constraintIdx = 0; !isDone; constraintIdx++)
|
for (int constraintIdx = 0; !isDone; constraintIdx++)
|
||||||
{
|
{
|
||||||
// if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
// if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||||
// {
|
// {
|
||||||
// if (nextToken->mToken == BfToken_LParen)
|
// if (nextToken->mToken == BfToken_LParen)
|
||||||
// {
|
// {
|
||||||
// BfGenericConstraintExpression* genericConstraint = mAlloc->Alloc<BfGenericConstraintExpression>();
|
// BfGenericConstraintExpression* genericConstraint = mAlloc->Alloc<BfGenericConstraintExpression>();
|
||||||
// ReplaceNode(tokenNode, genericConstraint);
|
// ReplaceNode(tokenNode, genericConstraint);
|
||||||
// genericConstraint->mWhereToken = tokenNode;
|
// genericConstraint->mWhereToken = tokenNode;
|
||||||
// constraintsDeclaration->mHasExpressions = true;
|
// constraintsDeclaration->mHasExpressions = true;
|
||||||
//
|
//
|
||||||
// genericConstraintsArr.push_back(genericConstraint);
|
// genericConstraintsArr.push_back(genericConstraint);
|
||||||
//
|
//
|
||||||
// auto expr = CreateExpressionAfter(genericConstraint, CreateExprFlags_EarlyExit);
|
// auto expr = CreateExpressionAfter(genericConstraint, CreateExprFlags_EarlyExit);
|
||||||
// if (expr == NULL)
|
// if (expr == NULL)
|
||||||
// break;
|
// break;
|
||||||
//
|
//
|
||||||
// MEMBER_SET(genericConstraint, mExpression, expr);
|
// MEMBER_SET(genericConstraint, mExpression, expr);
|
||||||
//
|
//
|
||||||
// BfTokenNode* nextWhereToken = NULL;
|
// BfTokenNode* nextWhereToken = NULL;
|
||||||
// if (auto checkToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
// if (auto checkToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
|
||||||
// {
|
// {
|
||||||
// if (checkToken->mToken != BfToken_Where)
|
// if (checkToken->mToken != BfToken_Where)
|
||||||
// nextWhereToken = checkToken;
|
// nextWhereToken = checkToken;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// auto nextNode = mVisitorPos.GetNext();
|
// auto nextNode = mVisitorPos.GetNext();
|
||||||
// if (BfNodeDynCast<BfBlock>(nextNode))
|
// if (BfNodeDynCast<BfBlock>(nextNode))
|
||||||
// break;
|
// break;
|
||||||
//
|
//
|
||||||
// bool handled = false;
|
// bool handled = false;
|
||||||
// if (auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode))
|
// if (auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||||
// {
|
// {
|
||||||
// if (tokenNode->mToken == BfToken_FatArrow)
|
// if (tokenNode->mToken == BfToken_FatArrow)
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// tokenNode = ExpectTokenAfter(genericConstraint, BfToken_LBrace, BfToken_Where, BfToken_Semicolon);
|
// tokenNode = ExpectTokenAfter(genericConstraint, BfToken_LBrace, BfToken_Where, BfToken_Semicolon);
|
||||||
// if (tokenNode == NULL)
|
// if (tokenNode == NULL)
|
||||||
// break;
|
// break;
|
||||||
//
|
//
|
||||||
// BfToken token = tokenNode->GetToken();
|
// BfToken token = tokenNode->GetToken();
|
||||||
// if (token != BfToken_Where)
|
// if (token != BfToken_Where)
|
||||||
// {
|
// {
|
||||||
// mVisitorPos.mReadPos--;
|
// mVisitorPos.mReadPos--;
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
BfGenericConstraint* genericConstraint = mAlloc->Alloc<BfGenericConstraint>();
|
BfGenericConstraint* genericConstraint = mAlloc->Alloc<BfGenericConstraint>();
|
||||||
BfDeferredAstSizedArray<BfAstNode*> constraintTypes(genericConstraint->mConstraintTypes, mAlloc);
|
BfDeferredAstSizedArray<BfAstNode*> constraintTypes(genericConstraint->mConstraintTypes, mAlloc);
|
||||||
|
@ -10840,19 +10944,131 @@ void BfReducer::HandleBlock(BfBlock* block, bool allowEndingExpression)
|
||||||
mVisitorPos.Trim();
|
mVisitorPos.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfReducer::HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode)
|
bool BfReducer::IsInitializerStatement(int checkIdx)
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<int> prevReadPos(mVisitorPos.mReadPos);
|
||||||
|
|
||||||
|
int nodeCount = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
mVisitorPos.mReadPos = checkIdx;
|
||||||
|
auto checkNode = mVisitorPos.GetCurrent();
|
||||||
|
if (checkNode == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto checkToken = BfNodeDynCast<BfTokenNode>(checkNode))
|
||||||
|
{
|
||||||
|
switch (checkToken->mToken)
|
||||||
|
{
|
||||||
|
case BfToken_Dot:
|
||||||
|
if (nodeCount == 0)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case BfToken_Public:
|
||||||
|
case BfToken_Private:
|
||||||
|
case BfToken_Internal:
|
||||||
|
case BfToken_Protected:
|
||||||
|
case BfToken_This:
|
||||||
|
case BfToken_LBracket:
|
||||||
|
case BfToken_Semicolon:
|
||||||
|
case BfToken_Case:
|
||||||
|
case BfToken_Const:
|
||||||
|
case BfToken_Static:
|
||||||
|
case BfToken_TypeAlias:
|
||||||
|
case BfToken_Mixin:
|
||||||
|
case BfToken_Class:
|
||||||
|
case BfToken_Struct:
|
||||||
|
case BfToken_Enum:
|
||||||
|
case BfToken_Interface:
|
||||||
|
case BfToken_Override:
|
||||||
|
return false;
|
||||||
|
case BfToken_AssignEquals:
|
||||||
|
if (nodeCount > 0)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case BfToken_Comma:
|
||||||
|
if (nodeCount == 0)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (auto literalExpr = BfNodeDynCast<BfLiteralExpression>(checkNode))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (auto block = BfNodeDynCast<BfBlock>(checkNode))
|
||||||
|
{
|
||||||
|
if (nodeCount == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int endNode = -1;
|
||||||
|
bool coundBeExpr = false;
|
||||||
|
if (IsTypeReference(checkNode, BfToken_None, -1, &endNode, &coundBeExpr))
|
||||||
|
{
|
||||||
|
auto nextNode = mVisitorPos.Get(endNode);
|
||||||
|
if (nextNode == NULL)
|
||||||
|
{
|
||||||
|
// At end
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BfNodeIsA<BfIdentifierNode>(nextNode))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode))
|
||||||
|
{
|
||||||
|
switch (nextToken->mToken)
|
||||||
|
{
|
||||||
|
case BfToken_This:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeCount++;
|
||||||
|
checkIdx = BF_MAX(checkIdx + 1, endNode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeCount++;
|
||||||
|
checkIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BfReducer::IsInitializerStatement(BfAstNode* node)
|
||||||
|
{
|
||||||
|
AssertCurrentNode(node);
|
||||||
|
return IsInitializerStatement(mVisitorPos.mReadPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BfReducer::InitializerBlockHasInlineTypeDecl(BfBlock* block)
|
||||||
|
{
|
||||||
|
if (block->mChildArr.mSize == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(block));
|
||||||
|
return !IsInitializerStatement(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfReducer::HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode, bool findInitializer)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDecl);
|
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDecl);
|
||||||
CurTypeState curTypeState(typeDecl, mAlloc);
|
CurTypeState curTypeState(typeDecl, mAlloc);
|
||||||
SetAndRestoreValue<CurTypeState*> prevTypeState(mCurTypeState, &curTypeState);
|
SetAndRestoreValue<CurTypeState*> prevTypeState(mCurTypeState, &curTypeState);
|
||||||
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(BfNodeDynCast<BfBlock>(typeDecl->mDefineNode)));
|
SetAndRestoreValue<BfVisitorPos> prevVisitorPos(mVisitorPos, BfVisitorPos(BfNodeDynCast<BfBlock>(typeDecl->mDefineNode)));
|
||||||
|
|
||||||
|
if (findInitializer)
|
||||||
|
prevVisitorPos.CancelRestore();
|
||||||
|
|
||||||
if (attributes != NULL)
|
if (attributes != NULL)
|
||||||
{
|
{
|
||||||
MEMBER_SET(typeDecl, mAttributes, attributes);
|
MEMBER_SET(typeDecl, mAttributes, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!IsNodeRelevant(deferredHeadNode, typeDecl)) && (!typeDecl->IsTemporary()))
|
if ((!IsNodeRelevant(deferredHeadNode, typeDecl)) && (!typeDecl->IsTemporary()) && (!findInitializer))
|
||||||
{
|
{
|
||||||
typeDecl->mIgnoreDeclaration = true;
|
typeDecl->mIgnoreDeclaration = true;
|
||||||
return;
|
return;
|
||||||
|
@ -10874,6 +11090,13 @@ void BfReducer::HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDi
|
||||||
BfAstNode* typeMember = BfNodeDynCast<BfMemberDeclaration>(node);
|
BfAstNode* typeMember = BfNodeDynCast<BfMemberDeclaration>(node);
|
||||||
if (typeMember == NULL)
|
if (typeMember == NULL)
|
||||||
{
|
{
|
||||||
|
if (findInitializer)
|
||||||
|
{
|
||||||
|
bool isInitializerStatement = IsInitializerStatement(node);
|
||||||
|
if (isInitializerStatement)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SetAndRestoreValue<BfAstNode*> prevTypeMemberNodeStart(mTypeMemberNodeStart, node);
|
SetAndRestoreValue<BfAstNode*> prevTypeMemberNodeStart(mTypeMemberNodeStart, node);
|
||||||
typeMember = ReadTypeMember(node);
|
typeMember = ReadTypeMember(node);
|
||||||
}
|
}
|
||||||
|
@ -11397,7 +11620,7 @@ BfInlineAsmStatement* BfReducer::CreateInlineAsmStatement(BfAstNode* asmNode)
|
||||||
instrNodes.Clear();
|
instrNodes.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto & instNode : dstInstructions)
|
for (auto& instNode : dstInstructions)
|
||||||
MoveNode(instNode, asmStatement);
|
MoveNode(instNode, asmStatement);
|
||||||
asmStatement->mInstructions = std::move(dstInstructions);
|
asmStatement->mInstructions = std::move(dstInstructions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,6 @@ public:
|
||||||
BfAstNode* mTypeMemberNodeStart;
|
BfAstNode* mTypeMemberNodeStart;
|
||||||
int mClassDepth;
|
int mClassDepth;
|
||||||
int mMethodDepth;
|
int mMethodDepth;
|
||||||
int mCurUniqueIdx;
|
|
||||||
BfTypeDeclaration* mCurTypeDecl;
|
BfTypeDeclaration* mCurTypeDecl;
|
||||||
CurTypeState* mCurTypeState;
|
CurTypeState* mCurTypeState;
|
||||||
BfTypeDeclaration* mLastTypeDecl;
|
BfTypeDeclaration* mLastTypeDecl;
|
||||||
|
@ -211,10 +210,12 @@ public:
|
||||||
|
|
||||||
void AssertCurrentNode(BfAstNode* node);
|
void AssertCurrentNode(BfAstNode* node);
|
||||||
bool IsNodeRelevant(BfAstNode* astNode);
|
bool IsNodeRelevant(BfAstNode* astNode);
|
||||||
|
bool IsCursorInside(BfAstNode* astNode);
|
||||||
bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode);
|
bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode);
|
||||||
void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
|
void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
|
||||||
void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
|
void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
|
||||||
|
|
||||||
|
void InitAnonymousType(BfTypeDeclaration* typeDecl);
|
||||||
bool CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes);
|
bool CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes);
|
||||||
void CheckMultiuseAttributeTypeRef(BfAstNode* typeRef);
|
void CheckMultiuseAttributeTypeRef(BfAstNode* typeRef);
|
||||||
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
|
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
|
||||||
|
@ -280,7 +281,10 @@ public:
|
||||||
BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
|
BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
|
||||||
|
|
||||||
void HandleBlock(BfBlock* block, bool allowEndingExpression = false);
|
void HandleBlock(BfBlock* block, bool allowEndingExpression = false);
|
||||||
void HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL);
|
bool IsInitializerStatement(int checkIdx);
|
||||||
|
bool IsInitializerStatement(BfAstNode* node);
|
||||||
|
bool InitializerBlockHasInlineTypeDecl(BfBlock* block);
|
||||||
|
void HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL, bool findInitializer = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfReducer();
|
BfReducer();
|
||||||
|
|
|
@ -2455,6 +2455,11 @@ bool BfTypeInstance::IsAnonymous()
|
||||||
return (mTypeDef->mTypeDeclaration != NULL) && (mTypeDef->mTypeDeclaration->IsAnonymous());
|
return (mTypeDef->mTypeDeclaration != NULL) && (mTypeDef->mTypeDeclaration->IsAnonymous());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfTypeInstance::IsAnonymousInitializerType()
|
||||||
|
{
|
||||||
|
return (mTypeDef->mTypeDeclaration != NULL) && (mTypeDef->mTypeDeclaration->IsAnonymousInitializerType());
|
||||||
|
}
|
||||||
|
|
||||||
void BfTypeInstance::ReportMemory(MemReporter* memReporter)
|
void BfTypeInstance::ReportMemory(MemReporter* memReporter)
|
||||||
{
|
{
|
||||||
if (mGenericTypeInfo != NULL)
|
if (mGenericTypeInfo != NULL)
|
||||||
|
|
|
@ -2206,6 +2206,7 @@ public:
|
||||||
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();
|
bool IsAnonymous();
|
||||||
|
bool IsAnonymousInitializerType();
|
||||||
|
|
||||||
virtual void ReportMemory(MemReporter* memReporter) override;
|
virtual void ReportMemory(MemReporter* memReporter) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@ BfSourceClassifier::BfSourceClassifier(BfParser* bfParser, CharData* charData)
|
||||||
mPrevNode = NULL;
|
mPrevNode = NULL;
|
||||||
mCurMember = NULL;
|
mCurMember = NULL;
|
||||||
mCurLocalMethodDeclaration = NULL;
|
mCurLocalMethodDeclaration = NULL;
|
||||||
|
mSkipAnonymousTypes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfSourceClassifier::ModifyFlags(BfAstNode* node, uint8 andFlags, uint8 orFlags)
|
void BfSourceClassifier::ModifyFlags(BfAstNode* node, uint8 andFlags, uint8 orFlags)
|
||||||
|
@ -657,6 +658,9 @@ void BfSourceClassifier::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||||
|
|
||||||
void BfSourceClassifier::Visit(BfTypeDeclaration* typeDeclaration)
|
void BfSourceClassifier::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
{
|
{
|
||||||
|
if ((mSkipAnonymousTypes) && (typeDeclaration->IsAnonymous()))
|
||||||
|
return;
|
||||||
|
|
||||||
if (typeDeclaration->mIgnoreDeclaration)
|
if (typeDeclaration->mIgnoreDeclaration)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
bool mSkipAttributes;
|
bool mSkipAttributes;
|
||||||
bool mIsSideChannel;
|
bool mIsSideChannel;
|
||||||
bool mPreserveFlags;
|
bool mPreserveFlags;
|
||||||
|
bool mSkipAnonymousTypes;
|
||||||
uint8 mClassifierPassId;
|
uint8 mClassifierPassId;
|
||||||
BfAstNode* mPrevNode;
|
BfAstNode* mPrevNode;
|
||||||
BfAstNode* mCurMember;
|
BfAstNode* mCurMember;
|
||||||
|
|
|
@ -3044,7 +3044,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
|
|
||||||
typeDef->mProtection = nextTypeDef->mProtection;
|
typeDef->mProtection = nextTypeDef->mProtection;
|
||||||
|
|
||||||
BF_ASSERT(typeDef->mTypeCode == nextTypeDef->mTypeCode);
|
BF_ASSERT((typeDef->mTypeCode == nextTypeDef->mTypeCode) || (nextTypeDef->mTypeCode == BfTypeCode_Inferred));
|
||||||
|
|
||||||
typeDef->mTypeCode = nextTypeDef->mTypeCode;
|
typeDef->mTypeCode = nextTypeDef->mTypeCode;
|
||||||
typeDef->mShow = nextTypeDef->mShow;
|
typeDef->mShow = nextTypeDef->mShow;
|
||||||
|
|
|
@ -30,6 +30,21 @@ class Anonymous
|
||||||
} mCoords;
|
} mCoords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructC
|
||||||
|
{
|
||||||
|
public int mA;
|
||||||
|
|
||||||
|
public this(int a)
|
||||||
|
{
|
||||||
|
mA = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassA
|
||||||
|
{
|
||||||
|
public int Val = 123;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -47,5 +62,28 @@ class Anonymous
|
||||||
StructB sb = default;
|
StructB sb = default;
|
||||||
sb.mX = 345;
|
sb.mX = 345;
|
||||||
Test.Assert(sb.mY == 345);
|
Test.Assert(sb.mY == 345);
|
||||||
|
|
||||||
|
var sc = StructC(456)
|
||||||
|
{
|
||||||
|
public int mB = 567;
|
||||||
|
|
||||||
|
{
|
||||||
|
_.mB += 1000;
|
||||||
|
},
|
||||||
|
mB += 10000
|
||||||
|
};
|
||||||
|
Test.Assert(sc.mA == 456);
|
||||||
|
Test.Assert(sc.mB == 11567);
|
||||||
|
|
||||||
|
var ca = scope ClassA()
|
||||||
|
{
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
strBuffer.Append("ClassA override");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var str = ca.ToString(.. scope .());
|
||||||
|
Test.Assert(str == "ClassA override");
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue