mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Working on wrapping for formatter
This commit is contained in:
parent
edcdb3bbb1
commit
076931cf3b
8 changed files with 315 additions and 66 deletions
|
@ -1784,6 +1784,13 @@ BfBinaryOp Beefy::BfGetFlippedBinaryOp(BfBinaryOp origOp)
|
|||
return BfBinaryOp_None;
|
||||
}
|
||||
|
||||
bool Beefy::BfIsCommentBlock(BfCommentKind commentKind)
|
||||
{
|
||||
return
|
||||
(commentKind == BfCommentKind_Block) ||
|
||||
(commentKind == BfCommentKind_Documentation_Block_Pre) ||
|
||||
(commentKind == BfCommentKind_Documentation_Block_Post);
|
||||
}
|
||||
|
||||
BfInlineAsmInstruction::AsmArg::AsmArg()
|
||||
: mType(ARGTYPE_Immediate)
|
||||
|
|
|
@ -1760,9 +1760,12 @@ public:
|
|||
|
||||
enum BfCommentKind
|
||||
{
|
||||
BfCommentKind_Normal,
|
||||
BfCommentKind_Documentation_Pre,
|
||||
BfCommentKind_Documentation_Post,
|
||||
BfCommentKind_Line,
|
||||
BfCommentKind_Block,
|
||||
BfCommentKind_Documentation_Block_Pre,
|
||||
BfCommentKind_Documentation_Line_Pre,
|
||||
BfCommentKind_Documentation_Block_Post,
|
||||
BfCommentKind_Documentation_Line_Post,
|
||||
};
|
||||
|
||||
class BfCommentNode : public BfAstNode
|
||||
|
@ -3182,5 +3185,6 @@ const char* BfGetOpName(BfUnaryOp unaryOp);
|
|||
BfBinaryOp BfTokenToBinaryOp(BfToken token);
|
||||
BfUnaryOp BfTokenToUnaryOp(BfToken token);
|
||||
BfAssignmentOp BfTokenToAssignmentOp(BfToken token);
|
||||
bool BfIsCommentBlock(BfCommentKind commentKind);
|
||||
|
||||
NS_BF_END
|
|
@ -5712,6 +5712,12 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
{
|
||||
BP_ZONE("BfCompiler::Compile");
|
||||
|
||||
if (mSystem->mTypeDefs.mCount == 0)
|
||||
{
|
||||
// No-source bailout
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mOptions.mErrorString.IsEmpty())
|
||||
{
|
||||
mPassInstance->Fail(mOptions.mErrorString);
|
||||
|
|
|
@ -772,30 +772,30 @@ void BfContext::AddTypeToWorkList(BfType* type)
|
|||
void BfContext::ValidateDependencies()
|
||||
{
|
||||
#if _DEBUG
|
||||
BP_ZONE("BfContext::ValidateDependencies");
|
||||
BfLogSysM("ValidateDependencies\n");
|
||||
|
||||
bool deletedNewTypes = false;
|
||||
auto itr = mResolvedTypes.begin();
|
||||
while (itr != mResolvedTypes.end())
|
||||
{
|
||||
auto type = itr.mCurEntry->mValue;
|
||||
if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined))
|
||||
{
|
||||
// We can't contain deleted generic arguments without being deleted ourselves
|
||||
BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;
|
||||
|
||||
for (auto genericTypeArg : genericType->mTypeGenericArguments)
|
||||
{
|
||||
auto depType = genericTypeArg->ToDependedType();
|
||||
if (depType != NULL)
|
||||
{
|
||||
BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type));
|
||||
}
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
// BP_ZONE("BfContext::ValidateDependencies");
|
||||
// BfLogSysM("ValidateDependencies\n");
|
||||
//
|
||||
// bool deletedNewTypes = false;
|
||||
// auto itr = mResolvedTypes.begin();
|
||||
// while (itr != mResolvedTypes.end())
|
||||
// {
|
||||
// auto type = itr.mCurEntry->mValue;
|
||||
// if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined))
|
||||
// {
|
||||
// // We can't contain deleted generic arguments without being deleted ourselves
|
||||
// BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;
|
||||
//
|
||||
// for (auto genericTypeArg : genericType->mTypeGenericArguments)
|
||||
// {
|
||||
// auto depType = genericTypeArg->ToDependedType();
|
||||
// if (depType != NULL)
|
||||
// {
|
||||
// BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ++itr;
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -626,17 +626,17 @@ void BfParser::AddErrorNode(int startIdx, int endIdx)
|
|||
|
||||
BfCommentKind BfParser::GetCommentKind(int startIdx)
|
||||
{
|
||||
if (((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] == '<')) ||
|
||||
((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] == '<')))
|
||||
{
|
||||
return BfCommentKind_Documentation_Post;
|
||||
}
|
||||
if (((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/')) ||
|
||||
((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/')))
|
||||
{
|
||||
return BfCommentKind_Documentation_Pre;
|
||||
}
|
||||
return BfCommentKind_Normal;
|
||||
if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] == '<'))
|
||||
return BfCommentKind_Documentation_Block_Post;
|
||||
if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] == '<'))
|
||||
return BfCommentKind_Documentation_Line_Post;
|
||||
if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/'))
|
||||
return BfCommentKind_Documentation_Block_Pre;
|
||||
if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/'))
|
||||
return BfCommentKind_Documentation_Line_Pre;
|
||||
if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*'))
|
||||
return BfCommentKind_Block;
|
||||
return BfCommentKind_Line;
|
||||
}
|
||||
|
||||
bool BfParser::EvaluatePreprocessor(BfExpression* expr)
|
||||
|
@ -1950,6 +1950,7 @@ void BfParser::NextToken(int endIdx)
|
|||
|
||||
if (mPreprocessorIgnoredSectionNode == NULL)
|
||||
{
|
||||
auto commentKind = GetCommentKind(mTokenStart);
|
||||
bool handled = false;
|
||||
if (!mPendingSideNodes.IsEmpty())
|
||||
{
|
||||
|
@ -1958,7 +1959,9 @@ void BfParser::NextToken(int endIdx)
|
|||
// This is required for folding '///' style multi-line documentation into a single node
|
||||
if (prevComment->GetTriviaStart() == mTriviaStart)
|
||||
{
|
||||
if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
|
||||
auto prevCommentKind = GetCommentKind(prevComment->mSrcStart);
|
||||
|
||||
if ((!BfIsCommentBlock(commentKind)) && (commentKind == prevCommentKind))
|
||||
{
|
||||
prevComment->SetSrcEnd(mSrcIdx);
|
||||
handled = true;
|
||||
|
@ -1971,7 +1974,7 @@ void BfParser::NextToken(int endIdx)
|
|||
{
|
||||
auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
|
||||
bfCommentNode->Init(this);
|
||||
bfCommentNode->mCommentKind = GetCommentKind(mTokenStart);
|
||||
bfCommentNode->mCommentKind = commentKind;
|
||||
mSidechannelRootNode->Add(bfCommentNode);
|
||||
mPendingSideNodes.push_back(bfCommentNode);
|
||||
}
|
||||
|
@ -2025,11 +2028,12 @@ void BfParser::NextToken(int endIdx)
|
|||
// This is required for folding documentation into a single node
|
||||
if (prevComment->GetTriviaStart() == mTriviaStart)
|
||||
{
|
||||
if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
|
||||
{
|
||||
prevComment->SetSrcEnd(mSrcIdx);
|
||||
handled = true;
|
||||
}
|
||||
//TODO: Why did we allow merging BLOCKS of comments together? This messes up BfPrinter word wrapping on comments
|
||||
// if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart))
|
||||
// {
|
||||
// prevComment->SetSrcEnd(mSrcIdx);
|
||||
// handled = true;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#include "BfPrinter.h"
|
||||
#include "BfParser.h"
|
||||
#include "BfUtil.h"
|
||||
#include "BeefySysLib/util/UTF8.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
// This is a really long line, I'm testing to see what's up. This is a really long line, I'm testing to see what's up. This is a really long line, I'm testing to see what's up.
|
||||
// This is a really long line, I'm testing to see what's up.
|
||||
BfPrinter::BfPrinter(BfRootNode *rootNode, BfRootNode *sidechannelRootNode, BfRootNode *errorRootNode)
|
||||
{
|
||||
mSource = rootNode->GetSourceData();
|
||||
|
@ -39,10 +42,28 @@ BfPrinter::BfPrinter(BfRootNode* rootNode, BfRootNode* sidechannelRootNode, BfRo
|
|||
mVirtualNewLineIdx = 0;
|
||||
mHighestCharId = 0;
|
||||
mCurTypeDecl = NULL;
|
||||
mCurCol = 0;
|
||||
mMaxCol = 120;
|
||||
}
|
||||
|
||||
void BfPrinter::Write(const StringView& str)
|
||||
{
|
||||
if (str == '\n')
|
||||
mCurCol = 0;
|
||||
else if (mMaxCol > 0)
|
||||
{
|
||||
int startCol = mCurCol;
|
||||
|
||||
for (int i = 0; i < (int)str.mLength; i++)
|
||||
{
|
||||
char c = str[i];
|
||||
if (c == '\t')
|
||||
mCurCol = ((mCurCol + 1) & ~3) + 4;
|
||||
else
|
||||
mCurCol++;
|
||||
}
|
||||
}
|
||||
|
||||
mOutString.Append(str);
|
||||
if (mCharMapping != NULL)
|
||||
{
|
||||
|
@ -108,6 +129,28 @@ void BfPrinter::FlushIndent()
|
|||
void BfPrinter::Write(BfAstNode* node, int start, int len)
|
||||
{
|
||||
FlushIndent();
|
||||
|
||||
if (mMaxCol > 0)
|
||||
{
|
||||
int startCol = mCurCol;
|
||||
|
||||
auto parserData = node->GetParserData();
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char c = parserData->mSrc[start + i];
|
||||
if (c == '\t')
|
||||
mCurCol = ((mCurCol + 1) & ~3) + 4;
|
||||
else
|
||||
mCurCol++;
|
||||
}
|
||||
|
||||
if ((mCurCol > mMaxCol) && (startCol != 0))
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
}
|
||||
|
||||
mOutString.Append(node->GetSourceData()->mSrc + start, len);
|
||||
if (mCharMapping != NULL)
|
||||
{
|
||||
|
@ -256,6 +299,8 @@ int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx)
|
|||
|
||||
void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
||||
{
|
||||
bool wasExpectingNewLine = mExpectingNewLine;
|
||||
|
||||
mTriviaIdx = std::max(mTriviaIdx, node->GetTriviaStart());
|
||||
int endIdx = mTriviaIdx;
|
||||
int crCount = 0;
|
||||
|
@ -290,6 +335,46 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
|||
}
|
||||
}
|
||||
|
||||
auto commentNode = BfNodeDynCast<BfCommentNode>(node);
|
||||
bool isBlockComment = false;
|
||||
bool isStarredBlockComment = false;
|
||||
|
||||
if (commentNode != NULL)
|
||||
{
|
||||
if ((commentNode->mCommentKind == BfCommentKind_Block) ||
|
||||
(commentNode->mCommentKind == BfCommentKind_Documentation_Block_Pre) ||
|
||||
(commentNode->mCommentKind == BfCommentKind_Documentation_Block_Post))
|
||||
{
|
||||
isBlockComment = true;
|
||||
|
||||
int lineCount = 0;
|
||||
bool onNewLine = false;
|
||||
for (int srcIdx = startIdx; srcIdx < endIdx; srcIdx++)
|
||||
{
|
||||
char checkC = astNodeSrc->mSrc[srcIdx];
|
||||
if (checkC == '\n')
|
||||
{
|
||||
onNewLine = true;
|
||||
lineCount++;
|
||||
if (lineCount >= 2)
|
||||
break;
|
||||
}
|
||||
else if ((checkC == '*') && (onNewLine))
|
||||
isStarredBlockComment = true;
|
||||
else if ((checkC != ' ') && (checkC != '\t'))
|
||||
onNewLine = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool doWrap = (commentNode != NULL) && (mMaxCol > 0);
|
||||
bool prevHadWrap = false;
|
||||
|
||||
if (commentNode != NULL)
|
||||
{
|
||||
Visit((BfAstNode*)node);
|
||||
startIdx = node->mSrcStart;
|
||||
}
|
||||
|
||||
// This handles tab adjustment within multiline comments
|
||||
FlushIndent();
|
||||
bool isNewLine = false;
|
||||
|
@ -300,9 +385,90 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
|||
#endif
|
||||
|
||||
bool emitChar = true;
|
||||
|
||||
char c = astNodeSrc->mSrc[srcIdx];
|
||||
if (c == '\n')
|
||||
{
|
||||
isNewLine = true;
|
||||
|
||||
if (prevHadWrap)
|
||||
{
|
||||
bool merging = false;
|
||||
|
||||
int blockContentStart = -1;
|
||||
|
||||
bool foundStar = false;
|
||||
int startIdx = srcIdx;
|
||||
for (int checkIdx = srcIdx + 1; checkIdx < endIdx + 1; checkIdx++)
|
||||
{
|
||||
char checkC = astNodeSrc->mSrc[checkIdx];
|
||||
|
||||
if (isBlockComment)
|
||||
{
|
||||
if (checkC == '\n')
|
||||
break;
|
||||
|
||||
if ((isStarredBlockComment) && (!foundStar) && (checkC == '*'))
|
||||
{
|
||||
foundStar = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((checkC != ' ') && (checkC != '\t'))
|
||||
{
|
||||
if (blockContentStart == -1)
|
||||
{
|
||||
blockContentStart = checkIdx;
|
||||
}
|
||||
|
||||
// Only do merge if we have content on this line
|
||||
if (isalnum(checkC))
|
||||
{
|
||||
srcIdx = blockContentStart;
|
||||
merging = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((checkC == '/') && (astNodeSrc->mSrc[checkIdx + 1] == '/'))
|
||||
{
|
||||
srcIdx = checkIdx;
|
||||
while (srcIdx < endIdx)
|
||||
{
|
||||
char checkC = astNodeSrc->mSrc[srcIdx];
|
||||
if (checkC != '/')
|
||||
break;
|
||||
srcIdx++;
|
||||
}
|
||||
merging = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((checkC != ' ') && (checkC != '\t'))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (merging)
|
||||
{
|
||||
srcIdx--;
|
||||
while (srcIdx < endIdx - 1)
|
||||
{
|
||||
char checkC = astNodeSrc->mSrc[srcIdx + 1];
|
||||
if ((checkC != ' ') && (checkC != '\t'))
|
||||
break;
|
||||
srcIdx++;
|
||||
}
|
||||
Write(" ");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
mCurCol = 0;
|
||||
prevHadWrap = false;
|
||||
}
|
||||
else if (isNewLine)
|
||||
{
|
||||
if (c == ' ')
|
||||
|
@ -320,21 +486,78 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
|||
// Leave left-aligned preprocessor nodes that are commented out
|
||||
if ((c != '#') || (mQueuedSpaceCount > 0))
|
||||
mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset);
|
||||
else
|
||||
mQueuedSpaceCount = mCurIndentLevel * 4; // Do default indent
|
||||
isNewLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitChar)
|
||||
{
|
||||
int startIdx = srcIdx;
|
||||
|
||||
if (c != '\n')
|
||||
{
|
||||
while (srcIdx < endIdx)
|
||||
{
|
||||
char c = astNodeSrc->mSrc[srcIdx + 1];
|
||||
if (isspace((uint8)c))
|
||||
break;
|
||||
srcIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (doWrap)
|
||||
{
|
||||
int len = 0;
|
||||
for (int idx = startIdx; idx <= srcIdx; idx++)
|
||||
{
|
||||
char c = astNodeSrc->mSrc[idx];
|
||||
if (isutf(c))
|
||||
len++;
|
||||
}
|
||||
|
||||
if (mCurCol + len > mMaxCol)
|
||||
{
|
||||
Write("\n");
|
||||
mQueuedSpaceCount = mCurIndentLevel * 4;
|
||||
FlushIndent();
|
||||
|
||||
if (isStarredBlockComment)
|
||||
Write(" * ");
|
||||
else if (!isBlockComment)
|
||||
Write("// ");
|
||||
prevHadWrap = true;
|
||||
|
||||
while (startIdx < endIdx)
|
||||
{
|
||||
char c = astNodeSrc->mSrc[startIdx];
|
||||
if (!isspace((uint8)c))
|
||||
break;
|
||||
startIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FlushIndent();
|
||||
|
||||
for (int idx = startIdx; idx <= srcIdx; idx++)
|
||||
{
|
||||
char c = astNodeSrc->mSrc[idx];
|
||||
mOutString.Append(c);
|
||||
if (mCharMapping != NULL)
|
||||
{
|
||||
if (srcIdx < mParser->mSrcLength)
|
||||
mCharMapping->push_back(srcIdx);
|
||||
if (idx < mParser->mSrcLength)
|
||||
mCharMapping->push_back(idx);
|
||||
else
|
||||
mCharMapping->push_back(-1);
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
mCurCol = 0;
|
||||
else if (isutf(c))
|
||||
mCurCol++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,6 +565,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
|||
|
||||
mTriviaIdx = endIdx;
|
||||
mIsFirstStatementInBlock = false;
|
||||
mExpectingNewLine = wasExpectingNewLine;
|
||||
}
|
||||
|
||||
void BfPrinter::Visit(BfAstNode* bfAstNode)
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
int mQueuedSpaceCount;
|
||||
int mLastSpaceOffset; // Indent difference from original to new
|
||||
bool mExpectingNewLine;
|
||||
int mCurCol;
|
||||
int mMaxCol;
|
||||
|
||||
bool mIsFirstStatementInBlock;
|
||||
bool mForceUseTrivia;
|
||||
|
|
|
@ -8330,14 +8330,15 @@ BfCommentNode * BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode*
|
|||
while (mDocumentCheckIdx < mSource->mSidechannelRootNode->mChildArr.mSize)
|
||||
{
|
||||
auto checkComment = BfNodeDynCast<BfCommentNode>(mSource->mSidechannelRootNode->mChildArr[mDocumentCheckIdx]);
|
||||
if ((checkComment == NULL) || (checkComment->mCommentKind == BfCommentKind_Normal))
|
||||
if ((checkComment == NULL) || (checkComment->mCommentKind == BfCommentKind_Block) || (checkComment->mCommentKind == BfCommentKind_Line))
|
||||
{
|
||||
mDocumentCheckIdx++;
|
||||
continue;
|
||||
}
|
||||
if (checkComment->GetSrcEnd() > defNodeEnd->GetSrcStart())
|
||||
{
|
||||
if (checkComment->mCommentKind == BfCommentKind_Documentation_Post)
|
||||
if ((checkComment->mCommentKind == BfCommentKind_Documentation_Line_Post) ||
|
||||
(checkComment->mCommentKind == BfCommentKind_Documentation_Block_Post))
|
||||
{
|
||||
int defEnd = defNodeEnd->GetSrcEnd();
|
||||
if (checkDocAfter)
|
||||
|
@ -8368,7 +8369,8 @@ BfCommentNode * BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode*
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (checkComment->mCommentKind != BfCommentKind_Documentation_Pre)
|
||||
if ((checkComment->mCommentKind != BfCommentKind_Documentation_Line_Pre) &&
|
||||
(checkComment->mCommentKind != BfCommentKind_Documentation_Block_Pre))
|
||||
{
|
||||
// Skip this, not used
|
||||
mDocumentCheckIdx++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue