1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Anonymous subclassing in initializer blocks

This commit is contained in:
Brian Fiete 2025-01-04 10:57:37 -08:00
parent 01c2c35fc3
commit a5e9a33f64
25 changed files with 1111 additions and 608 deletions

View file

@ -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()

View file

@ -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:

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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;
} }
}; };

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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)
{ {

View file

@ -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;
} }

View file

@ -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;

View file

@ -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)
@ -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;
@ -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);
@ -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)
@ -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);
} }

View file

@ -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();

View file

@ -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)

View file

@ -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;
}; };

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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");
} }
} }