mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fixed false signature change with multiple extensions
This commit is contained in:
parent
f81a1cf896
commit
fa65029dfa
7 changed files with 155 additions and 8 deletions
|
@ -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++)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -1374,7 +1425,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
|
|
||||||
SetAndRestoreValue<HashContext*> prevFullHashCtx(mFullHashCtx, &fullHashCtx);
|
SetAndRestoreValue<HashContext*> prevFullHashCtx(mFullHashCtx, &fullHashCtx);
|
||||||
SetAndRestoreValue<HashContext*> prevSignatureHashCtx(mSignatureHashCtx, &signatureHashCtx);
|
SetAndRestoreValue<HashContext*> prevSignatureHashCtx(mSignatureHashCtx, &signatureHashCtx);
|
||||||
|
|
||||||
if (bfParser != NULL)
|
if (bfParser != NULL)
|
||||||
{
|
{
|
||||||
mFullHashCtx->MixinStr(bfParser->mFileName);
|
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)
|
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
|
||||||
|
@ -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,
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -628,13 +628,44 @@ 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
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue