1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Fixed false signature change with multiple extensions

This commit is contained in:
Brian Fiete 2020-12-31 09:56:51 -08:00
parent f81a1cf896
commit fa65029dfa
7 changed files with 155 additions and 8 deletions

View file

@ -67,6 +67,24 @@ bool StringView::operator!=(const StringImpl& strB) const
return strncmp(this->mPtr, strB.GetPtr(), this->mLength) != 0;
}
bool StringView::StartsWith(const StringView& b, StringView::CompareKind comparisonType) const
{
if (this->mLength < b.mLength)
return false;
if (comparisonType == String::CompareKind_OrdinalIgnoreCase)
return String::EqualsIgnoreCaseHelper(mPtr, b.mPtr, b.mLength);
return String::EqualsHelper(mPtr, b.mPtr, b.mLength);
}
bool StringView::EndsWith(const StringView& b, StringView::CompareKind comparisonType) const
{
if (this->mLength < b.mLength)
return false;
if (comparisonType == String::CompareKind_OrdinalIgnoreCase)
return String::EqualsIgnoreCaseHelper(this->mPtr + this->mLength - b.mLength, b.mPtr, b.mLength);
return String::EqualsHelper(this->mPtr + this->mLength - b.mLength, b.mPtr, b.mLength);
}
intptr StringView::IndexOf(const StringView& subStr, bool ignoreCase) const
{
for (intptr ofs = 0; ofs <= mLength - subStr.mLength; ofs++)

View file

@ -16,6 +16,17 @@ struct StringSplitEnumerator;
class StringView
{
public:
enum CompareKind
{
CompareKind_CurrentCulture = 0,
CompareKind_CurrentCultureIgnoreCase = 1,
CompareKind_InvariantCulture = 2,
CompareKind_InvariantCultureIgnoreCase = 3,
CompareKind_Ordinal = 4,
CompareKind_OrdinalIgnoreCase = 5,
};
public:
const char* mPtr;
intptr mLength;
@ -253,6 +264,23 @@ public:
return mLength;
}
bool StartsWith(const StringView& b, CompareKind comparisonType = CompareKind_Ordinal) const;
bool EndsWith(const StringView& b, CompareKind comparisonType = CompareKind_Ordinal) const;
bool StartsWith(char c) const
{
if (this->mLength == 0)
return false;
return this->mPtr[0] == c;
}
bool EndsWith(char c) const
{
if (this->mLength == 0)
return false;
return this->mPtr[this->mLength - 1] == c;
}
intptr IndexOf(const StringView& subStr, bool ignoreCase = false) const;
intptr IndexOf(const StringView& subStr, int32 startIdx) const;
intptr IndexOf(const StringView& subStr, int64 startIdx) const;
@ -488,6 +516,8 @@ public:
CompareKind_OrdinalIgnoreCase = 5,
};
friend class StringView;
public:
typedef int int_strsize;

View file

