mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +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();
|
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]
|
[IDECommand]
|
||||||
public void MarkPosition()
|
public void MarkPosition()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2159,6 +2159,12 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
|
||||||
// If any atoms have been placed in the graveyard, typesHash will be zero and thus cause a rebuild
|
// If any atoms have been placed in the graveyard, typesHash will be zero and thus cause a rebuild
|
||||||
uint32 atomUpdateIdx = lookupEntry.mName.GetAtomUpdateIdx();
|
uint32 atomUpdateIdx = lookupEntry.mName.GetAtomUpdateIdx();
|
||||||
|
|
||||||
|
if (atomUpdateIdx == 0)
|
||||||
|
{
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Sanity check, mostly checking that useTypeDef wasn't deleted
|
// Sanity check, mostly checking that useTypeDef wasn't deleted
|
||||||
BF_ASSERT((lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx >= 1) && (lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx <= mSystem->mAtomUpdateIdx));
|
BF_ASSERT((lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx >= 1) && (lookupEntry.mUseTypeDef->mName->mAtomUpdateIdx <= mSystem->mAtomUpdateIdx));
|
||||||
|
|
||||||
|
@ -2178,6 +2184,7 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
|
||||||
lookupEntry.mAtomUpdateIdx = atomUpdateIdx;
|
lookupEntry.mAtomUpdateIdx = atomUpdateIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isDirty)
|
if (isDirty)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,6 +103,8 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
|
||||||
BfAtom::~BfAtom()
|
BfAtom::~BfAtom()
|
||||||
{
|
{
|
||||||
BF_ASSERT(mPrevNamesMap.IsEmpty());
|
BF_ASSERT(mPrevNamesMap.IsEmpty());
|
||||||
|
BF_ASSERT(mRefCount == 0);
|
||||||
|
BF_ASSERT(mPendingDerefCount == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfAtom::Ref()
|
void BfAtom::Ref()
|
||||||
|
@ -360,7 +362,7 @@ uint32 BfAtomComposite::GetAtomUpdateIdx()
|
||||||
for (int i = 0; i < mSize; i++)
|
for (int i = 0; i < mSize; i++)
|
||||||
{
|
{
|
||||||
auto atom = mParts[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
|
return 0; // 0 is our "error condition" when we're looking at a graveyard'ed atom
|
||||||
updateIdx = BF_MAX(updateIdx, atom->mAtomUpdateIdx);
|
updateIdx = BF_MAX(updateIdx, atom->mAtomUpdateIdx);
|
||||||
}
|
}
|
||||||
|
@ -618,6 +620,12 @@ void BfTypeDef::FreeMembers()
|
||||||
{
|
{
|
||||||
if (!mIsNextRevision)
|
if (!mIsNextRevision)
|
||||||
mSystem->UntrackName(this);
|
mSystem->UntrackName(this);
|
||||||
|
if (mInDeleteQueue)
|
||||||
|
{
|
||||||
|
BF_ASSERT(mName->mPendingDerefCount > 0);
|
||||||
|
if (mName->mPendingDerefCount > 0)
|
||||||
|
mName->mPendingDerefCount--;
|
||||||
|
}
|
||||||
mSystem->ReleaseAtom(mName);
|
mSystem->ReleaseAtom(mName);
|
||||||
}
|
}
|
||||||
mName = NULL;
|
mName = NULL;
|
||||||
|
@ -625,6 +633,12 @@ void BfTypeDef::FreeMembers()
|
||||||
|
|
||||||
if (mNameEx != NULL)
|
if (mNameEx != NULL)
|
||||||
{
|
{
|
||||||
|
if (mInDeleteQueue)
|
||||||
|
{
|
||||||
|
BF_ASSERT(mNameEx->mPendingDerefCount > 0);
|
||||||
|
if (mNameEx->mPendingDerefCount > 0)
|
||||||
|
mNameEx->mPendingDerefCount--;
|
||||||
|
}
|
||||||
mSystem->ReleaseAtom(mNameEx);
|
mSystem->ReleaseAtom(mNameEx);
|
||||||
mNameEx = NULL;
|
mNameEx = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1854,6 +1868,7 @@ BfAtom* BfSystem::GetAtom(const StringImpl& string)
|
||||||
atom->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
atom->mAtomUpdateIdx = ++mAtomUpdateIdx;
|
||||||
atom->mString = *stringPtr;
|
atom->mString = *stringPtr;
|
||||||
atom->mRefCount = 1;
|
atom->mRefCount = 1;
|
||||||
|
atom->mPendingDerefCount = 0;
|
||||||
|
|
||||||
atom->mHash = 0;
|
atom->mHash = 0;
|
||||||
for (char c : string)
|
for (char c : string)
|
||||||
|
@ -2496,6 +2511,21 @@ void BfSystem::RemoveTypeDef(BfTypeDef* typeDef)
|
||||||
// mTypeDef is already locked by the system lock
|
// mTypeDef is already locked by the system lock
|
||||||
mTypeDefs.Remove(typeDef);
|
mTypeDefs.Remove(typeDef);
|
||||||
AutoCrit autoCrit(mDataLock);
|
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);
|
mTypeDefDeleteQueue.push_back(typeDef);
|
||||||
mTypeMapVersion++;
|
mTypeMapVersion++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ class BfAtom
|
||||||
public:
|
public:
|
||||||
StringView mString;
|
StringView mString;
|
||||||
int mRefCount;
|
int mRefCount;
|
||||||
|
int mPendingDerefCount;
|
||||||
int mHash;
|
int mHash;
|
||||||
uint32 mAtomUpdateIdx;
|
uint32 mAtomUpdateIdx;
|
||||||
bool mIsSystemType;
|
bool mIsSystemType;
|
||||||
|
@ -930,6 +931,7 @@ public:
|
||||||
bool mHasOverrideMethods;
|
bool mHasOverrideMethods;
|
||||||
bool mIsOpaque;
|
bool mIsOpaque;
|
||||||
bool mIsNextRevision;
|
bool mIsNextRevision;
|
||||||
|
bool mInDeleteQueue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTypeDef()
|
BfTypeDef()
|
||||||
|
@ -969,6 +971,7 @@ public:
|
||||||
mIsOpaque = false;
|
mIsOpaque = false;
|
||||||
mPartialUsed = false;
|
mPartialUsed = false;
|
||||||
mIsNextRevision = false;
|
mIsNextRevision = false;
|
||||||
|
mInDeleteQueue = false;
|
||||||
mDupDetectedRevision = -1;
|
mDupDetectedRevision = -1;
|
||||||
mNestDepth = 0;
|
mNestDepth = 0;
|
||||||
mOuterType = NULL;
|
mOuterType = NULL;
|
||||||
|
|
|
@ -59,6 +59,10 @@ PUSHD %~dp0..\
|
||||||
@CALL :TEST
|
@CALL :TEST
|
||||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
|
@SET TESTPATH=IDE\Tests\BugW006
|
||||||
|
@CALL :TEST
|
||||||
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
@SET TESTPATH=IDE\Tests\IndentTest
|
@SET TESTPATH=IDE\Tests\IndentTest
|
||||||
@CALL :TEST
|
@CALL :TEST
|
||||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue