1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Working on wrapping for formatter

This commit is contained in:
Brian Fiete 2020-03-28 14:26:14 -07:00
parent edcdb3bbb1
commit 076931cf3b
8 changed files with 315 additions and 66 deletions

View file

@ -1784,6 +1784,13 @@ BfBinaryOp Beefy::BfGetFlippedBinaryOp(BfBinaryOp origOp)
return BfBinaryOp_None; 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() BfInlineAsmInstruction::AsmArg::AsmArg()
: mType(ARGTYPE_Immediate) : mType(ARGTYPE_Immediate)

View file

@ -1760,9 +1760,12 @@ public:
enum BfCommentKind enum BfCommentKind
{ {
BfCommentKind_Normal, BfCommentKind_Line,
BfCommentKind_Documentation_Pre, BfCommentKind_Block,
BfCommentKind_Documentation_Post, BfCommentKind_Documentation_Block_Pre,
BfCommentKind_Documentation_Line_Pre,
BfCommentKind_Documentation_Block_Post,
BfCommentKind_Documentation_Line_Post,
}; };
class BfCommentNode : public BfAstNode class BfCommentNode : public BfAstNode
@ -3182,5 +3185,6 @@ const char* BfGetOpName(BfUnaryOp unaryOp);
BfBinaryOp BfTokenToBinaryOp(BfToken token); BfBinaryOp BfTokenToBinaryOp(BfToken token);
BfUnaryOp BfTokenToUnaryOp(BfToken token); BfUnaryOp BfTokenToUnaryOp(BfToken token);
BfAssignmentOp BfTokenToAssignmentOp(BfToken token); BfAssignmentOp BfTokenToAssignmentOp(BfToken token);
bool BfIsCommentBlock(BfCommentKind commentKind);
NS_BF_END NS_BF_END

View file

@ -5712,6 +5712,12 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
{ {
BP_ZONE("BfCompiler::Compile"); BP_ZONE("BfCompiler::Compile");
if (mSystem->mTypeDefs.mCount == 0)
{
// No-source bailout
return true;
}
if (!mOptions.mErrorString.IsEmpty()) if (!mOptions.mErrorString.IsEmpty())
{ {
mPassInstance->Fail(mOptions.mErrorString); mPassInstance->Fail(mOptions.mErrorString);

View file

@ -772,30 +772,30 @@ void BfContext::AddTypeToWorkList(BfType* type)
void BfContext::ValidateDependencies() void BfContext::ValidateDependencies()
{ {
#if _DEBUG #if _DEBUG
BP_ZONE("BfContext::ValidateDependencies"); // BP_ZONE("BfContext::ValidateDependencies");
BfLogSysM("ValidateDependencies\n"); // BfLogSysM("ValidateDependencies\n");
//
bool deletedNewTypes = false; // bool deletedNewTypes = false;
auto itr = mResolvedTypes.begin(); // auto itr = mResolvedTypes.begin();
while (itr != mResolvedTypes.end()) // while (itr != mResolvedTypes.end())
{ // {
auto type = itr.mCurEntry->mValue; // auto type = itr.mCurEntry->mValue;
if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined)) // if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined))
{ // {
// We can't contain deleted generic arguments without being deleted ourselves // // We can't contain deleted generic arguments without being deleted ourselves
BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type; // BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;
//
for (auto genericTypeArg : genericType->mTypeGenericArguments) // for (auto genericTypeArg : genericType->mTypeGenericArguments)
{ // {
auto depType = genericTypeArg->ToDependedType(); // auto depType = genericTypeArg->ToDependedType();
if (depType != NULL) // if (depType != NULL)
{ // {
BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type)); // BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type));
} // }
} // }
} // }
++itr; // ++itr;
} // }
#endif #endif
} }

View file

@ -626,17 +626,17 @@ void BfParser::AddErrorNode(int startIdx, int endIdx)
BfCommentKind BfParser::GetCommentKind(int startIdx) BfCommentKind BfParser::GetCommentKind(int startIdx)
{ {
if (((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] == '<')) || 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_Block_Post;
{ if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] == '<'))
return BfCommentKind_Documentation_Post; return BfCommentKind_Documentation_Line_Post;
} if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/'))
if (((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*') && (mSrc[startIdx + 2] == '*') && (mSrc[startIdx + 3] != '/')) || return BfCommentKind_Documentation_Block_Pre;
((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/'))) if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '/') && (mSrc[startIdx + 2] == '/') && (mSrc[startIdx + 3] != '/'))
{ return BfCommentKind_Documentation_Line_Pre;
return BfCommentKind_Documentation_Pre; if ((mSrc[startIdx] == '/') && (mSrc[startIdx + 1] == '*'))
} return BfCommentKind_Block;
return BfCommentKind_Normal; return BfCommentKind_Line;
} }
bool BfParser::EvaluatePreprocessor(BfExpression* expr) bool BfParser::EvaluatePreprocessor(BfExpression* expr)
@ -1950,6 +1950,7 @@ void BfParser::NextToken(int endIdx)
if (mPreprocessorIgnoredSectionNode == NULL) if (mPreprocessorIgnoredSectionNode == NULL)
{ {
auto commentKind = GetCommentKind(mTokenStart);
bool handled = false; bool handled = false;
if (!mPendingSideNodes.IsEmpty()) 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 // This is required for folding '///' style multi-line documentation into a single node
if (prevComment->GetTriviaStart() == mTriviaStart) if (prevComment->GetTriviaStart() == mTriviaStart)
{ {
if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart)) auto prevCommentKind = GetCommentKind(prevComment->mSrcStart);
if ((!BfIsCommentBlock(commentKind)) && (commentKind == prevCommentKind))
{ {
prevComment->SetSrcEnd(mSrcIdx); prevComment->SetSrcEnd(mSrcIdx);
handled = true; handled = true;
@ -1971,7 +1974,7 @@ void BfParser::NextToken(int endIdx)
{ {
auto bfCommentNode = mAlloc->Alloc<BfCommentNode>(); auto bfCommentNode = mAlloc->Alloc<BfCommentNode>();
bfCommentNode->Init(this); bfCommentNode->Init(this);
bfCommentNode->mCommentKind = GetCommentKind(mTokenStart); bfCommentNode->mCommentKind = commentKind;
mSidechannelRootNode->Add(bfCommentNode); mSidechannelRootNode->Add(bfCommentNode);
mPendingSideNodes.push_back(bfCommentNode); mPendingSideNodes.push_back(bfCommentNode);
} }
@ -2025,11 +2028,12 @@ void BfParser::NextToken(int endIdx)
// This is required for folding documentation into a single node // This is required for folding documentation into a single node
if (prevComment->GetTriviaStart() == mTriviaStart) if (prevComment->GetTriviaStart() == mTriviaStart)
{ {
if (GetCommentKind(prevComment->mSrcStart) == GetCommentKind(mTokenStart)) //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; // prevComment->SetSrcEnd(mSrcIdx);
} // handled = true;
// }
} }
} }
} }

View file

@ -1,10 +1,13 @@
#include "BfPrinter.h" #include "BfPrinter.h"
#include "BfParser.h" #include "BfParser.h"
#include "BfUtil.h" #include "BfUtil.h"
#include "BeefySysLib/util/UTF8.h"
USING_NS_BF; USING_NS_BF;
BfPrinter::BfPrinter(BfRootNode* rootNode, BfRootNode* sidechannelRootNode, BfRootNode* errorRootNode) // 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(); mSource = rootNode->GetSourceData();
mParser = mSource->ToParserData(); mParser = mSource->ToParserData();
@ -39,10 +42,28 @@ BfPrinter::BfPrinter(BfRootNode* rootNode, BfRootNode* sidechannelRootNode, BfRo
mVirtualNewLineIdx = 0; mVirtualNewLineIdx = 0;
mHighestCharId = 0; mHighestCharId = 0;
mCurTypeDecl = NULL; mCurTypeDecl = NULL;
mCurCol = 0;
mMaxCol = 120;
} }
void BfPrinter::Write(const StringView& str) 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); mOutString.Append(str);
if (mCharMapping != NULL) if (mCharMapping != NULL)
{ {
@ -108,6 +129,28 @@ void BfPrinter::FlushIndent()
void BfPrinter::Write(BfAstNode* node, int start, int len) void BfPrinter::Write(BfAstNode* node, int start, int len)
{ {
FlushIndent(); 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); mOutString.Append(node->GetSourceData()->mSrc + start, len);
if (mCharMapping != NULL) if (mCharMapping != NULL)
{ {
@ -256,6 +299,8 @@ int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx)
void BfPrinter::WriteIgnoredNode(BfAstNode* node) void BfPrinter::WriteIgnoredNode(BfAstNode* node)
{ {
bool wasExpectingNewLine = mExpectingNewLine;
mTriviaIdx = std::max(mTriviaIdx, node->GetTriviaStart()); mTriviaIdx = std::max(mTriviaIdx, node->GetTriviaStart());
int endIdx = mTriviaIdx; int endIdx = mTriviaIdx;
int crCount = 0; 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 // This handles tab adjustment within multiline comments
FlushIndent(); FlushIndent();
bool isNewLine = false; bool isNewLine = false;
@ -300,9 +385,90 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
#endif #endif
bool emitChar = true; bool emitChar = true;
char c = astNodeSrc->mSrc[srcIdx]; char c = astNodeSrc->mSrc[srcIdx];
if (c == '\n') if (c == '\n')
{
isNewLine = true; 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) else if (isNewLine)
{ {
if (c == ' ') if (c == ' ')
@ -320,21 +486,78 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
// Leave left-aligned preprocessor nodes that are commented out // Leave left-aligned preprocessor nodes that are commented out
if ((c != '#') || (mQueuedSpaceCount > 0)) if ((c != '#') || (mQueuedSpaceCount > 0))
mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset); mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset);
else
mQueuedSpaceCount = mCurIndentLevel * 4; // Do default indent
isNewLine = false; isNewLine = false;
} }
} }
if (emitChar) 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(); 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); mOutString.Append(c);
if (mCharMapping != NULL) if (mCharMapping != NULL)
{ {
if (srcIdx < mParser->mSrcLength) if (idx < mParser->mSrcLength)
mCharMapping->push_back(srcIdx); mCharMapping->push_back(idx);
else else
mCharMapping->push_back(-1); 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; mTriviaIdx = endIdx;
mIsFirstStatementInBlock = false; mIsFirstStatementInBlock = false;
mExpectingNewLine = wasExpectingNewLine;
} }
void BfPrinter::Visit(BfAstNode* bfAstNode) void BfPrinter::Visit(BfAstNode* bfAstNode)

View file

@ -62,6 +62,8 @@ public:
int mQueuedSpaceCount; int mQueuedSpaceCount;
int mLastSpaceOffset; // Indent difference from original to new int mLastSpaceOffset; // Indent difference from original to new
bool mExpectingNewLine; bool mExpectingNewLine;
int mCurCol;
int mMaxCol;
bool mIsFirstStatementInBlock; bool mIsFirstStatementInBlock;
bool mForceUseTrivia; bool mForceUseTrivia;

View file

@ -8330,14 +8330,15 @@ BfCommentNode * BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode*
while (mDocumentCheckIdx < mSource->mSidechannelRootNode->mChildArr.mSize) while (mDocumentCheckIdx < mSource->mSidechannelRootNode->mChildArr.mSize)
{ {
auto checkComment = BfNodeDynCast<BfCommentNode>(mSource->mSidechannelRootNode->mChildArr[mDocumentCheckIdx]); 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++; mDocumentCheckIdx++;
continue; continue;
} }
if (checkComment->GetSrcEnd() > defNodeEnd->GetSrcStart()) 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(); int defEnd = defNodeEnd->GetSrcEnd();
if (checkDocAfter) if (checkDocAfter)
@ -8368,7 +8369,8 @@ BfCommentNode * BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode*
return NULL; 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 // Skip this, not used
mDocumentCheckIdx++; mDocumentCheckIdx++;