@ -1006,6 +1006,15 @@ bool BfAstNode::Equals(const StringImpl& str)
return strncmp(str.GetPtr(), source->mSrc + mSrcStart, len) == 0;
}
bool BfAstNode::Equals(const StringView& str)
{
int len = mSrcEnd - mSrcStart;
if (len != str.mLength)
return false;
auto source = GetSourceData();
return strncmp(str.mPtr, source->mSrc + mSrcStart, len) == 0;
}
bool BfAstNode::Equals(const char* str)
{
auto source = GetSourceData();

View file

@ -1090,6 +1090,7 @@ public:
StringView ToStringView();
void ToString(StringImpl& str);
bool Equals(const StringImpl& str);
bool Equals(const StringView& str);
bool Equals(const char* str);
void Init(BfParser* bfParser);
void Accept(BfStructuralVisitor* bfVisitor);

View file

@ -1262,6 +1262,57 @@ void BfDefBuilder::AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, co
methodDef->mParams.push_back(paramDef);
}
BfTypeDef* BfDefBuilder::ComparePrevTypeDef(BfTypeDef* prevTypeDef, BfTypeDef* checkTypeDef)
{
if (!mCurTypeDef->IsExtension())
return prevTypeDef;
BF_ASSERT(mCurTypeDef->mGenericParamDefs.size() == prevTypeDef->mGenericParamDefs.size());
BF_ASSERT(mCurTypeDef->mGenericParamDefs.size() == checkTypeDef->mGenericParamDefs.size());
bool prevMatches = true;
bool checkMatches = true;
for (int genericParamIdx = 0; genericParamIdx < (int)mCurTypeDef->mGenericParamDefs.size(); genericParamIdx++)
{
BfGenericParamDef* paramDef = mCurTypeDef->mGenericParamDefs[genericParamIdx];
BfGenericParamDef* prevParamDef = prevTypeDef->mGenericParamDefs[genericParamIdx];
BfGenericParamDef* checkParamDef = checkTypeDef->mGenericParamDefs[genericParamIdx];
if (*paramDef != *prevParamDef)
prevMatches = false;
if (*paramDef != *checkParamDef)
checkMatches = false;
}
if (mCurTypeDef->mExternalConstraints.mSize == prevTypeDef->mExternalConstraints.mSize)
{
for (int constraintIdx = 0; constraintIdx < mCurTypeDef->mExternalConstraints.mSize; constraintIdx++)
{
if (mCurTypeDef->mExternalConstraints[constraintIdx] != prevTypeDef->mExternalConstraints[constraintIdx])
prevMatches = false;
}
}
else
prevMatches = false;
if (mCurTypeDef->mExternalConstraints.mSize == checkTypeDef->mExternalConstraints.mSize)
{
for (int constraintIdx = 0; constraintIdx < mCurTypeDef->mExternalConstraints.mSize; constraintIdx++)
{
if (mCurTypeDef->mExternalConstraints[constraintIdx] != checkTypeDef->mExternalConstraints[constraintIdx])
checkMatches = false;
}
}
else
checkMatches = false;
if ((!prevMatches) && (checkMatches))
return checkTypeDef;
return prevTypeDef;
}
void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
{
BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
@ -1374,7 +1425,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
SetAndRestoreValue<HashContext*> prevFullHashCtx(mFullHashCtx, &fullHashCtx);
SetAndRestoreValue<HashContext*> prevSignatureHashCtx(mSignatureHashCtx, &signatureHashCtx);
if (bfParser != NULL)
{
mFullHashCtx->MixinStr(bfParser->mFileName);
@ -1627,6 +1678,12 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
}
}
int outerGenericSize = 0;
if (mCurTypeDef->mOuterType != NULL)
outerGenericSize = (int)mCurTypeDef->mOuterType->mGenericParamDefs.size();
bool isGeneric = (outerGenericSize != 0) || (typeDeclaration->mGenericParams != NULL);
ParseGenericParams(typeDeclaration->mGenericParams, typeDeclaration->mGenericConstraintsDeclaration, mCurTypeDef->mGenericParamDefs, &mCurTypeDef->mExternalConstraints, outerGenericSize, isGeneric);
if (!isAutoCompleteTempType)
{
BfTypeDef* prevDef = NULL;
@ -1670,6 +1727,12 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
prevRevisionTypeDef = checkTypeDef;
prevDef = checkTypeDef;
}
else
{
auto bestTypeDef = ComparePrevTypeDef(prevRevisionTypeDef, checkTypeDef);
prevRevisionTypeDef = bestTypeDef;
prevDef = bestTypeDef;
}
}
}
else
@ -1731,12 +1794,6 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration,
typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType);
int outerGenericSize = 0;
if (mCurTypeDef->mOuterType != NULL)
outerGenericSize = (int)mCurTypeDef->mOuterType->mGenericParamDefs.size();
bool isGeneric = (outerGenericSize != 0) || (typeDeclaration->mGenericParams != NULL);
ParseGenericParams(typeDeclaration->mGenericParams, typeDeclaration->mGenericConstraintsDeclaration, mCurTypeDef->mGenericParamDefs, &mCurTypeDef->mExternalConstraints, outerGenericSize, isGeneric);
BF_ASSERT(mCurTypeDef->mNameEx == NULL);

View file

@ -37,6 +37,7 @@ public:
static BfMethodDef* AddDtor(BfTypeDef* typeDef);
static void AddDynamicCastMethods(BfTypeDef* typeDef);
void AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName);
BfTypeDef* ComparePrevTypeDef(BfTypeDef* prevTypeDef, BfTypeDef* checkTypeDef);
void FinishTypeDef(bool wantsToString);
void ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef);
void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef);

View file

@ -628,13 +628,44 @@ public:
{
mGenericParamFlags = BfGenericParamFlag_None;
}
bool operator==(const BfConstraintDef& other) const
{
if (mGenericParamFlags != other.mGenericParamFlags)
return false;
if (mConstraints.mSize != other.mConstraints.mSize)
return false;
for (int i = 0; i < mConstraints.mSize; i++)
{
if (!mConstraints[i]->Equals(other.mConstraints[i]->ToStringView()))
return false;
}
return true;
}
bool operator!=(const BfConstraintDef& other) const
{
return !(*this == other);
}
};
class BfGenericParamDef : public BfConstraintDef
{
public:
String mName;
Array<BfIdentifierNode*> mNameNodes; // 0 is always the def name
Array<BfIdentifierNode*> mNameNodes; // 0 is always the def name
bool operator==(const BfGenericParamDef& other) const
{
if (mName != other.mName)
return false;
return *(BfConstraintDef*)this == *(BfConstraintDef*)&other;
}
bool operator!=(const BfGenericParamDef& other) const
{
return !(*this == other);
}
};
class BfExternalConstraintDef : public BfConstraintDef