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; 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 intptr StringView::IndexOf(const StringView& subStr, bool ignoreCase) const
{ {
for (intptr ofs = 0; ofs <= mLength - subStr.mLength; ofs++) for (intptr ofs = 0; ofs <= mLength - subStr.mLength; ofs++)

View file

@ -16,6 +16,17 @@ struct StringSplitEnumerator;
class StringView class StringView
{ {
public:
enum CompareKind
{
CompareKind_CurrentCulture = 0,
CompareKind_CurrentCultureIgnoreCase = 1,
CompareKind_InvariantCulture = 2,
CompareKind_InvariantCultureIgnoreCase = 3,
CompareKind_Ordinal = 4,
CompareKind_OrdinalIgnoreCase = 5,
};
public: public:
const char* mPtr; const char* mPtr;
intptr mLength; intptr mLength;
@ -253,6 +264,23 @@ public:
return mLength; 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, bool ignoreCase = false) const;
intptr IndexOf(const StringView& subStr, int32 startIdx) const; intptr IndexOf(const StringView& subStr, int32 startIdx) const;
intptr IndexOf(const StringView& subStr, int64 startIdx) const; intptr IndexOf(const StringView& subStr, int64 startIdx) const;
@ -488,6 +516,8 @@ public:
CompareKind_OrdinalIgnoreCase = 5, CompareKind_OrdinalIgnoreCase = 5,
}; };
friend class StringView;
public: public:
typedef int int_strsize; 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; 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) bool BfAstNode::Equals(const char* str)
{ {
auto source = GetSourceData(); auto source = GetSourceData();

View file

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

View file

@ -1262,6 +1262,57 @@ void BfDefBuilder::AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, co
methodDef->mParams.push_back(paramDef); 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) void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
{ {
BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData); BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
@ -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) if (!isAutoCompleteTempType)
{ {
BfTypeDef* prevDef = NULL; BfTypeDef* prevDef = NULL;
@ -1670,6 +1727,12 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
prevRevisionTypeDef = checkTypeDef; prevRevisionTypeDef = checkTypeDef;
prevDef = checkTypeDef; prevDef = checkTypeDef;
} }
else
{
auto bestTypeDef = ComparePrevTypeDef(prevRevisionTypeDef, checkTypeDef);
prevRevisionTypeDef = bestTypeDef;
prevDef = bestTypeDef;
}
} }
} }
else else
@ -1732,12 +1795,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, 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); 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); BF_ASSERT(mCurTypeDef->mNameEx == NULL);
if (mCurTypeDef->mGenericParamDefs.size() != 0) if (mCurTypeDef->mGenericParamDefs.size() != 0)

View file

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

View file

@ -628,6 +628,25 @@ public:
{ {
mGenericParamFlags = BfGenericParamFlag_None; 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 class BfGenericParamDef : public BfConstraintDef
@ -635,6 +654,18 @@ class BfGenericParamDef : public BfConstraintDef
public: public:
String mName; 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 class BfExternalConstraintDef : public BfConstraintDef