mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fixed atom deletion issue
This commit is contained in:
parent
2130b7d60c
commit
27a586df04
9 changed files with 133 additions and 18 deletions
5
IDE/Tests/BugW006/BeefProj.toml
Normal file
5
IDE/Tests/BugW006/BeefProj.toml
Normal file
|
@ -0,0 +1,5 @@
|
|||
FileVersion = 1
|
||||
|
||||
[Project]
|
||||
Name = "Bug"
|
||||
StartupObject = "Bug.Program"
|
6
IDE/Tests/BugW006/BeefSpace.toml
Normal file
6
IDE/Tests/BugW006/BeefSpace.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
FileVersion = 1
|
||||
Projects = {Bug = {Path = "."}}
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "Bug"
|
||||
|
25
IDE/Tests/BugW006/scripts/Test.txt
Normal file
25
IDE/Tests/BugW006/scripts/Test.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
# This tests that types that fail generic tests don't create types referenced in methods
|
||||
# and also that they get deleted immediately when they are dereferenced.
|
||||
|
||||
ShowFile("src/Program.bf")
|
||||
|
||||
GotoText("//Test_Y")
|
||||
AdjustCursor(16, 1)
|
||||
InsertText(" abc")
|
||||
Sleep(500)
|
||||
InsertText(", in")
|
||||
Sleep(500)
|
||||
InsertText("t def")
|
||||
|
||||
Compile()
|
||||
|
||||
DeleteTextBackward(5)
|
||||
Sleep(500)
|
||||
DeleteTextBackward(4)
|
||||
Sleep(500)
|
||||
DeleteTextBackward(4)
|
||||
Sleep(500)
|
||||
ToggleCommentAt("Test_Definition")
|
||||
|
||||
Sleep(500)
|
||||
Compile()
|
25
IDE/Tests/BugW006/src/Program.bf
Normal file
25
IDE/Tests/BugW006/src/Program.bf
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Bug
|
||||
{
|
||||
class Program
|
||||
{
|
||||
//*Test_Definition
|
||||
public class Test<T, K> where K: enum
|
||||
{
|
||||
typealias x = function void (T t);
|
||||
//Test_Y
|
||||
typealias y = (K);
|
||||
}
|
||||
/*@*/
|
||||
|
||||
|
||||
public static int Main(String[] args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2172,6 +2172,16 @@ namespace IDE
|
|||
textPanel.EditWidget.mEditWidgetContent.DeleteSelection();
|
||||
}
|
||||
|
||||
[IDECommand]
|
||||
public void DeleteTextBackward(int count)
|
||||
{
|
||||
var textPanel = GetActiveTextPanel();
|
||||
if (textPanel == null)
|
||||
return;
|
||||
for (int i < count)
|
||||
textPanel.EditWidget.mEditWidgetContent.Backspace();
|
||||
}
|
||||
|
||||
[IDECommand]
|
||||
public void MarkPosition()
|
||||
{
|
||||
|
|
|
@ -2159,23 +2159,30 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
|
|||
// If any atoms have been placed in the graveyard, typesHash will be zero and thus cause a rebuild
|
||||
uint32 atomUpdateIdx = lookupEntry.mName.GetAtomUpdateIdx();
|
||||
|
||||
// Sanity check, mostly checking that useTypeDef wasn't deleted
|
||||
BF_ASSERT((lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx >= 1) && (lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx <= mSystem->mAtomUpdateIdx));
|
||||
|
||||
// Only do the actual lookup if types were added or removed whose name is contained in one of the name parts referenced
|
||||
if (atomUpdateIdx != lookupEntry.mAtomUpdateIdx)
|
||||
if (atomUpdateIdx == 0)
|
||||
{
|
||||
// NOTE: we purposely don't use mNextRevision here. If the the was NOT rebuilt then that means we didn't actually rebuild
|
||||
// so the mNextRevision will be ignored
|
||||
auto useTypeDef = lookupEntry.mUseTypeDef;
|
||||
BfTypeDef* ambiguousTypeDef = NULL;
|
||||
BfTypeDef* result = mSystem->FindTypeDef(lookupEntry.mName, lookupEntry.mNumGenericParams, useTypeDef->mProject, useTypeDef->mNamespaceSearch, &ambiguousTypeDef);
|
||||
if (result != lookupEntryPair.mValue.mTypeDef)
|
||||
{
|
||||
isDirty = true;
|
||||
isDirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sanity check, mostly checking that useTypeDef wasn't deleted
|
||||
BF_ASSERT((lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx >= 1) && (lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx <= mSystem->mAtomUpdateIdx));
|
||||
|
||||
// Only do the actual lookup if types were added or removed whose name is contained in one of the name parts referenced
|
||||
if (atomUpdateIdx != lookupEntry.mAtomUpdateIdx)
|
||||
{
|
||||
// NOTE: we purposely don't use mNextRevision here. If the the was NOT rebuilt then that means we didn't actually rebuild
|
||||
// so the mNextRevision will be ignored
|
||||
auto useTypeDef = lookupEntry.mUseTypeDef;
|
||||
BfTypeDef* ambiguousTypeDef = NULL;
|
||||
BfTypeDef* result = mSystem->FindTypeDef(lookupEntry.mName, lookupEntry.mNumGenericParams, useTypeDef->mProject, useTypeDef->mNamespaceSearch, &ambiguousTypeDef);
|
||||
if (result != lookupEntryPair.mValue.mTypeDef)
|
||||
{
|
||||
isDirty = true;
|
||||
}
|
||||
else
|
||||
lookupEntry.mAtomUpdateIdx = atomUpdateIdx;
|
||||
}
|
||||
else
|
||||
lookupEntry.mAtomUpdateIdx = atomUpdateIdx;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,8 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
|
|||
BfAtom::~BfAtom()
|
||||
{
|
||||
BF_ASSERT(mPrevNamesMap.IsEmpty());
|
||||
BF_ASSERT(mRefCount == 0);
|
||||
BF_ASSERT(mPendingDerefCount == 0);
|
||||
}
|
||||
|
||||
void BfAtom::Ref()
|
||||
|
@ -360,7 +362,7 @@ uint32 BfAtomComposite::GetAtomUpdateIdx()
|
|||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
auto atom = mParts[i];
|
||||
if (atom->mRefCount == 0)
|
||||
if ((atom->mRefCount - atom->mPendingDerefCount) == 0)
|
||||
return 0; // 0 is our "error condition" when we're looking at a graveyard'ed atom
|
||||
updateIdx = BF_MAX(updateIdx, atom->mAtomUpdateIdx);
|
||||
}
|
||||
|
@ -618,6 +620,12 @@ void BfTypeDef::FreeMembers()
|
|||
{
|
||||
if (!mIsNextRevision)
|
||||
mSystem->UntrackName(this);
|
||||
if (mInDeleteQueue)
|
||||
{
|
||||
BF_ASSERT(mName->mPendingDerefCount > 0);
|
||||
if (mName->mPendingDerefCount > 0)
|
||||
mName->mPendingDerefCount--;
|
||||
}
|
||||
mSystem->ReleaseAtom(mName);
|
||||
}
|
||||
mName = NULL;
|
||||
|
@ -625,6 +633,12 @@ void BfTypeDef::FreeMembers()
|
|||
|
||||
if (mNameEx != NULL)
|
||||
{
|
||||
if (mInDeleteQueue)
|
||||
{
|
||||
BF_ASSERT(mNameEx->mPendingDerefCount > 0);
|
||||
if (mNameEx->mPendingDerefCount > 0)
|
||||
mNameEx->mPendingDerefCount--;
|
||||
}
|
||||
mSystem->ReleaseAtom(mNameEx);
|
||||
mNameEx = NULL;
|
||||
}
|
||||
|
@ -1854,6 +1868,7 @@ BfAtom* BfSystem::GetAtom(const StringImpl& string)
|
|||
atom->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
||||
atom->mString = *stringPtr;
|
||||
atom->mRefCount = 1;
|
||||
atom->mPendingDerefCount = 0;
|
||||
|
||||
atom->mHash = 0;
|
||||
for (char c : string)
|
||||
|
@ -2496,6 +2511,21 @@ void BfSystem::RemoveTypeDef(BfTypeDef* typeDef)
|
|||
// mTypeDef is already locked by the system lock
|
||||
mTypeDefs.Remove(typeDef);
|
||||
AutoCrit autoCrit(mDataLock);
|
||||
|
||||
// This will get properly handled in UntrackName when we process the mTypeDefDeleteQueue, but this
|
||||
// mAtomUpdateIdx increment will trigger lookup changes in BfContext::VerifyTypeLookups
|
||||
if (typeDef->mName != mEmptyAtom)
|
||||
{
|
||||
typeDef->mName->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
||||
typeDef->mName->mPendingDerefCount++;
|
||||
}
|
||||
if (typeDef->mNameEx != mEmptyAtom)
|
||||
{
|
||||
typeDef->mNameEx->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
||||
typeDef->mNameEx->mPendingDerefCount++;
|
||||
}
|
||||
typeDef->mInDeleteQueue = true;
|
||||
|
||||
mTypeDefDeleteQueue.push_back(typeDef);
|
||||
mTypeMapVersion++;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ class BfAtom
|
|||
{
|
||||
public:
|
||||
StringView mString;
|
||||
int mRefCount;
|
||||
int mRefCount;
|
||||
int mPendingDerefCount;
|
||||
int mHash;
|
||||
uint32 mAtomUpdateIdx;
|
||||
bool mIsSystemType;
|
||||
|
@ -929,7 +930,8 @@ public:
|
|||
bool mHasExtensionMethods;
|
||||
bool mHasOverrideMethods;
|
||||
bool mIsOpaque;
|
||||
bool mIsNextRevision;
|
||||
bool mIsNextRevision;
|
||||
bool mInDeleteQueue;
|
||||
|
||||
public:
|
||||
BfTypeDef()
|
||||
|
@ -969,6 +971,7 @@ public:
|
|||
mIsOpaque = false;
|
||||
mPartialUsed = false;
|
||||
mIsNextRevision = false;
|
||||
mInDeleteQueue = false;
|
||||
mDupDetectedRevision = -1;
|
||||
mNestDepth = 0;
|
||||
mOuterType = NULL;
|
||||
|
|
|
@ -59,6 +59,10 @@ PUSHD %~dp0..\
|
|||
@CALL :TEST
|
||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||
|
||||
@SET TESTPATH=IDE\Tests\BugW006
|
||||
@CALL :TEST
|
||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||
|
||||
@SET TESTPATH=IDE\Tests\IndentTest
|
||||
@CALL :TEST
|
||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue