diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index f32e9e6e..4c1fa69c 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -11544,8 +11544,6 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) BfTypedValue initValue = GetResult(true); bool isFirstAdd = true; - BfFunctionBindResult addFunctionBindResult; - addFunctionBindResult.mWantsArgs = true; for (auto elementExpr : initExpr->mValues) { @@ -11604,6 +11602,26 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) findName.c_str()), identifierNode); } } + else if (auto indexerExpression = BfNodeDynCast(assignExpr->mLeft)) + { + if (indexerExpression->mTarget == NULL) + { + if ((initValue.mType->IsValueType()) && (!initValue.IsAddr())) + { + initValue = mModule->MakeAddressable(initValue, true, true); + } + + mResult = BfTypedValue(); + HandleIndexerExpression(indexerExpression, initValue); + wasValidInitKind = true; + + if ((mPropDef) || (mResult)) + { + PerformAssignment(assignExpr, true, BfTypedValue()); + mResult = BfTypedValue(); + } + } + } } else { @@ -11622,40 +11640,13 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) } } - bool wasFirstAdd = isFirstAdd; - if (isFirstAdd) - { - BfExprEvaluator exprEvaluator(mModule); - exprEvaluator.mFunctionBindResult = &addFunctionBindResult; - SizedArray argExprs; - argExprs.push_back(elementExpr); - BfSizedArray sizedArgExprs(argExprs); - BfResolvedArgs argValues(&sizedArgExprs); - exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval); - exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments()); - - if (addFunctionBindResult.mMethodInstance != NULL) - CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs); - - isFirstAdd = false; - } - else if ((addFunctionBindResult.mMethodInstance == NULL) || (addFunctionBindResult.mMethodInstance->GetParamCount() == 0)) - { - mModule->CreateValueFromExpression(elementExpr, NULL, (BfEvalExprFlags)(mBfEvalExprFlags& BfEvalExprFlags_InheritFlags)); - } - else - { - auto argValue = mModule->CreateValueFromExpression(elementExpr, addFunctionBindResult.mMethodInstance->GetParamType(0), (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); - if ((argValue) && (!mModule->mBfIRBuilder->mIgnoreWrites)) - { - SizedArray irArgs; - PushThis(elementExpr, initValue, addFunctionBindResult.mMethodInstance, irArgs); - PushArg(argValue, irArgs); - for (int argIdx = (int)irArgs.size(); argIdx < (int)addFunctionBindResult.mIRArgs.size(); argIdx++) - irArgs.Add(addFunctionBindResult.mIRArgs[argIdx]); - CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, irArgs); - } - } + BfExprEvaluator exprEvaluator(mModule); + SizedArray argExprs; + argExprs.push_back(elementExpr); + BfSizedArray sizedArgExprs(argExprs); + BfResolvedArgs argValues(&sizedArgExprs); + exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval); + exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments()); wasValidInitKind = true; } @@ -21664,30 +21655,38 @@ void BfExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) { - BfTypedValue target; + HandleIndexerExpression(indexerExpr, BfTypedValue()); +} + +void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target) +{ bool wantStatic = false; // Try first as a non-static indexer, then as a static indexer - for (int pass = 0; pass < 2; pass++) - { - /// - { - SetAndRestoreValue prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0); - VisitChild(indexerExpr->mTarget); - } - ResolveGenericType(); - target = GetResult(true); - if (target) - break; - if (pass == 0) + if (!target) + { + for (int pass = 0; pass < 2; pass++) { - SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0)); - auto staticType = mModule->ResolveTypeRef(indexerExpr->mTarget, {}); - if (staticType != NULL) + /// { - wantStatic = true; - target.mType = staticType; + SetAndRestoreValue prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0); + VisitChild(indexerExpr->mTarget); + } + ResolveGenericType(); + target = GetResult(true); + if (target) break; + + if (pass == 0) + { + SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0)); + auto staticType = mModule->ResolveTypeRef(indexerExpr->mTarget, {}); + if (staticType != NULL) + { + wantStatic = true; + target.mType = staticType; + break; + } } } } diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 26d15042..07c6add9 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -538,6 +538,7 @@ public: void CheckDotToken(BfTokenNode* tokenNode); void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue); void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType); + void HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target); ////////////////////////////////////////////////////////////////////////// diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index 52dc70be..089e6222 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -2093,7 +2093,12 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } else if (token == BfToken_LBracket) { - exprLeft = CreateAttributedExpression(tokenNode, false); + if ((createExprFlags & CreateExprFlags_AllowAnonymousIndexer) != 0) + { + exprLeft = CreateIndexerExpression(NULL, tokenNode); + } + else + exprLeft = CreateAttributedExpression(tokenNode, false); } else if (token == BfToken_FatArrow) { @@ -7570,7 +7575,7 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta BfAstNode* node = mVisitorPos.GetCurrent(); initializerExpr->mSrcEnd = node->mSrcEnd; - auto expr = CreateExpression(node); + auto expr = CreateExpression(node, BfReducer::CreateExprFlags_AllowAnonymousIndexer); isDone = !mVisitorPos.MoveNext(); if (expr != NULL) values.Add(expr); @@ -8167,15 +8172,24 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all return objectCreateExpr; } -BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target) +BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target, BfTokenNode* openBracketNode) { - auto tokenNode = ExpectTokenAfter(target, BfToken_LBracket, BfToken_QuestionLBracket); + auto tokenNode = openBracketNode; + if (openBracketNode == NULL) + tokenNode = ExpectTokenAfter(target, BfToken_LBracket, BfToken_QuestionLBracket); auto indexerExpr = mAlloc->Alloc(); BfDeferredAstSizedArray arguments(indexerExpr->mArguments, mAlloc); BfDeferredAstSizedArray commas(indexerExpr->mCommas, mAlloc); - indexerExpr->mTarget = target; - ReplaceNode(target, indexerExpr); + if (target != NULL) + { + indexerExpr->mTarget = target; + ReplaceNode(target, indexerExpr); + } + else + { + ReplaceNode(openBracketNode, indexerExpr); + } indexerExpr->mOpenBracket = tokenNode; MoveNode(indexerExpr->mOpenBracket, indexerExpr); diff --git a/IDEHelper/Compiler/BfReducer.h b/IDEHelper/Compiler/BfReducer.h index 5b2ec940..f40127ee 100644 --- a/IDEHelper/Compiler/BfReducer.h +++ b/IDEHelper/Compiler/BfReducer.h @@ -27,7 +27,8 @@ public: CreateExprFlags_NoCheckBinOpPrecedence = 0x100, CreateExprFlags_BreakOnCascade = 0x200, CreateExprFlags_EarlyExit = 0x400, // Don't attempt binary or ternary operations - CreateExprFlags_AllowEmpty = 0x800 + CreateExprFlags_AllowEmpty = 0x800, + CreateExprFlags_AllowAnonymousIndexer = 0x1000 }; enum CreateStmtFlags @@ -206,7 +207,7 @@ public: BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken); BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None); BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target); - BfExpression* CreateIndexerExpression(BfExpression* target); + BfExpression* CreateIndexerExpression(BfExpression* target, BfTokenNode* openBracketNode = NULL); BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target); BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL); BfExpression* CreateExpression(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None); diff --git a/IDEHelper/Tests/src/Extensions.bf b/IDEHelper/Tests/src/Extensions.bf index 961a2bae..696660cf 100644 --- a/IDEHelper/Tests/src/Extensions.bf +++ b/IDEHelper/Tests/src/Extensions.bf @@ -18,7 +18,7 @@ namespace System.Collections } } - extension Dictionary + extension Dictionary { public static bool operator==(Self lhs, Self rhs) { diff --git a/IDEHelper/Tests/src/Generics.bf b/IDEHelper/Tests/src/Generics.bf index d6c88192..b53a77b1 100644 --- a/IDEHelper/Tests/src/Generics.bf +++ b/IDEHelper/Tests/src/Generics.bf @@ -420,6 +420,10 @@ namespace Tests list.Sort(); List floatList = scope .() {1, 2, 3}; + Dictionary dict = scope .() { (1, "Foo"), [2]="Bar" }; + Test.Assert(dict[1] == "Foo"); + Test.Assert(dict[2] == "Bar"); + ClassA ca = scope .(); ClassB cb = scope .(); Test.Assert(LibA.LibA0.GetVal(ca) == 123); diff --git a/IDEHelper/Tests/src/Initializers.bf b/IDEHelper/Tests/src/Initializers.bf index d9633706..647e6c25 100644 --- a/IDEHelper/Tests/src/Initializers.bf +++ b/IDEHelper/Tests/src/Initializers.bf @@ -25,9 +25,9 @@ namespace Tests mD += (int)val2 * 10; } - public void Add(int val) + public void Add(int val) mut { - Test.FatalError("Shouldn't be called"); + mD += (int)val * 1000; } } @@ -38,7 +38,7 @@ namespace Tests Test.Assert(sa.mA == 123); Test.Assert(sa.mB == 345); Test.Assert(sa.mC == 456); - Test.Assert(sa.mD == 6036); + Test.Assert(sa.mD == 791907); } } }