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

3287 lines
76 KiB
C++
Raw Normal View History

2019-08-23 11:56:54 -07:00
#include "BfPrinter.h"
#include "BfParser.h"
#include "BfUtil.h"
2020-03-28 14:26:14 -07:00
#include "BeefySysLib/util/UTF8.h"
2019-08-23 11:56:54 -07:00
USING_NS_BF;
2020-03-28 14:26:14 -07:00
// 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)
{
2019-08-23 11:56:54 -07:00
mSource = rootNode->GetSourceData();
2020-03-28 14:26:14 -07:00
mParser = mSource->ToParserData();
2019-08-23 11:56:54 -07:00
if (sidechannelRootNode != NULL)
mSidechannelItr = sidechannelRootNode->begin();
mSidechannelNextNode = mSidechannelItr.Get();
2020-03-28 14:26:14 -07:00
2019-08-23 11:56:54 -07:00
if (errorRootNode != NULL)
2022-07-26 13:27:03 -04:00
mErrorItr = errorRootNode->begin();
mErrorNextNode = mErrorItr.Get();
2019-08-23 11:56:54 -07:00
mTriviaIdx = 0;
mCurSrcIdx = 0;
mCurIndentLevel = 0;
mCurBlockState = NULL;
2019-08-23 11:56:54 -07:00
mQueuedSpaceCount = 0;
mLastSpaceOffset = 0;
2022-07-26 13:27:03 -04:00
mReformatting = false;
2019-08-23 11:56:54 -07:00
mDocPrep = false;
mIgnoreTrivia = false;
2022-07-26 13:27:03 -04:00
mForceUseTrivia = false;
mIsFirstStatementInBlock = false;
2019-08-23 11:56:54 -07:00
mFormatStart = -1;
mFormatEnd = -1;
mInSideChannel = false;
mCharMapping = NULL;
mExpectingNewLine = false;
mCurBlockMember = NULL;
mStateModifyVirtualIndentLevel = 0;
mVirtualIndentLevel = 0;
mVirtualNewLineIdx = 0;
mHighestCharId = 0;
mCurTypeDecl = NULL;
2020-03-28 14:26:14 -07:00
mCurCol = 0;
mMaxCol = 120;
2022-05-16 11:01:30 -07:00
mTabSize = 4;
mWantsTabsAsSpaces = false;
mIndentCaseLabels = false;
mFormatDisableCount = 0;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Write(const StringView& str)
2022-07-26 13:27:03 -04:00
{
2020-03-28 14:26:14 -07:00
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')
2022-05-16 11:01:30 -07:00
mCurCol = ((mCurCol / mTabSize) + 1) * mTabSize;
2020-03-28 14:26:14 -07:00
else
mCurCol++;
2022-07-26 13:27:03 -04:00
}
}
2020-03-28 14:26:14 -07:00
2019-08-23 11:56:54 -07:00
mOutString.Append(str);
if (mCharMapping != NULL)
{
for (int i = 0; i < (int)str.length(); i++)
{
int prevSrcIdx = -1;
2022-07-26 13:27:03 -04:00
if (mCharMapping->size() > 0)
prevSrcIdx = mCharMapping->back();
2019-08-23 11:56:54 -07:00
if (prevSrcIdx != -1)
{
bool matched = false;
int curSrcIdx = prevSrcIdx + 1;
// Search for char, skipping over whitespace
while (curSrcIdx < mParser->mSrcLength)
{
char c = mParser->mSrc[curSrcIdx];
if (c == str[i])
{
matched = true;
break;
}
else if ((c == '\t') || (c == ' '))
curSrcIdx++;
else
break;
}
if (matched)
{
2022-07-26 13:27:03 -04:00
// It matches the source character, extend...
2019-08-23 11:56:54 -07:00
mCharMapping->push_back(curSrcIdx);
}
else
{
// New char
mCharMapping->push_back(-1);
}
}
else
{
mCharMapping->push_back(-1);
}
}
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
void BfPrinter::FlushIndent()
2022-07-26 13:27:03 -04:00
{
2022-05-16 11:01:30 -07:00
while ((mQueuedSpaceCount >= mTabSize) && (!mWantsTabsAsSpaces))
2019-08-23 11:56:54 -07:00
{
Write("\t");
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount -= mTabSize;
2019-08-23 11:56:54 -07:00
}
while (mQueuedSpaceCount > 0)
{
2022-07-26 13:27:03 -04:00
Write(" ");
2019-08-23 11:56:54 -07:00
mQueuedSpaceCount--;
}
}
void BfPrinter::Write(BfAstNode* node, int start, int len)
{
2022-07-26 13:27:03 -04:00
FlushIndent();
2020-03-28 14:26:14 -07:00
if (mMaxCol > 0)
{
int startCol = mCurCol;
2022-07-26 13:27:03 -04:00
2020-03-28 14:26:14 -07:00
auto parserData = node->GetParserData();
for (int i = 0; i < len; i++)
{
char c = parserData->mSrc[start + i];
if (c == '\t')
2022-05-16 11:01:30 -07:00
mCurCol = ((mCurCol / mTabSize) + 1) * mTabSize;
2020-03-28 14:26:14 -07:00
else
mCurCol++;
2022-07-26 13:27:03 -04:00
}
2020-03-28 14:26:14 -07:00
}
2019-08-23 11:56:54 -07:00
mOutString.Append(node->GetSourceData()->mSrc + start, len);
if (mCharMapping != NULL)
{
if (start < mParser->mSrcLength)
{
for (int i = 0; i < len; i++)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
mCharMapping->push_back(start + i);
}
}
else
{
for (int i = 0; i < len; i++)
mCharMapping->push_back(-1);
}
}
}
void BfPrinter::WriteSourceString(BfAstNode* node)
{
2022-07-26 13:27:03 -04:00
Write(node, node->GetSrcStart(), node->GetSrcLength());
2019-08-23 11:56:54 -07:00
}
void BfPrinter::QueueVisitChild(BfAstNode* astNode)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
if (astNode != NULL)
{
mNextStateModify.mQueuedNode = astNode;
mChildNodeQueue.push_back(mNextStateModify);
mNextStateModify.Clear();
}
}
void BfPrinter::QueueVisitErrorNodes(BfRootNode* astNode)
{
for (auto& childNodeRef : *astNode)
{
2022-07-26 13:27:03 -04:00
BfAstNode* childNode = childNodeRef;
2019-08-23 11:56:54 -07:00
if (childNode->IsA<BfErrorNode>())
QueueVisitChild(childNode);
}
}
static bool CompareNodeStart(const BfPrinter::StateModify& node1, const BfPrinter::StateModify& node2)
{
return node1.mQueuedNode->GetSrcStart() < node2.mQueuedNode->GetSrcStart();
}
void BfPrinter::FlushVisitChild()
{
if (mChildNodeQueue.size() == 0)
return;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
auto nodeQueue = mChildNodeQueue;
2022-07-26 13:27:03 -04:00
mChildNodeQueue.Clear();
std::stable_sort(nodeQueue.begin(), nodeQueue.end(), CompareNodeStart);
2019-08-23 11:56:54 -07:00
for (auto& node : nodeQueue)
{
mNextStateModify = node;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChild(node.mQueuedNode);
if (mVirtualNewLineIdx == mNextStateModify.mWantNewLineIdx)
mVirtualNewLineIdx = node.mWantNewLineIdx;
}
}
void BfPrinter::VisitChildWithPrecedingSpace(BfAstNode* bfAstNode)
{
if (bfAstNode == NULL)
return;
ExpectSpace();
VisitChild(bfAstNode);
}
void BfPrinter::VisitChildWithProceedingSpace(BfAstNode* bfAstNode)
{
if (bfAstNode == NULL)
2022-07-26 13:27:03 -04:00
return;
2019-08-23 11:56:54 -07:00
VisitChild(bfAstNode);
ExpectSpace();
}
void BfPrinter::ExpectSpace()
{
2022-07-26 13:27:03 -04:00
mNextStateModify.mExpectingSpace = true;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::ExpectNewLine()
{
2022-07-26 13:27:03 -04:00
mNextStateModify.mWantNewLineIdx++;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::ExpectIndent()
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
mNextStateModify.mWantVirtualIndent++;
ExpectNewLine();
}
void BfPrinter::ExpectUnindent()
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
mNextStateModify.mWantVirtualIndent--;
ExpectNewLine();
}
void BfPrinter::VisitChildNextLine(BfAstNode* node)
{
if (node == NULL)
return;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (node->IsA<BfBlock>())
{
VisitChild(node);
}
else
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectNewLine();
ExpectIndent();
VisitChild(node);
ExpectUnindent();
}
}
int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx)
{
int origLineSpacing = 0;
int checkIdx = bfAstNode->GetSrcStart() - 1;
auto astNodeSrc = bfAstNode->GetSourceData();
for ( ; checkIdx >= 0; checkIdx--)
{
char c = astNodeSrc->mSrc[checkIdx];
if (c == '\n')
break;
if (c == '\t')
2022-05-16 11:01:30 -07:00
origLineSpacing += mTabSize;
2019-08-23 11:56:54 -07:00
else if (c == ' ')
origLineSpacing += 1;
else
2022-07-26 13:27:03 -04:00
return -1;
2019-08-23 11:56:54 -07:00
}
if (lineStartIdx != NULL)
*lineStartIdx = checkIdx + 1;
return origLineSpacing;
}
void BfPrinter::WriteIgnoredNode(BfAstNode* node)
{
Update(node);
if (!mReformatting)
{
int startIdx = BF_MAX(node->mTriviaStart, mTriviaIdx);
Write(node, startIdx, node->mSrcEnd - startIdx);
2022-07-26 13:27:03 -04:00
mTriviaIdx = node->mSrcEnd;
return;
}
2021-12-21 07:14:46 -05:00
bool startsWithSpace = false;
2022-07-26 13:27:03 -04:00
2020-03-28 14:26:14 -07:00
bool wasExpectingNewLine = mExpectingNewLine;
2019-08-23 11:56:54 -07:00
mTriviaIdx = std::max(mTriviaIdx, node->GetTriviaStart());
2022-07-26 13:27:03 -04:00
int endIdx = mTriviaIdx;
2019-08-23 11:56:54 -07:00
int crCount = 0;
auto astNodeSrc = node->GetSourceData();
int srcEnd = node->GetSrcEnd();
for (int i = mTriviaIdx; i < srcEnd; i++)
{
char c = astNodeSrc->mSrc[i];
2021-12-21 07:14:46 -05:00
if ((i == mTriviaIdx) && (isspace((uint8)c)))
startsWithSpace = true;
2019-08-23 11:56:54 -07:00
if ((c == '\n') && (i < node->GetSrcStart()))
crCount++;
if (((c != ' ') && (c != '\t')) || (!mReformatting))
endIdx = i + 1;
}
2021-12-21 07:14:46 -05:00
bool wantsPrefixSpace = (!mOutString.IsEmpty()) && (!isspace((uint8)mOutString[mOutString.mLength - 1]));
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
bool expectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
int startIdx = mTriviaIdx;
if ((expectingNewLine) && (mReformatting))
{
// Try to adjust the tabbing of this comment by the same amount that the previous line was adjusted
int lineStart = -1;
int origLineSpacing = CalcOrigLineSpacing(node, &lineStart);
if ((origLineSpacing != -1) && (lineStart != -1))
{
for (int i = 0; i < crCount; i++)
2021-12-21 07:14:46 -05:00
{
2019-08-23 11:56:54 -07:00
Write("\n");
2021-12-21 07:14:46 -05:00
wantsPrefixSpace = false;
}
2019-08-23 11:56:54 -07:00
startIdx = node->GetSrcStart();
// Leave left-aligned preprocessor nodes
if ((node->GetSourceData()->mSrc[node->GetSrcStart()] != '#') || (origLineSpacing > 0))
2022-07-26 13:27:03 -04:00
mQueuedSpaceCount = origLineSpacing + mLastSpaceOffset;
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
2020-03-28 14:26:14 -07:00
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;
2021-02-25 10:14:22 -08:00
if (doWrap)
2022-07-26 13:27:03 -04:00
{
2021-02-25 10:14:22 -08:00
bool wantWrap = false;
int spacedWordCount = 0;
bool inQuotes = false;
auto src = astNodeSrc->mSrc;
bool isDefinitelyCode = false;
bool hadNonSlash = false;
for (int i = node->mSrcStart + 1; i < node->mSrcEnd - 1; i++)
{
char c = src[i];
if (c != '/')
hadNonSlash = true;
if (inQuotes)
{
if (c == '\\')
{
i++;
}
else if (c == '\"')
{
inQuotes = false;
}
}
else if (c == '"')
{
inQuotes = true;
}
else if (c == ' ')
{
if ((isalpha((uint8)src[i - 1])) && (isalpha((uint8)src[i + 1])))
spacedWordCount++;
}
else if ((c == '/') && (src[i - 1] == '/') && (hadNonSlash))
isDefinitelyCode = true;
}
// If this doesn't look like a sentence then don't try to word wrap
if ((isDefinitelyCode) || (spacedWordCount < 4))
doWrap = false;
}
2020-03-28 14:26:14 -07:00
}
int lineEmittedChars = 0;
2019-08-23 11:56:54 -07:00
// This handles tab adjustment within multiline comments
2022-07-26 13:27:03 -04:00
FlushIndent();
bool isNewLine = false;
2019-08-23 11:56:54 -07:00
for (int srcIdx = startIdx; srcIdx < endIdx; srcIdx++)
{
#ifdef A
int zap = 999;
#endif
bool emitChar = true;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
char c = astNodeSrc->mSrc[srcIdx];
2021-12-21 07:14:46 -05:00
if ((wantsPrefixSpace) && (isspace((uint8)c)))
wantsPrefixSpace = false;
2020-03-28 14:26:14 -07:00
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++)
{
2022-07-26 13:27:03 -04:00
char checkC = astNodeSrc->mSrc[checkIdx];
2020-03-28 14:26:14 -07:00
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;
2022-07-26 13:27:03 -04:00
}
2020-03-28 14:26:14 -07:00
}
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;
}
2022-07-26 13:27:03 -04:00
else if (isNewLine)
2019-08-23 11:56:54 -07:00
{
if (c == ' ')
{
mQueuedSpaceCount++;
emitChar = false;
}
else if (c == '\t')
{
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount += mTabSize;
2019-08-23 11:56:54 -07:00
emitChar = false;
}
else
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
// Leave left-aligned preprocessor nodes that are commented out
if ((c != '#') || (mQueuedSpaceCount > 0))
2020-03-28 14:26:14 -07:00
mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset);
else
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount = mCurIndentLevel * mTabSize; // Do default indent
2022-07-26 13:27:03 -04:00
isNewLine = false;
2019-08-23 11:56:54 -07:00
}
}
if (emitChar)
2022-07-26 13:27:03 -04:00
{
2020-03-28 14:26:14 -07:00
int startIdx = srcIdx;
if (c != '\n')
2019-08-23 11:56:54 -07:00
{
2020-03-28 14:26:14 -07:00
while (srcIdx < endIdx)
2022-07-26 13:27:03 -04:00
{
2020-03-28 14:26:14 -07:00
char c = astNodeSrc->mSrc[srcIdx + 1];
if (isspace((uint8)c))
break;
srcIdx++;
}
}
2022-07-26 13:27:03 -04:00
2020-03-28 14:26:14 -07:00
if (doWrap)
{
int len = 0;
for (int idx = startIdx; idx <= srcIdx; idx++)
{
char c = astNodeSrc->mSrc[idx];
if (isutf(c))
len++;
}
2022-07-26 13:27:03 -04:00
if ((mCurCol + len > mMaxCol) && (lineEmittedChars >= 8))
2020-03-28 14:26:14 -07:00
{
Write("\n");
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount = mCurIndentLevel * mTabSize;
2020-03-28 14:26:14 -07:00
FlushIndent();
if (isStarredBlockComment)
Write(" * ");
2022-07-26 13:27:03 -04:00
else if (!isBlockComment)
2020-03-28 14:26:14 -07:00
Write("// ");
2022-07-26 13:27:03 -04:00
prevHadWrap = true;
2020-03-28 14:26:14 -07:00
while (startIdx < endIdx)
{
char c = astNodeSrc->mSrc[startIdx];
if (!isspace((uint8)c))
break;
startIdx++;
}
lineEmittedChars = 0;
2020-03-28 14:26:14 -07:00
}
}
2021-12-21 07:14:46 -05:00
if (wantsPrefixSpace)
2022-07-26 13:27:03 -04:00
{
2021-12-21 07:14:46 -05:00
mQueuedSpaceCount++;
wantsPrefixSpace = false;
}
FlushIndent();
2020-03-28 14:26:14 -07:00
for (int idx = startIdx; idx <= BF_MIN(srcIdx, endIdx - 1); idx++)
2020-03-28 14:26:14 -07:00
{
char c = astNodeSrc->mSrc[idx];
mOutString.Append(c);
if (mCharMapping != NULL)
{
if (idx < mParser->mSrcLength)
mCharMapping->push_back(idx);
else
mCharMapping->push_back(-1);
}
if (c == '\n')
{
mCurCol = 0;
lineEmittedChars = 0;
}
2020-03-28 14:26:14 -07:00
else if (isutf(c))
{
2020-03-28 14:26:14 -07:00
mCurCol++;
lineEmittedChars++;
}
2019-08-23 11:56:54 -07:00
}
}
}
FlushIndent();
2022-07-26 13:27:03 -04:00
mTriviaIdx = endIdx;
2019-08-23 11:56:54 -07:00
mIsFirstStatementInBlock = false;
2020-03-28 14:26:14 -07:00
mExpectingNewLine = wasExpectingNewLine;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::CheckRawNode(BfAstNode* node)
{
if (node == NULL)
return;
if ((!BfNodeIsExact<BfTokenNode>(node)) &&
(!BfNodeIsExact<BfIdentifierNode>(node)) &&
(!BfNodeIsExact<BfLiteralExpression>(node)))
return;
2022-07-26 13:27:03 -04:00
//mForceUseTrivia = true;
// Usually 'raw' nodes get merged into larger nodes like expressions/statements, but if they don't then this tries to help formatting
mExpectingNewLine = false;
mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx;
mNextStateModify.mExpectingSpace = false;
bool inLineStart = false;
int spaceCount = 0;
2022-07-26 13:27:03 -04:00
auto parserData = node->GetParserData();
for (int i = node->mTriviaStart; i < node->mSrcStart; i++)
{
char c = parserData->mSrc[i];
if (c == '\n')
{
ExpectNewLine();
inLineStart = true;
spaceCount = 0;
}
else if (c == '\t')
{
ExpectSpace();
if (inLineStart)
2022-05-16 11:01:30 -07:00
spaceCount += mTabSize;
}
else if (c == ' ')
{
ExpectSpace();
if (inLineStart)
spaceCount++;
}
else
{
inLineStart = false;
}
}
if ((spaceCount > 0) && (mCurBlockState != NULL))
{
2022-05-16 11:01:30 -07:00
int indentCount = spaceCount / mTabSize;
mNextStateModify.mWantVirtualIndent = BF_MAX(indentCount, mCurBlockState->mIndentStart + 1);
}
}
void BfPrinter::Update(BfAstNode* bfAstNode)
{
// This won't be true if we move nodes around during refactoring
if (bfAstNode->GetSrcStart() >= mCurSrcIdx)
{
mCurSrcIdx = bfAstNode->GetSrcStart();
}
if ((!mReformatting) && (mFormatDisableCount == 0) && (mFormatStart != -1) && (mCurSrcIdx >= mFormatStart) && ((mCurSrcIdx < mFormatEnd) || (mFormatEnd == -1)))
{
mReformatting = true;
// We entered the format region, figure our what our current indent level is
int backIdx = mCurSrcIdx - 1;
int prevSpaceCount = 0;
auto astNodeSrc = bfAstNode->GetSourceData();
while (backIdx >= 0)
{
char c = astNodeSrc->mSrc[backIdx];
if (c == ' ')
prevSpaceCount++;
else if (c == '\t')
prevSpaceCount += mTabSize;
else if (c == '\n')
{
// Found previous line
mCurIndentLevel = prevSpaceCount / mTabSize;
break;
}
else
{
prevSpaceCount = 0;
}
backIdx--;
}
}
if (mFormatDisableCount != 0)
mReformatting = false;
if ((mCurSrcIdx >= mFormatEnd) && (mFormatEnd != -1))
mReformatting = false;
bool expectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx;
if (expectingNewLine)
mExpectingNewLine = true;
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfAstNode* bfAstNode)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
SetAndRestoreValue<bool> prevForceTrivia(mForceUseTrivia);
bool newExpectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx;
if (newExpectingNewLine)
2019-08-23 11:56:54 -07:00
mExpectingNewLine = true;
bool expectingNewLine = mExpectingNewLine;
2019-08-23 11:56:54 -07:00
int indentOffset = 0;
if (bfAstNode->GetTriviaStart() != -1)
2022-07-26 13:27:03 -04:00
{
if (newExpectingNewLine)
2019-08-23 11:56:54 -07:00
{
indentOffset = mNextStateModify.mWantVirtualIndent - mVirtualIndentLevel;
mVirtualIndentLevel += indentOffset;
mCurIndentLevel += indentOffset;
}
}
while (true)
{
2022-07-26 13:27:03 -04:00
int sidechannelDist = -1;
2019-08-23 11:56:54 -07:00
if (mSidechannelNextNode != NULL)
sidechannelDist = bfAstNode->GetSrcStart() - mSidechannelNextNode->GetSrcStart();
int errorDist = -1;
if (mErrorNextNode != NULL)
errorDist = bfAstNode->GetSrcStart() - mErrorNextNode->GetSrcStart();
if ((sidechannelDist > 0) && (sidechannelDist >= errorDist))
{
BF_ASSERT(!mInSideChannel);
mInSideChannel = true;
VisitChild(mSidechannelNextNode);
mInSideChannel = false;
++mSidechannelItr;
mSidechannelNextNode = mSidechannelItr.Get();
}
else if (errorDist > 0)
{
auto curErrorNode = mErrorNextNode;
++mErrorItr;
2022-07-26 13:27:03 -04:00
mErrorNextNode = mErrorItr.Get();
2019-08-23 11:56:54 -07:00
mForceUseTrivia = true;
2022-07-26 13:27:03 -04:00
VisitChild(curErrorNode);
2019-08-23 11:56:54 -07:00
}
else
break;
}
2022-07-26 13:27:03 -04:00
Update(bfAstNode);
2019-08-23 11:56:54 -07:00
// When triviaStart == -1, that indicates it's a combined node where the text we want to process is on the inside
2022-07-26 13:27:03 -04:00
if (bfAstNode->GetTriviaStart() != -1)
{
2019-08-23 11:56:54 -07:00
mTriviaIdx = std::max(mTriviaIdx, bfAstNode->GetTriviaStart());
bool usedTrivia = false;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if ((!mIgnoreTrivia) && (mTriviaIdx < bfAstNode->GetSrcStart()))
{
if ((!mReformatting) || (mForceUseTrivia))
{
Write(bfAstNode, mTriviaIdx, bfAstNode->GetSrcStart() - mTriviaIdx);
usedTrivia = true;
2022-07-26 13:27:03 -04:00
}
}
2019-08-23 11:56:54 -07:00
if ((mReformatting) && (!mInSideChannel))
{
// Check to see if our trivia contained a newline and duplicate whatever the
// indent increase was from the previous line
if ((!usedTrivia) && (mTriviaIdx < bfAstNode->GetSrcStart()) && (!mIsFirstStatementInBlock) && (!mNextStateModify.mDoingBlockOpen) && (!mNextStateModify.mDoingBlockClose))
{
bool hadNewline = true;
bool hadPrevLineSpacing = false;
int prevSpaceCount = -1;
int spaceCount = 0;
auto astNodeSrc = bfAstNode->GetSourceData();
bool canUseTrivia = true;
int spaceTriviaStart = -1;
int triviaEnd = bfAstNode->GetSrcStart();
for (int i = mTriviaIdx; i < triviaEnd; i++)
2019-08-23 11:56:54 -07:00
{
if (mIgnoreTrivia)
2022-07-26 13:27:03 -04:00
break;
2019-08-23 11:56:54 -07:00
char c = astNodeSrc->mSrc[i];
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (c == ' ')
{
if (spaceTriviaStart == -1)
spaceTriviaStart = i;
2019-08-23 11:56:54 -07:00
spaceCount++;
}
2019-08-23 11:56:54 -07:00
else if (c == '\t')
{
if (spaceTriviaStart == -1)
spaceTriviaStart = i;
2022-05-16 11:01:30 -07:00
spaceCount += mTabSize;
}
2019-08-23 11:56:54 -07:00
if (((c == '\n') || (i == bfAstNode->GetSrcStart() - 1)) && (hadPrevLineSpacing) && (prevSpaceCount > 0))
2022-07-26 13:27:03 -04:00
{
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount += std::max(0, spaceCount - prevSpaceCount) - std::max(0, indentOffset * mTabSize);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
prevSpaceCount = -1;
hadPrevLineSpacing = false;
}
if (c == '\n')
{
canUseTrivia = false;
2019-08-23 11:56:54 -07:00
hadNewline = true;
int backIdx = i - 1;
2022-07-26 13:27:03 -04:00
prevSpaceCount = 0;
2019-08-23 11:56:54 -07:00
while (backIdx >= 0)
{
char c = astNodeSrc->mSrc[backIdx];
if (c == ' ')
prevSpaceCount++;
else if (c == '\t')
2022-05-16 11:01:30 -07:00
prevSpaceCount += mTabSize;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if ((c == '\n') || (backIdx == 0))
{
// Found previous line
usedTrivia = true;
Write("\n");
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount = mCurIndentLevel * mTabSize;
2019-08-23 11:56:54 -07:00
// Indents extra if we have a statement split over multiple lines
if (!expectingNewLine)
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount += mTabSize;
2019-08-23 11:56:54 -07:00
break;
}
else
{
hadPrevLineSpacing = true;
prevSpaceCount = 0;
}
backIdx--;
}
spaceCount = 0;
spaceTriviaStart = -1;
2019-08-23 11:56:54 -07:00
}
else if (!isspace((uint8)c))
{
spaceCount = 0;
spaceTriviaStart = -1;
2022-07-26 13:27:03 -04:00
}
}
if ((canUseTrivia) && (spaceCount > 1) && (spaceTriviaStart != -1))
{
Write(bfAstNode, spaceTriviaStart, triviaEnd - spaceTriviaStart);
mNextStateModify.mExpectingSpace = false;
usedTrivia = true;
}
2019-08-23 11:56:54 -07:00
}
if (usedTrivia)
{
// Already did whitespace
mNextStateModify.mExpectingSpace = false;
2019-08-23 11:56:54 -07:00
}
else if ((mNextStateModify.mDoingBlockOpen) || (mNextStateModify.mDoingBlockClose) || (mIsFirstStatementInBlock))
{
int wasOnNewLine = true;
int idx = (int)mOutString.length() - 1;
while (idx >= 0)
{
char c = mOutString[idx];
if (c == '\n')
break;
if (!isspace((uint8)c))
{
Write("\n");
2022-05-16 11:01:30 -07:00
mQueuedSpaceCount = mCurIndentLevel * mTabSize;
if (!mNextStateModify.mDoingBlockClose)
{
int origLineSpacing = CalcOrigLineSpacing(bfAstNode, NULL);
if (origLineSpacing != -1)
mLastSpaceOffset = mQueuedSpaceCount - origLineSpacing;
}
2019-08-23 11:56:54 -07:00
break;
}
idx--;
}
}
else if ((mNextStateModify.mExpectingSpace) || (newExpectingNewLine))
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
FlushIndent();
char startChar = bfAstNode->GetSourceData()->mSrc[bfAstNode->GetSrcStart()];
bool isEnding = (startChar == ';') || (startChar == ')');
if ((!isEnding) && (mOutString.length() > 0) && (!isspace((uint8)mOutString[mOutString.length() - 1])))
Write(" ");
2022-07-26 13:27:03 -04:00
}
}
2019-08-23 11:56:54 -07:00
if (!mInSideChannel)
{
if (mNextStateModify.mDoingBlockOpen)
mIsFirstStatementInBlock = true;
else
mIsFirstStatementInBlock = false;
mNextStateModify.mExpectingSpace = false;
mNextStateModify.mDoingBlockOpen = false;
mNextStateModify.mDoingBlockClose = false;
mNextStateModify.Clear();
mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx;
}
2022-07-26 13:27:03 -04:00
mForceUseTrivia = false;
2019-08-23 11:56:54 -07:00
if (bfAstNode->GetSrcStart() >= mTriviaIdx)
mTriviaIdx = bfAstNode->GetSrcStart();
// We either used this mExpectingNewLine to do an extra indent for a statement split over multiple lines or we didn't
mExpectingNewLine = false;
}
}
bool BfPrinter::CheckReplace(BfAstNode* astNode)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
return false;
}
void BfPrinter::Visit(BfErrorNode* errorNode)
{
SetAndRestoreValue<bool> prevForceUseTrivia(mForceUseTrivia, true);
SetAndRestoreValue<bool> prevFormatting(mReformatting, false);
SetAndRestoreValue<int> prevFormatEndIdx(mFormatEnd, 0);
VisitChild(errorNode->mRefNode);
}
void BfPrinter::Visit(BfScopeNode* scopeNode)
{
Visit(scopeNode->ToBase());
VisitChild(scopeNode->mScopeToken);
VisitChild(scopeNode->mColonToken);
VisitChild(scopeNode->mTargetNode);
if (scopeNode->mAttributes != NULL)
{
ExpectSpace();
VisitChild(scopeNode->mAttributes);
}
}
void BfPrinter::Visit(BfNewNode* newNode)
{
Visit(newNode->ToBase());
VisitChild(newNode->mNewToken);
VisitChild(newNode->mColonToken);
VisitChild(newNode->mAllocNode);
if (newNode->mAttributes != NULL)
{
ExpectSpace();
VisitChild(newNode->mAttributes);
}
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfExpression* expr)
{
2022-07-26 13:27:03 -04:00
Visit(expr->ToBase());
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfExpressionStatement* exprStmt)
{
//Visit((BfAstNode*)exprStmt);
Visit(exprStmt->ToBase());
VisitChild(exprStmt->mExpression);
VisitChild(exprStmt->mTrailingSemicolon);
}
2022-06-24 18:41:54 -07:00
void BfPrinter::Visit(BfNamedExpression* namedExpr)
{
Visit(namedExpr->ToBase());
VisitChild(namedExpr->mNameNode);
VisitChild(namedExpr->mColonToken);
ExpectSpace();
VisitChild(namedExpr->mExpression);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfAttributedExpression* attribExpr)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
Visit(attribExpr->ToBase());
if (auto indexerExpr = BfNodeDynCast<BfIndexerExpression>(attribExpr->mExpression))
{
VisitChild(indexerExpr->mTarget);
VisitChild(indexerExpr->mOpenBracket);
VisitChild(attribExpr->mAttributes);
for (int i = 0; i < (int)indexerExpr->mArguments.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(indexerExpr->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(indexerExpr->mArguments[i]);
}
2022-07-26 13:27:03 -04:00
VisitChild(indexerExpr->mCloseBracket);
2019-08-23 11:56:54 -07:00
}
else
{
VisitChild(attribExpr->mAttributes);
VisitChild(attribExpr->mExpression);
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfStatement* stmt)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
// Trailing semicolon must come after, so every derived type is responsible for printing it
2022-07-26 13:27:03 -04:00
#ifdef BF_AST_HAS_PARENT_MEMBER
2019-08-23 11:56:54 -07:00
// if (stmt->mParent != NULL)
// {
// if (auto block = BfNodeDynCast<BfBlock>(stmt->mParent))
// {
// if (block->mOpenBrace != NULL)
// {
// if (mReformatting)
// BF_ASSERT(stmt == mCurBlockMember);
// }
// }
// }
#endif
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (stmt == mCurBlockMember)
ExpectNewLine();
//Visit(stmt->ToBase());
}
void BfPrinter::Visit(BfLabelableStatement* labelableStmt)
{
Visit(labelableStmt->ToBase());
if (labelableStmt->mLabelNode != NULL)
{
ExpectNewLine();
VisitChild(labelableStmt->mLabelNode->mLabel);
VisitChild(labelableStmt->mLabelNode->mColonToken);
}
}
void BfPrinter::Visit(BfCommentNode* commentNode)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
WriteIgnoredNode(commentNode);
2021-12-21 07:14:46 -05:00
if (commentNode->mCommentKind == BfCommentKind_Line)
ExpectNewLine();
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection)
{
WriteIgnoredNode(preprocesorIgnoredSection);
ExpectNewLine();
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfPreprocessorNode* preprocessorNode)
{
WriteIgnoredNode(preprocessorNode);
2022-07-26 13:27:03 -04:00
if ((preprocessorNode->mCommand->ToStringView() == "pragma") &&
(preprocessorNode->mArgument != NULL) &&
(preprocessorNode->mArgument->mChildArr.mSize == 2) &&
(preprocessorNode->mArgument->mChildArr[0] != NULL) &&
(preprocessorNode->mArgument->mChildArr[0]->ToStringView() == "format") &&
(preprocessorNode->mArgument->mChildArr[1] != NULL))
{
if (preprocessorNode->mArgument->mChildArr[1]->ToStringView() == "disable")
mFormatDisableCount++;
else if (preprocessorNode->mArgument->mChildArr[1]->ToStringView() == "restore")
mFormatDisableCount = BF_MAX(0, mFormatDisableCount - 1);
}
2022-07-26 13:27:03 -04:00
ExpectNewLine();
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfAttributeDirective* attributeDirective)
{
Visit(attributeDirective->ToBase());
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (attributeDirective->mAttrOpenToken != NULL)
{
if (attributeDirective->mAttrOpenToken->mToken == BfToken_Comma)
{
VisitChild(attributeDirective->mAttrOpenToken);
ExpectSpace();
}
else
{
SetAndRestoreValue<bool> prevExpectNewLine(mExpectingNewLine, true);
VisitChild(attributeDirective->mAttrOpenToken);
}
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (attributeDirective->mAttributeTargetSpecifier != NULL)
{
if (auto attributeTargetSpecifier = BfNodeDynCast<BfAttributeTargetSpecifier>(attributeDirective->mAttributeTargetSpecifier))
{
VisitChild(attributeTargetSpecifier->mTargetToken);
VisitChild(attributeTargetSpecifier->mColonToken);
ExpectSpace();
}
else
{
VisitChild(attributeDirective->mAttributeTargetSpecifier);
}
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChild(attributeDirective->mAttributeTypeRef);
VisitChild(attributeDirective->mCtorOpenParen);
for (int i = 0; i < (int)attributeDirective->mArguments.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(attributeDirective->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(attributeDirective->mArguments[i]);
2019-08-23 11:56:54 -07:00
}
VisitChild(attributeDirective->mCtorCloseParen);
VisitChild(attributeDirective->mAttrCloseToken);
if ((attributeDirective->mNextAttribute != NULL) && (attributeDirective->mNextAttribute->mAttrOpenToken != NULL) &&
(attributeDirective->mNextAttribute->mAttrOpenToken->mToken == BfToken_LBracket))
ExpectNewLine();
2019-08-23 11:56:54 -07:00
VisitChild(attributeDirective->mNextAttribute);
}
void BfPrinter::Visit(BfGenericParamsDeclaration* genericParams)
{
Visit(genericParams->ToBase());
VisitChild(genericParams->mOpenChevron);
for (int i = 0; i < (int)genericParams->mGenericParams.size(); i++)
2019-08-23 11:56:54 -07:00
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(genericParams->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(genericParams->mGenericParams[i]);
2019-08-23 11:56:54 -07:00
}
VisitChild(genericParams->mCloseChevron);
}
void BfPrinter::Visit(BfGenericOperatorConstraint* genericConstraints)
{
Visit(genericConstraints->ToBase());
VisitChild(genericConstraints->mOperatorToken);
ExpectSpace();
VisitChild(genericConstraints->mLeftType);
ExpectSpace();
VisitChild(genericConstraints->mOpToken);
ExpectSpace();
VisitChild(genericConstraints->mRightType);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfGenericConstraintsDeclaration* genericConstraints)
{
Visit(genericConstraints->ToBase());
for (auto genericConstraintNode : genericConstraints->mGenericConstraints)
2019-08-23 11:56:54 -07:00
{
auto genericConstraint = BfNodeDynCast<BfGenericConstraint>(genericConstraintNode);
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(genericConstraint->mWhereToken);
ExpectSpace();
VisitChild(genericConstraint->mTypeRef);
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(genericConstraint->mColonToken);
ExpectSpace();
for (int i = 0; i < (int)genericConstraint->mConstraintTypes.size(); i++)
{
if (i > 0)
{
if (!genericConstraint->mCommas.IsEmpty())
2020-09-06 05:28:19 -07:00
VisitChildNoRef(genericConstraint->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(genericConstraint->mConstraintTypes[i]);
2019-08-23 11:56:54 -07:00
}
}
}
void BfPrinter::Visit(BfGenericArgumentsNode* genericArgumentsNode)
{
Visit(genericArgumentsNode->ToBase());
VisitChild(genericArgumentsNode->mOpenChevron);
for (int i = 0; i < (int)genericArgumentsNode->mGenericArgs.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(genericArgumentsNode->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(genericArgumentsNode->mGenericArgs[i]);
2019-08-23 11:56:54 -07:00
}
for (int i = (int)genericArgumentsNode->mGenericArgs.size() - 1; i < (int)genericArgumentsNode->mCommas.size(); i++)
VisitChildNoRef(genericArgumentsNode->mCommas.GetSafe(i));
2019-08-23 11:56:54 -07:00
VisitChild(genericArgumentsNode->mCloseChevron);
}
void BfPrinter::Visit(BfEmptyStatement* emptyStmt)
{
Visit(emptyStmt->ToBase());
VisitChild(emptyStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfTokenNode* tokenNode)
{
Visit(tokenNode->ToBase());
if (mDocPrep)
{
if (tokenNode->mToken == BfToken_Mut)
return;
}
if (tokenNode->GetSrcEnd() == 0)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
String tokenStr = BfTokenToString(tokenNode->GetToken());
Write(tokenStr);
}
else
{
BF_ASSERT(tokenNode->GetSrcEnd() > tokenNode->GetSrcStart());
WriteSourceString(tokenNode);
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
2020-12-07 07:53:12 -08:00
void BfPrinter::Visit(BfTokenPairNode* tokenPairNode)
{
Visit(tokenPairNode->ToBase());
VisitChild(tokenPairNode->mLeft);
if ((tokenPairNode->mRight != NULL) && (tokenPairNode->mRight->mToken != BfToken_Star))
ExpectSpace();
VisitChild(tokenPairNode->mRight);
}
2022-07-13 07:07:38 -04:00
void BfPrinter::Visit(BfUsingSpecifierNode* usingSpecifier)
{
Visit(usingSpecifier->ToBase());
VisitChild(usingSpecifier->mProtection);
ExpectSpace();
VisitChild(usingSpecifier->mUsingToken);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfLiteralExpression* literalExpr)
{
Visit(literalExpr->ToBase());
if (literalExpr->mValue.mTypeCode == BfTypeCode_CharPtr)
{
bool isMultiLine = false;
auto sourceData = literalExpr->GetSourceData();
for (int i = literalExpr->GetSrcStart(); i < (int)literalExpr->GetSrcEnd(); i++)
{
char c = sourceData->mSrc[i];
if (c == '\n')
{
isMultiLine = true;
break;
}
}
if (isMultiLine)
{
int srcLineStart = 0;
int checkIdx = literalExpr->GetSrcStart() - 1;
while (checkIdx >= 0)
{
char c = sourceData->mSrc[checkIdx];
if (c == '\n')
{
srcLineStart = checkIdx + 1;
break;
}
checkIdx--;
}
2022-07-26 13:27:03 -04:00
int queuedSpaceCount = mQueuedSpaceCount;
FlushIndent();
for (int i = literalExpr->GetSrcStart(); i < (int)literalExpr->GetSrcEnd(); i++)
{
char c = sourceData->mSrc[i];
Write(c);
if (c == '\n')
{
i++;
int srcIdx = srcLineStart;
while (true)
{
char srcC = sourceData->mSrc[srcIdx++];
char litC = sourceData->mSrc[i];
if (srcC != litC)
break;
if ((srcC != ' ') && (srcC != '\t'))
break;
i++;
}
mQueuedSpaceCount = queuedSpaceCount;
FlushIndent();
i--;
2022-07-26 13:27:03 -04:00
}
}
2022-07-26 13:27:03 -04:00
return;
}
}
2022-07-26 13:27:03 -04:00
WriteSourceString(literalExpr);
2019-08-23 11:56:54 -07:00
}
2020-11-11 05:46:52 -08:00
void BfPrinter::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
{
Visit(stringInterpolationExpression->ToBase());
String str;
stringInterpolationExpression->ToString(str);
Write(str);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfIdentifierNode* identifierNode)
{
2022-07-26 13:27:03 -04:00
Visit(identifierNode->ToBase());
2019-08-23 11:56:54 -07:00
if (!CheckReplace(identifierNode))
{
if (!mOutString.IsEmpty())
{
char endC = mOutString[mOutString.mLength - 1];
if ((endC == '_') || (isalnum((uint8)endC)))
{
// Can fix spacing in error conditions
if (identifierNode->mTriviaStart >= 0)
Write(identifierNode, identifierNode->mTriviaStart, identifierNode->mSrcStart - identifierNode->mTriviaStart);
}
}
2019-08-23 11:56:54 -07:00
WriteSourceString(identifierNode);
}
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfQualifiedNameNode* nameNode)
{
Visit((BfAstNode*)nameNode);
VisitChild(nameNode->mLeft);
VisitChild(nameNode->mDot);
VisitChild(nameNode->mRight);
}
void BfPrinter::Visit(BfThisExpression* thisExpr)
{
Visit((BfAstNode*)thisExpr);
WriteSourceString(thisExpr);
}
void BfPrinter::Visit(BfBaseExpression* baseExpr)
{
Visit((BfAstNode*)baseExpr);
WriteSourceString(baseExpr);
}
void BfPrinter::Visit(BfMixinExpression* mixinExpr)
{
Visit((BfAstNode*)mixinExpr);
WriteSourceString(mixinExpr);
}
void BfPrinter::Visit(BfSizedArrayCreateExpression* createExpr)
{
Visit(createExpr->ToBase());
VisitChild(createExpr->mTypeRef);
VisitChildWithPrecedingSpace(createExpr->mInitializer);
}
2020-06-18 06:12:14 -07:00
void BfPrinter::Visit(BfInitializerExpression* initExpr)
{
Visit(initExpr->ToBase());
VisitChild(initExpr->mTarget);
BlockState blockState;
2022-07-26 13:27:03 -04:00
DoBlockOpen(initExpr->mTarget, initExpr->mOpenBrace, initExpr->mCloseBrace, false, blockState);
2020-06-18 06:12:14 -07:00
for (int i = 0; i < (int)initExpr->mValues.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(initExpr->mCommas.GetSafe(i - 1));
if (blockState.mDoInlineBlock)
ExpectSpace();
else
ExpectNewLine();
2020-06-18 06:12:14 -07:00
}
2022-07-26 13:27:03 -04:00
2020-06-18 06:12:14 -07:00
VisitChild(initExpr->mValues[i]);
}
DoBlockClose(initExpr->mTarget, initExpr->mOpenBrace, initExpr->mCloseBrace, false, blockState);
// Visit(initExpr->ToBase());
2022-07-26 13:27:03 -04:00
//
// VisitChild(initExpr->mTarget);
// ExpectSpace();
// VisitChild(initExpr->mOpenBrace);
// ExpectIndent();
// for (int i = 0; i < (int)initExpr->mValues.size(); i++)
// {
// if (i > 0)
// {
// VisitChildNoRef(initExpr->mCommas.GetSafe(i - 1));
// ExpectSpace();
// }
// VisitChild(initExpr->mValues[i]);
// }
// ExpectUnindent();
// VisitChild(initExpr->mCloseBrace);
2020-06-18 06:12:14 -07:00
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfCollectionInitializerExpression* initExpr)
{
Visit(initExpr->ToBase());
VisitChild(initExpr->mOpenBrace);
for (int i = 0; i < (int)initExpr->mValues.size(); i++)
2019-08-23 11:56:54 -07:00
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(initExpr->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(initExpr->mValues[i]);
}
VisitChild(initExpr->mCloseBrace);
}
void BfPrinter::Visit(BfTypeReference* typeRef)
{
Visit(typeRef->ToBase());
}
void BfPrinter::Visit(BfNamedTypeReference* typeRef)
{
Visit((BfAstNode*) typeRef);
VisitChild(typeRef->mNameNode);
}
void BfPrinter::Visit(BfQualifiedTypeReference* qualifiedTypeRef)
{
Visit(qualifiedTypeRef->ToBase());
VisitChild(qualifiedTypeRef->mLeft);
VisitChild(qualifiedTypeRef->mDot);
VisitChild(qualifiedTypeRef->mRight);
}
void BfPrinter::Visit(BfVarTypeReference* typeRef)
{
Visit(typeRef->ToBase());
VisitChild(typeRef->mVarToken);
}
void BfPrinter::Visit(BfLetTypeReference* typeRef)
{
Visit(typeRef->ToBase());
VisitChild(typeRef->mLetToken);
}
void BfPrinter::Visit(BfConstTypeRef* typeRef)
{
Visit(typeRef->ToBase());
VisitChild(typeRef->mConstToken);
ExpectSpace();
VisitChild(typeRef->mElementType);
}
void BfPrinter::Visit(BfConstExprTypeRef* typeRef)
{
Visit(typeRef->ToBase());
if (typeRef->mConstToken != NULL)
{
VisitChild(typeRef->mConstToken);
ExpectSpace();
}
VisitChild(typeRef->mConstExpr);
}
void BfPrinter::Visit(BfRefTypeRef* typeRef)
{
Visit(typeRef->ToBase());
VisitChild(typeRef->mRefToken);
ExpectSpace();
VisitChild(typeRef->mElementType);
}
void BfPrinter::Visit(BfArrayTypeRef* arrayTypeRef)
{
Visit((BfAstNode*)arrayTypeRef);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
std::function<void(BfTypeReference*)> _VisitElements = [&](BfTypeReference* elementRef)
{
auto arrType = BfNodeDynCast<BfArrayTypeRef>(elementRef);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (arrType != NULL)
{
_VisitElements(arrType->mElementType);
}
else
{
VisitChild(elementRef);
}
};
std::function<void(BfArrayTypeRef*)> _VisitBrackets = [&](BfArrayTypeRef* arrayTypeRef)
{
VisitChild(arrayTypeRef->mOpenBracket);
for (int paramIdx = 0; paramIdx < (int)arrayTypeRef->mParams.size(); paramIdx++)
{
auto param = arrayTypeRef->mParams[paramIdx];
if (paramIdx > 0)
{
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(param))
{
}
else
{
ExpectSpace();
}
}
VisitChild(param);
}
VisitChild(arrayTypeRef->mCloseBracket);
if (auto innerArrayType = BfNodeDynCast<BfArrayTypeRef>(arrayTypeRef->mElementType))
_VisitBrackets(innerArrayType);
};
_VisitElements(arrayTypeRef);
_VisitBrackets(arrayTypeRef);
}
void BfPrinter::Visit(BfGenericInstanceTypeRef* genericInstTypeRef)
{
Visit((BfAstNode*) genericInstTypeRef);
VisitChild(genericInstTypeRef->mElementType);
VisitChild(genericInstTypeRef->mOpenChevron);
if (genericInstTypeRef->mGenericArguments.size() > 0)
{
for (int i = 0; i < (int)genericInstTypeRef->mGenericArguments.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(genericInstTypeRef->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(genericInstTypeRef->mGenericArguments[i]);
}
}
else
{
for (auto comma : genericInstTypeRef->mCommas)
VisitChild(comma);
}
VisitChild(genericInstTypeRef->mCloseChevron);
}
void BfPrinter::Visit(BfTupleTypeRef* typeRef)
{
Visit((BfAstNode*) typeRef);
2022-07-26 13:27:03 -04:00
VisitChild(typeRef->mOpenParen);
2019-08-23 11:56:54 -07:00
for (int i = 0; i < (int)typeRef->mFieldTypes.size(); i++)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(typeRef->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(typeRef->mFieldTypes[i]);
if (i < (int)typeRef->mFieldNames.size())
{
ExpectSpace();
auto fieldNameNode = typeRef->mFieldNames[i];
2022-07-26 13:27:03 -04:00
if (fieldNameNode != NULL)
2019-08-23 11:56:54 -07:00
VisitChild(fieldNameNode);
}
}
VisitChild(typeRef->mCloseParen);
}
2024-11-08 09:16:27 -05:00
void BfPrinter::Visit(BfTagTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);
VisitChild(typeRef->mTagNode);
ExpectSpace();
VisitChild(typeRef->mNameNode);
}
void BfPrinter::Visit(BfDelegateTypeRef* typeRef)
{
Visit((BfAstNode*)typeRef);
VisitChild(typeRef->mTypeToken);
ExpectSpace();
VisitChild(typeRef->mAttributes);
2021-12-27 12:55:14 -05:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(typeRef->mReturnType);
VisitChild(typeRef->mOpenParen);
for (int i = 0; i < (int)typeRef->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(typeRef->mCommas.GetSafe(i - 1));
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(typeRef->mParams[i]);
}
2019-08-23 11:56:54 -07:00
VisitChild(typeRef->mCloseParen);
}
void BfPrinter::Visit(BfPointerTypeRef* ptrType)
{
Visit((BfAstNode*)ptrType);
2019-08-23 11:56:54 -07:00
VisitChild(ptrType->mElementType);
VisitChild(ptrType->mStarNode);
}
void BfPrinter::Visit(BfNullableTypeRef* ptrType)
{
Visit((BfAstNode*) ptrType);
VisitChild(ptrType->mElementType);
VisitChild(ptrType->mQuestionToken);
}
void BfPrinter::Visit(BfVariableDeclaration* varDecl)
{
//Visit(varDecl->ToBase());
VisitChild(varDecl->mAttributes);
2019-08-23 11:56:54 -07:00
VisitChildWithProceedingSpace(varDecl->mModSpecifier);
if (varDecl->mPrecedingComma != NULL)
{
mNextStateModify.mWantNewLineIdx--;
VisitChild(varDecl->mPrecedingComma);
}
2023-04-18 08:41:49 -07:00
else if (varDecl->mTypeRef != NULL)
{
if (varDecl->mTypeRef->mSrcStart >= varDecl->mSrcStart)
{
VisitChild(varDecl->mTypeRef);
}
else
{
// May be from a `for (int k = 1, m = 0; k <= 20; k++)`
}
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChildWithPrecedingSpace(varDecl->mNameNode);
VisitChildWithPrecedingSpace(varDecl->mEqualsNode);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (varDecl->mInitializer != NULL)
{
if (varDecl->mNameNode != NULL)
ExpectSpace();
VisitChild(varDecl->mInitializer);
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfParameterDeclaration* paramDecl)
{
if (paramDecl->mModToken != NULL)
{
VisitChild(paramDecl->mModToken);
ExpectSpace();
}
Visit(paramDecl->ToBase());
}
void BfPrinter::Visit(BfTypeOfExpression* typeOfExpr)
{
Visit(typeOfExpr->ToBase());
VisitChild(typeOfExpr->mToken);
VisitChild(typeOfExpr->mOpenParen);
VisitChild(typeOfExpr->mTypeRef);
2022-07-26 13:27:03 -04:00
VisitChild(typeOfExpr->mCloseParen);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfSizeOfExpression* sizeOfExpr)
{
Visit(sizeOfExpr->ToBase());
VisitChild(sizeOfExpr->mToken);
VisitChild(sizeOfExpr->mOpenParen);
VisitChild(sizeOfExpr->mTypeRef);
VisitChild(sizeOfExpr->mCloseParen);
}
2021-09-10 14:21:25 -07:00
void BfPrinter::Visit(BfOffsetOfExpression* offsetOfExpr)
{
VisitChild(offsetOfExpr->mToken);
VisitChild(offsetOfExpr->mOpenParen);
2022-07-26 13:27:03 -04:00
VisitChild(offsetOfExpr->mTypeRef);
2021-09-10 14:21:25 -07:00
VisitChild(offsetOfExpr->mCommaToken);
ExpectSpace();
VisitChild(offsetOfExpr->mMemberName);
VisitChild(offsetOfExpr->mCloseParen);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfDefaultExpression* defaultExpr)
{
Visit(defaultExpr->ToBase());
VisitChild(defaultExpr->mDefaultToken);
VisitChild(defaultExpr->mOpenParen);
VisitChild(defaultExpr->mTypeRef);
VisitChild(defaultExpr->mCloseParen);
}
void BfPrinter::Visit(BfIsConstExpression* isConstExpr)
{
Visit(isConstExpr->ToBase());
VisitChild(isConstExpr->mIsConstToken);
VisitChild(isConstExpr->mOpenParen);
VisitChild(isConstExpr->mExpression);
VisitChild(isConstExpr->mCloseParen);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfCheckTypeExpression* checkTypeExpr)
{
Visit(checkTypeExpr->ToBase());
VisitChild(checkTypeExpr->mTarget);
ExpectSpace();
VisitChild(checkTypeExpr->mIsToken);
ExpectSpace();
VisitChild(checkTypeExpr->mTypeRef);
}
void BfPrinter::Visit(BfDynamicCastExpression* dynCastExpr)
{
Visit(dynCastExpr->ToBase());
VisitChild(dynCastExpr->mTarget);
ExpectSpace();
VisitChild(dynCastExpr->mAsToken);
ExpectSpace();
VisitChild(dynCastExpr->mTypeRef);
}
void BfPrinter::Visit(BfCastExpression* castExpr)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
Visit((BfAstNode*)castExpr);
VisitChild(castExpr->mOpenParen);
VisitChild(castExpr->mTypeRef);
VisitChild(castExpr->mCloseParen);
bool surroundWithParen = false;
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (surroundWithParen)
Write("(");
VisitChild(castExpr->mExpression);
if (surroundWithParen)
Write(")");
}
void BfPrinter::Visit(BfDelegateBindExpression* bindExpr)
{
Visit(bindExpr->ToBase());
VisitChild(bindExpr->mNewToken);
ExpectSpace();
VisitChild(bindExpr->mFatArrowToken);
ExpectSpace();
VisitChild(bindExpr->mTarget);
VisitChild(bindExpr->mGenericArgs);
}
void BfPrinter::Visit(BfLambdaBindExpression* lambdaBindExpr)
{
Visit(lambdaBindExpr->ToBase());
if (lambdaBindExpr->mNewToken != NULL)
{
VisitChild(lambdaBindExpr->mNewToken);
ExpectSpace();
}
2019-08-23 11:56:54 -07:00
VisitChild(lambdaBindExpr->mOpenParen);
for (int i = 0; i < (int)lambdaBindExpr->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(lambdaBindExpr->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(lambdaBindExpr->mParams[i]);
2019-08-23 11:56:54 -07:00
}
VisitChild(lambdaBindExpr->mCloseParen);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(lambdaBindExpr->mFatArrowToken);
2019-08-23 11:56:54 -07:00
if (lambdaBindExpr->mBody != NULL)
{
if (lambdaBindExpr->mBody->IsA<BfBlock>())
{
ExpectNewLine();
ExpectIndent();
2022-07-26 13:27:03 -04:00
VisitChild(lambdaBindExpr->mBody);
ExpectUnindent();
2019-08-23 11:56:54 -07:00
}
else
{
ExpectSpace();
VisitChild(lambdaBindExpr->mBody);
2019-08-23 11:56:54 -07:00
}
}
VisitChild(lambdaBindExpr->mDtor);
mNextStateModify.mExpectingSpace = false;
mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx;
mCurIndentLevel = mNextStateModify.mWantVirtualIndent;
mVirtualIndentLevel = mNextStateModify.mWantVirtualIndent;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfObjectCreateExpression* newExpr)
{
Visit(newExpr->ToBase());
VisitChild(newExpr->mNewNode);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(newExpr->mTypeRef);
2024-11-06 07:31:55 -05:00
VisitChild(newExpr->mCtorExplicit);
2019-08-23 11:56:54 -07:00
2020-05-28 08:47:09 -07:00
if (newExpr->mStarToken != NULL)
{
VisitChild(newExpr->mStarToken);
ExpectSpace();
}
auto _WriteToken = [&](BfAstNode* node, BfToken token)
{
if (node == NULL)
return;
2020-10-11 07:59:03 -07:00
Visit((BfAstNode*)node);
Write(node, node->GetSrcStart(), 0);
Write(BfTokenToString(token));
};
_WriteToken(newExpr->mOpenToken, BfToken_LParen);
2019-08-23 11:56:54 -07:00
for (int i = 0; i < (int)newExpr->mArguments.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(newExpr->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(newExpr->mArguments[i]);
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
_WriteToken(newExpr->mCloseToken, BfToken_RParen);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfBoxExpression* boxExpr)
{
Visit(boxExpr->ToBase());
VisitChild(boxExpr->mAllocNode);
ExpectSpace();
VisitChild(boxExpr->mBoxToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(boxExpr->mExpression);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfThrowStatement* throwStmt)
{
Visit(throwStmt->ToBase());
VisitChild(throwStmt->mThrowToken);
ExpectSpace();
VisitChild(throwStmt->mExpression);
VisitChild(throwStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfDeleteStatement* deleteStmt)
{
Visit(deleteStmt->ToBase());
VisitChild(deleteStmt->mDeleteToken);
VisitChild(deleteStmt->mTargetTypeToken);
VisitChild(deleteStmt->mAllocExpr);
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(deleteStmt->mExpression);
VisitChild(deleteStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfInvocationExpression* invocationExpr)
{
Visit(invocationExpr->ToBase());
VisitChild(invocationExpr->mTarget);
VisitChild(invocationExpr->mGenericArgs);
VisitChild(invocationExpr->mOpenParen);
for (int i = 0; i < (int) invocationExpr->mArguments.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(invocationExpr->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(invocationExpr->mArguments[i]);
}
VisitChild(invocationExpr->mCloseParen);
}
void BfPrinter::Visit(BfDeferStatement* deferStmt)
{
Visit(deferStmt->ToBase());
VisitChild(deferStmt->mDeferToken);
VisitChild(deferStmt->mColonToken);
2021-02-25 10:14:22 -08:00
VisitChild(deferStmt->mScopeName);
2019-08-23 11:56:54 -07:00
if (deferStmt->mBind != NULL)
{
auto bind = deferStmt->mBind;
2022-07-26 13:27:03 -04:00
VisitChild(bind->mOpenBracket);
2019-08-23 11:56:54 -07:00
for (int i = 0; i < bind->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(bind->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(bind->mParams[i]);
}
VisitChild(bind->mCloseBracket);
}
VisitChild(deferStmt->mOpenParen);
VisitChild(deferStmt->mScopeToken);
2022-07-26 13:27:03 -04:00
VisitChild(deferStmt->mCloseParen);
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(deferStmt->mTargetNode);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChild(deferStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfEnumCaseBindExpression* caseBindExpr)
{
Visit(caseBindExpr->ToBase());
VisitChild(caseBindExpr->mBindToken);
VisitChild(caseBindExpr->mEnumMemberExpr);
VisitChild(caseBindExpr->mBindNames);
}
void BfPrinter::Visit(BfCaseExpression* caseExpr)
{
Visit(caseExpr->ToBase());
if ((caseExpr->mValueExpression == NULL) || (caseExpr->mCaseToken->GetSrcStart() < caseExpr->mValueExpression->GetSrcStart()))
{
// Old version
VisitChild(caseExpr->mCaseToken);
ExpectSpace();
VisitChild(caseExpr->mCaseExpression);
ExpectSpace();
VisitChild(caseExpr->mEqualsNode);
ExpectSpace();
VisitChild(caseExpr->mValueExpression);
}
else
{
2022-07-26 13:27:03 -04:00
VisitChild(caseExpr->mValueExpression);
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(caseExpr->mCaseToken);
2019-08-23 11:56:54 -07:00
BF_ASSERT(caseExpr->mEqualsNode == NULL);
ExpectSpace();
VisitChild(caseExpr->mCaseExpression);
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfSwitchCase* switchCase)
{
2022-05-16 11:01:30 -07:00
if (mIndentCaseLabels)
ExpectIndent();
2022-07-26 13:27:03 -04:00
VisitChild(switchCase->mCaseToken);
2019-08-23 11:56:54 -07:00
for (int caseIdx = 0; caseIdx < (int) switchCase->mCaseExpressions.size(); caseIdx++)
{
if ((caseIdx == 0) || (caseIdx > (int)switchCase->mCaseCommas.size()))
ExpectSpace();
else
2020-09-06 05:28:19 -07:00
VisitChildNoRef(switchCase->mCaseCommas.GetSafe(caseIdx - 1));
2019-08-23 11:56:54 -07:00
VisitChild(switchCase->mCaseExpressions[caseIdx]);
}
VisitChild(switchCase->mColonToken);
ExpectNewLine();
ExpectIndent();
VisitChild(switchCase->mCodeBlock);
ExpectUnindent();
if (switchCase->mEndingToken != NULL)
{
ExpectNewLine();
VisitChild(switchCase->mEndingToken);
VisitChild(switchCase->mEndingSemicolonToken);
ExpectNewLine();
}
2022-05-16 11:01:30 -07:00
if (mIndentCaseLabels)
ExpectUnindent();
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfWhenExpression* whenExpr)
{
VisitChild(whenExpr->mWhenToken);
ExpectSpace();
VisitChild(whenExpr->mExpression);
}
void BfPrinter::Visit(BfSwitchStatement* switchStmt)
{
Visit(switchStmt->ToBase());
VisitChild(switchStmt->mSwitchToken);
ExpectSpace();
VisitChild(switchStmt->mOpenParen);
VisitChild(switchStmt->mSwitchValue);
VisitChild(switchStmt->mCloseParen);
ExpectNewLine();
VisitChild(switchStmt->mOpenBrace);
2022-07-26 13:27:03 -04:00
ExpectNewLine();
2019-08-23 11:56:54 -07:00
for (auto switchCase : switchStmt->mSwitchCases)
Visit(switchCase);
if (switchStmt->mDefaultCase != NULL)
Visit(switchStmt->mDefaultCase);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
ExpectNewLine();
VisitChild(switchStmt->mCloseBrace);
VisitChild(switchStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfTryStatement* tryStmt)
{
Visit(tryStmt->ToBase());
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChild(tryStmt->mTryToken);
VisitChild(tryStmt->mStatement);
}
void BfPrinter::Visit(BfCatchStatement* catchStmt)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
Visit(catchStmt->ToBase());
WriteSourceString(catchStmt);
VisitChild(catchStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfFinallyStatement* finallyStmt)
{
Visit(finallyStmt->ToBase());
VisitChild(finallyStmt->mFinallyToken);
VisitChild(finallyStmt->mStatement);
}
void BfPrinter::Visit(BfCheckedStatement* checkedStmt)
{
Visit(checkedStmt->ToBase());
VisitChild(checkedStmt->mCheckedToken);
VisitChild(checkedStmt->mStatement);
}
void BfPrinter::Visit(BfUncheckedStatement* uncheckedStmt)
{
Visit(uncheckedStmt->ToBase());
VisitChild(uncheckedStmt->mUncheckedToken);
VisitChild(uncheckedStmt->mStatement);
}
void BfPrinter::Visit(BfIfStatement* ifStmt)
{
Visit(ifStmt->ToBase());
VisitChild(ifStmt->mIfToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(ifStmt->mOpenParen);
2019-08-23 11:56:54 -07:00
VisitChild(ifStmt->mCondition);
VisitChild(ifStmt->mCloseParen);
2022-07-26 13:27:03 -04:00
ExpectSpace();
VisitChildNextLine(ifStmt->mTrueStatement);
VisitChild(ifStmt->mElseToken);
2019-08-23 11:56:54 -07:00
if (ifStmt->mFalseStatement != NULL)
{
ExpectSpace();
if (ifStmt->mFalseStatement->IsA<BfIfStatement>())
VisitChild(ifStmt->mFalseStatement);
else
VisitChildNextLine(ifStmt->mFalseStatement);
}
VisitChild(ifStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfReturnStatement* returnStmt)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
Visit(returnStmt->ToBase());
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChild(returnStmt->mReturnToken);
if (returnStmt->mExpression != NULL)
{
ExpectSpace();
VisitChild(returnStmt->mExpression);
}
VisitChild(returnStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfUsingStatement* doStmt)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
Visit(doStmt->ToBase());
VisitChild(doStmt->mUsingToken);
ExpectSpace();
VisitChild(doStmt->mOpenParen);
VisitChild(doStmt->mVariableDeclaration);
VisitChild(doStmt->mCloseParen);
VisitChildNextLine(doStmt->mEmbeddedStatement);
VisitChild(doStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfDoStatement* doStmt)
{
Visit(doStmt->ToBase());
VisitChild(doStmt->mDoToken);
2022-07-26 13:27:03 -04:00
VisitChildNextLine(doStmt->mEmbeddedStatement);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfRepeatStatement* repeatStmt)
{
Visit(repeatStmt->ToBase());
2022-07-26 13:27:03 -04:00
VisitChild(repeatStmt->mRepeatToken);
2019-08-23 11:56:54 -07:00
VisitChildNextLine(repeatStmt->mEmbeddedStatement);
VisitChild(repeatStmt->mWhileToken);
ExpectSpace();
VisitChild(repeatStmt->mOpenParen);
VisitChild(repeatStmt->mCondition);
2022-07-26 13:27:03 -04:00
VisitChild(repeatStmt->mCloseParen);
2019-08-23 11:56:54 -07:00
VisitChild(repeatStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfWhileStatement* whileStmt)
{
Visit(whileStmt->ToBase());
2022-07-26 13:27:03 -04:00
VisitChild(whileStmt->mWhileToken);
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(whileStmt->mOpenParen);
VisitChild(whileStmt->mCondition);
VisitChild(whileStmt->mCloseParen);
VisitChildNextLine(whileStmt->mEmbeddedStatement);
VisitChild(whileStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfBreakStatement* breakStmt)
{
Visit(breakStmt->ToBase());
VisitChild(breakStmt->mBreakNode);
if (breakStmt->mLabel != NULL)
{
ExpectSpace();
VisitChild(breakStmt->mLabel);
}
2022-07-26 13:27:03 -04:00
VisitChild(breakStmt->mTrailingSemicolon);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfContinueStatement* continueStmt)
{
Visit(continueStmt->ToBase());
VisitChild(continueStmt->mContinueNode);
if (continueStmt->mLabel != NULL)
{
ExpectSpace();
VisitChild(continueStmt->mLabel);
}
VisitChild(continueStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfFallthroughStatement* fallthroughStmt)
{
Visit(fallthroughStmt->ToBase());
VisitChild(fallthroughStmt->mFallthroughToken);
2023-12-16 07:38:27 -05:00
if (fallthroughStmt->mLabel != NULL)
{
ExpectSpace();
VisitChild(fallthroughStmt->mLabel);
}
2019-08-23 11:56:54 -07:00
VisitChild(fallthroughStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfForStatement* forStmt)
{
Visit(forStmt->ToBase());
VisitChild(forStmt->mForToken);
ExpectSpace();
VisitChild(forStmt->mOpenParen);
for (int i = 0; i < (int) forStmt->mInitializers.size(); i++)
{
if (i > 0)
2020-09-06 05:28:19 -07:00
VisitChildNoRef(forStmt->mInitializerCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
VisitChild(forStmt->mInitializers[i]);
}
VisitChild(forStmt->mInitializerSemicolon);
ExpectSpace();
VisitChild(forStmt->mCondition);
VisitChild(forStmt->mConditionSemicolon);
ExpectSpace();
for (int i = 0; i < (int) forStmt->mIterators.size(); i++)
{
if (i > 0)
2020-09-06 05:28:19 -07:00
VisitChildNoRef(forStmt->mIteratorCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
VisitChild(forStmt->mIterators[i]);
}
VisitChild(forStmt->mCloseParen);
VisitChildNextLine(forStmt->mEmbeddedStatement);
}
void BfPrinter::Visit(BfForEachStatement* forEachStmt)
{
2022-07-26 13:27:03 -04:00
Visit(forEachStmt->ToBase());
2019-08-23 11:56:54 -07:00
VisitChild(forEachStmt->mForToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(forEachStmt->mOpenParen);
2019-08-23 11:56:54 -07:00
if (forEachStmt->mReadOnlyToken != NULL)
{
VisitChild(forEachStmt->mReadOnlyToken);
ExpectSpace();
}
VisitChild(forEachStmt->mVariableTypeRef);
ExpectSpace();
VisitChild(forEachStmt->mVariableName);
ExpectSpace();
VisitChild(forEachStmt->mInToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(forEachStmt->mCollectionExpression);
2019-08-23 11:56:54 -07:00
VisitChild(forEachStmt->mCloseParen);
ExpectNewLine();
VisitChildNextLine(forEachStmt->mEmbeddedStatement);
VisitChild(forEachStmt->mTrailingSemicolon);
}
void BfPrinter::Visit(BfConditionalExpression* condExpr)
{
Visit(condExpr->ToBase());
VisitChild(condExpr->mConditionExpression);
ExpectSpace();
VisitChild(condExpr->mQuestionToken);
ExpectSpace();
VisitChild(condExpr->mTrueExpression);
ExpectSpace();
VisitChild(condExpr->mColonToken);
ExpectSpace();
VisitChild(condExpr->mFalseExpression);
}
void BfPrinter::Visit(BfAssignmentExpression* assignExpr)
{
Visit(assignExpr->ToBase());
VisitChild(assignExpr->mLeft);
ExpectSpace();
VisitChild(assignExpr->mOpToken);
ExpectSpace();
VisitChild(assignExpr->mRight);
}
void BfPrinter::Visit(BfParenthesizedExpression* parenExpr)
{
Visit(parenExpr->ToBase());
2022-07-26 13:27:03 -04:00
VisitChild(parenExpr->mOpenParen);
VisitChild(parenExpr->mExpression);
2019-08-23 11:56:54 -07:00
VisitChild(parenExpr->mCloseParen);
}
void BfPrinter::Visit(BfTupleExpression* tupleExpr)
{
Visit(tupleExpr->ToBase());
VisitChild(tupleExpr->mOpenParen);
for (int i = 0; i < (int)tupleExpr->mValues.size(); i++)
{
if (i > 0)
{
VisitChildNoRef(tupleExpr->mCommas.GetSafe(i - 1));
ExpectSpace();
}
2019-08-23 11:56:54 -07:00
if (i < (int)tupleExpr->mNames.size())
{
auto nameNode = tupleExpr->mNames[i];
if (nameNode != NULL)
{
VisitChild(nameNode->mNameNode);
VisitChild(nameNode->mColonToken);
ExpectSpace();
}
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
VisitChild(tupleExpr->mValues[i]);
}
VisitChild(tupleExpr->mCloseParen);
}
void BfPrinter::Visit(BfMemberReferenceExpression* memberRefExpr)
{
Visit(memberRefExpr->ToBase());
VisitChild(memberRefExpr->mTarget);
VisitChild(memberRefExpr->mDotToken);
VisitChild(memberRefExpr->mMemberName);
}
void BfPrinter::Visit(BfIndexerExpression* indexerExpr)
{
Visit(indexerExpr->ToBase());
VisitChild(indexerExpr->mTarget);
VisitChild(indexerExpr->mOpenBracket);
for (int i = 0; i < (int)indexerExpr->mArguments.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(indexerExpr->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
2022-07-26 13:27:03 -04:00
VisitChild(indexerExpr->mArguments[i]);
2019-08-23 11:56:54 -07:00
}
VisitChild(indexerExpr->mCloseBracket);
}
void BfPrinter::Visit(BfUnaryOperatorExpression* unaryOpExpr)
{
Visit(unaryOpExpr->ToBase());
bool postOp = (unaryOpExpr->mOp == BfUnaryOp_PostIncrement) || (unaryOpExpr->mOp == BfUnaryOp_PostDecrement) || (unaryOpExpr->mOp == BfUnaryOp_PartialRangeFrom);
2019-08-23 11:56:54 -07:00
if (!postOp)
VisitChild(unaryOpExpr->mOpToken);
if ((unaryOpExpr->mOp == BfUnaryOp_Ref) || (unaryOpExpr->mOp == BfUnaryOp_Mut) || (unaryOpExpr->mOp == BfUnaryOp_Out) || (unaryOpExpr->mOp == BfUnaryOp_Params) || (unaryOpExpr->mOp == BfUnaryOp_Cascade))
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(unaryOpExpr->mExpression);
if (postOp)
VisitChild(unaryOpExpr->mOpToken);
}
void BfPrinter::Visit(BfBinaryOperatorExpression* binOpExpr)
{
//Visit(binOpExpr->ToBase());
VisitChild(binOpExpr->mLeft);
ExpectSpace();
VisitChild(binOpExpr->mOpToken);
ExpectSpace();
VisitChild(binOpExpr->mRight);
}
void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration)
{
//Visit((BfAstNode*)ctorDeclaration);
2023-12-31 09:20:12 -05:00
if (!ctorDeclaration->IsA<BfAutoConstructorDeclaration>())
ExpectNewLine();
if (ctorDeclaration->mAttributes != NULL)
{
QueueVisitChild(ctorDeclaration->mAttributes);
ExpectNewLine();
}
2022-07-26 13:27:03 -04:00
QueueVisitChild(ctorDeclaration->mProtectionSpecifier);
2019-08-23 11:56:54 -07:00
ExpectSpace();
QueueVisitChild(ctorDeclaration->mNewSpecifier);
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(ctorDeclaration->mStaticSpecifier);
2019-08-23 11:56:54 -07:00
ExpectSpace();
if (mDocPrep)
{
FlushVisitChild();
Write(" ");
VisitChild(mCurTypeDecl->mNameNode);
}
else
{
QueueVisitChild(ctorDeclaration->mThisToken);
2022-07-26 13:27:03 -04:00
}
2024-11-06 07:31:55 -05:00
QueueVisitChild(ctorDeclaration->mGenericParams);
2019-08-23 11:56:54 -07:00
QueueVisitChild(ctorDeclaration->mOpenParen);
for (int i = 0; i < (int) ctorDeclaration->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
QueueVisitChild(ctorDeclaration->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
QueueVisitChild(ctorDeclaration->mParams[i]);
}
QueueVisitChild(ctorDeclaration->mCloseParen);
ExpectSpace();
QueueVisitChild(ctorDeclaration->mInitializerColonToken);
ExpectSpace();
QueueVisitChild(ctorDeclaration->mInitializer);
2024-11-06 07:31:55 -05:00
ExpectSpace();
QueueVisitChild(ctorDeclaration->mGenericConstraintsDeclaration);
2019-08-23 11:56:54 -07:00
2024-01-26 06:07:27 -05:00
if (ctorDeclaration->mFatArrowToken != NULL)
{
ExpectSpace();
QueueVisitChild(ctorDeclaration->mFatArrowToken);
ExpectSpace();
}
2019-08-23 11:56:54 -07:00
QueueVisitChild(ctorDeclaration->mBody);
2024-01-26 06:07:27 -05:00
QueueVisitChild(ctorDeclaration->mEndSemicolon);
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
FlushVisitChild();
}
2022-08-01 10:47:17 -04:00
void BfPrinter::Visit(BfAutoConstructorDeclaration* ctorDeclaration)
{
if (ctorDeclaration->mPrefix != NULL)
{
VisitChild(ctorDeclaration->mPrefix);
ExpectSpace();
}
Visit(ctorDeclaration->ToBase());
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration)
{
//Visit((BfAstNode*)dtorDeclaration);
2019-08-23 11:56:54 -07:00
QueueVisitChild(dtorDeclaration->mAttributes);
ExpectNewLine();
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(dtorDeclaration->mProtectionSpecifier);
2019-08-23 11:56:54 -07:00
ExpectSpace();
QueueVisitChild(dtorDeclaration->mNewSpecifier);
ExpectSpace();
QueueVisitChild(dtorDeclaration->mStaticSpecifier);
ExpectSpace();
QueueVisitChild(dtorDeclaration->mTildeToken);
if (mDocPrep)
{
2022-07-26 13:27:03 -04:00
FlushVisitChild();
2019-08-23 11:56:54 -07:00
VisitChild(mCurTypeDecl->mNameNode);
}
else
{
QueueVisitChild(dtorDeclaration->mThisToken);
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
QueueVisitChild(dtorDeclaration->mOpenParen);
for (int i = 0; i < (int) dtorDeclaration->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
QueueVisitChild(dtorDeclaration->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
QueueVisitChild(dtorDeclaration->mParams[i]);
}
2022-07-26 13:27:03 -04:00
QueueVisitChild(dtorDeclaration->mCloseParen);
2019-08-23 11:56:54 -07:00
QueueVisitChild(dtorDeclaration->mFatArrowToken);
QueueVisitChild(dtorDeclaration->mBody);
FlushVisitChild();
}
void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
if (methodDeclaration->mAttributes != NULL)
{
QueueVisitChild(methodDeclaration->mAttributes);
ExpectNewLine();
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (methodDeclaration->mExternSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mExternSpecifier);
2019-08-23 11:56:54 -07:00
}
if (methodDeclaration->mProtectionSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mProtectionSpecifier);
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (methodDeclaration->mNewSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mNewSpecifier);
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (methodDeclaration->mVirtualSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mVirtualSpecifier);
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (methodDeclaration->mStaticSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
QueueVisitChild(methodDeclaration->mStaticSpecifier);
}
if (methodDeclaration->mReadOnlySpecifier != NULL)
{
ExpectSpace();
QueueVisitChild(methodDeclaration->mReadOnlySpecifier);
2019-08-23 11:56:54 -07:00
}
if (methodDeclaration->mMixinSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mMixinSpecifier);
2019-08-23 11:56:54 -07:00
}
if (methodDeclaration->mPartialSpecifier != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mPartialSpecifier);
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if ((methodDeclaration->mNameNode != NULL) || (methodDeclaration->mExplicitInterface != NULL))
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mExplicitInterface);
2019-08-23 11:56:54 -07:00
QueueVisitChild(methodDeclaration->mExplicitInterfaceDotToken);
QueueVisitChild(methodDeclaration->mNameNode);
2022-07-26 13:27:03 -04:00
if (auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDeclaration))
{
if ((operatorDecl->mOpTypeToken != NULL) && (operatorDecl->mOpTypeToken->mToken == BfToken_LChevron))
ExpectSpace();
}
2019-08-23 11:56:54 -07:00
QueueVisitChild(methodDeclaration->mGenericParams);
if (auto operatorDecl = BfNodeDynCast<BfOperatorDeclaration>(methodDeclaration))
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
QueueVisitChild(operatorDecl->mExplicitToken);
ExpectSpace();
2022-01-17 17:10:37 -05:00
QueueVisitChild(operatorDecl->mOperatorToken);
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(operatorDecl->mOpTypeToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mReturnType);
2019-08-23 11:56:54 -07:00
}
else if (methodDeclaration->mReturnType != NULL)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mReturnType);
2019-08-23 11:56:54 -07:00
}
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
QueueVisitChild(methodDeclaration->mOpenParen);
2020-09-24 09:06:27 -07:00
if (methodDeclaration->mThisToken != NULL)
{
QueueVisitChild(methodDeclaration->mThisToken);
ExpectSpace();
}
2019-08-23 11:56:54 -07:00
for (int i = 0; i < (int) methodDeclaration->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
QueueVisitChild(methodDeclaration->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
QueueVisitChild(methodDeclaration->mParams[i]);
}
QueueVisitChild(methodDeclaration->mCloseParen);
ExpectSpace();
QueueVisitChild(methodDeclaration->mMutSpecifier);
ExpectSpace();
QueueVisitChild(methodDeclaration->mGenericConstraintsDeclaration);
if (methodDeclaration->mFatArrowToken != NULL)
{
ExpectSpace();
QueueVisitChild(methodDeclaration->mFatArrowToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
QueueVisitChild(methodDeclaration->mBody);
2022-07-26 13:27:03 -04:00
QueueVisitChild(methodDeclaration->mEndSemicolon);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfMethodDeclaration* methodDeclaration)
{
//Visit(methodDeclaration->ToBase());
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
ExpectNewLine();
QueueMethodDeclaration(methodDeclaration);
//?? QueueVisitErrorNodes(methodDeclaration);
FlushVisitChild();
ExpectNewLine();
}
void BfPrinter::Visit(BfOperatorDeclaration* opreratorDeclaration)
{
Visit(opreratorDeclaration->ToBase());
}
void BfPrinter::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
ExpectNewLine();
QueueVisitChild(propertyMethodDeclaration->mAttributes);
ExpectNewLine();
QueueVisitChild(propertyMethodDeclaration->mProtectionSpecifier);
2022-07-26 13:27:03 -04:00
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(propertyMethodDeclaration->mNameNode);
ExpectSpace();
2021-11-27 09:05:23 -08:00
QueueVisitChild(propertyMethodDeclaration->mSetRefSpecifier);
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(propertyMethodDeclaration->mMutSpecifier);
ExpectSpace();
2020-05-08 11:11:01 -07:00
QueueVisitChild(propertyMethodDeclaration->mFatArrowToken);
ExpectSpace();
2022-07-26 13:27:03 -04:00
if (auto block = BfNodeDynCast<BfBlock>(propertyMethodDeclaration->mBody))
ExpectNewLine();
2019-08-23 11:56:54 -07:00
QueueVisitChild(propertyMethodDeclaration->mBody);
2020-05-08 11:11:01 -07:00
QueueVisitChild(propertyMethodDeclaration->mEndSemicolon);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfPropertyBodyExpression* propertyBodyExpression)
{
VisitChild(propertyBodyExpression->mMutSpecifier);
ExpectSpace();
VisitChild(propertyBodyExpression->mFatTokenArrow);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration)
2020-09-25 09:17:33 -07:00
{
2019-08-23 11:56:54 -07:00
auto indexerDeclaration = BfNodeDynCast<BfIndexerDeclaration>(propertyDeclaration);
ExpectNewLine();
QueueVisitChild(propertyDeclaration->mAttributes);
2022-07-26 13:27:03 -04:00
ExpectNewLine();
2020-09-14 11:55:18 -07:00
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(propertyDeclaration->mProtectionSpecifier);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mConstSpecifier);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mReadOnlySpecifier);
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(propertyDeclaration->mVolatileSpecifier);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mNewSpecifier);
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(propertyDeclaration->mVirtualSpecifier);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mExternSpecifier);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mStaticSpecifier);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mTypeRef);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mExplicitInterface);
QueueVisitChild(propertyDeclaration->mExplicitInterfaceDotToken);
QueueVisitChild(propertyDeclaration->mNameNode);
ExpectSpace();
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
if (indexerDeclaration != NULL)
{
2021-11-27 10:31:32 -08:00
QueueVisitChild(indexerDeclaration->mThisToken);
QueueVisitChild(indexerDeclaration->mOpenBracket);
2019-08-23 11:56:54 -07:00
for (int i = 0; i < (int)indexerDeclaration->mParams.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
QueueVisitChild(indexerDeclaration->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
QueueVisitChild(indexerDeclaration->mParams[i]);
}
QueueVisitChild(indexerDeclaration->mCloseBracket);
ExpectSpace();
2021-11-27 10:31:32 -08:00
}
2019-08-23 11:56:54 -07:00
2019-09-30 12:24:02 -07:00
if (auto block = BfNodeDynCast<BfBlock>(propertyDeclaration->mDefinitionBlock))
2019-08-23 11:56:54 -07:00
{
BlockState blockState;
DoBlockOpen(NULL, block->mOpenBrace, block->mCloseBrace, true, blockState);
2019-09-30 12:24:02 -07:00
for (auto method : propertyDeclaration->mMethods)
{
Visit(method);
}
FlushVisitChild();
DoBlockClose(NULL, block->mOpenBrace, block->mCloseBrace, true, blockState);
2019-09-30 12:24:02 -07:00
}
else
{
2020-09-14 11:55:18 -07:00
ExpectSpace();
2019-09-30 12:24:02 -07:00
QueueVisitChild(propertyDeclaration->mDefinitionBlock);
ExpectSpace();
for (auto method : propertyDeclaration->mMethods)
{
QueueVisitChild(method->mBody);
}
2019-08-23 11:56:54 -07:00
}
2021-11-27 10:31:32 -08:00
ExpectSpace();
QueueVisitChild(propertyDeclaration->mEqualsNode);
ExpectSpace();
QueueVisitChild(propertyDeclaration->mInitializer);
2021-12-07 10:33:43 -08:00
ExpectSpace();
QueueVisitChild(propertyDeclaration->mFieldDtor);
2021-11-27 10:31:32 -08:00
FlushVisitChild();
2019-08-23 11:56:54 -07:00
//QueueVisitChild(propertyDeclaration->mTrailingSemicolon);
// ??? QueueVisitErrorNodes(propertyDeclaration);
FlushVisitChild();
}
2020-09-25 09:17:33 -07:00
void BfPrinter::Visit(BfIndexerDeclaration* indexerDeclaration)
{
Visit((BfPropertyDeclaration*)indexerDeclaration);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfFieldDeclaration* fieldDeclaration)
{
2020-02-06 16:45:53 -08:00
bool isEnumDecl = false;
if (auto enumEntry = BfNodeDynCast<BfEnumEntryDeclaration>(fieldDeclaration))
2022-07-26 13:27:03 -04:00
{
2020-02-06 16:45:53 -08:00
isEnumDecl = true;
}
2022-07-26 13:27:03 -04:00
if (fieldDeclaration->mPrecedingComma != NULL)
{
mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx;
2020-02-06 16:45:53 -08:00
QueueVisitChild(fieldDeclaration->mPrecedingComma);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mNameNode);
}
else
2019-08-23 11:56:54 -07:00
{
if (!isEnumDecl)
ExpectNewLine();
if (fieldDeclaration->mAttributes != NULL)
{
QueueVisitChild(fieldDeclaration->mAttributes);
ExpectNewLine();
}
ExpectSpace();
QueueVisitChild(fieldDeclaration->mProtectionSpecifier);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mConstSpecifier);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mReadOnlySpecifier);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mVolatileSpecifier);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mNewSpecifier);
ExpectSpace();
2021-01-02 08:16:51 -08:00
QueueVisitChild(fieldDeclaration->mExternSpecifier);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mStaticSpecifier);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mPrecedingComma);
ExpectSpace();
if (isEnumDecl)
mNextStateModify.mExpectingSpace = false;
QueueVisitChild(fieldDeclaration->mTypeRef);
ExpectSpace();
QueueVisitChild(fieldDeclaration->mNameNode);
}
2020-02-06 16:45:53 -08:00
if (fieldDeclaration->mEqualsNode != NULL)
{
ExpectSpace();
QueueVisitChild(fieldDeclaration->mEqualsNode);
}
if (fieldDeclaration->mInitializer != NULL)
{
ExpectSpace();
QueueVisitChild(fieldDeclaration->mInitializer);
}
2019-08-23 11:56:54 -07:00
mNextStateModify.mExpectingSpace = false;
FlushVisitChild();
VisitChild(fieldDeclaration->mFieldDtor);
mNextStateModify.mExpectingSpace = false;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfEnumCaseDeclaration* enumCaseDeclaration)
{
2020-02-06 16:45:53 -08:00
ExpectNewLine();
2022-07-26 13:27:03 -04:00
Visit(enumCaseDeclaration->ToBase());
2019-08-23 11:56:54 -07:00
if (mDocPrep)
{
for (int i = 0; i < (int)enumCaseDeclaration->mEntries.size(); i++)
{
auto fieldDecl = enumCaseDeclaration->mEntries[i];
Visit((BfAstNode*)fieldDecl);
Write("public static ");
Visit(mCurTypeDecl->mNameNode);
Write(" ");
VisitChild(fieldDecl);
Write(";");
}
return;
}
VisitChild(enumCaseDeclaration->mCaseToken);
2022-07-26 13:27:03 -04:00
ExpectSpace();
2019-08-23 11:56:54 -07:00
for (int i = 0; i < (int)enumCaseDeclaration->mEntries.size(); i++)
{
if (i > 0)
{
2020-09-06 05:28:19 -07:00
VisitChildNoRef(enumCaseDeclaration->mCommas.GetSafe(i - 1));
2019-08-23 11:56:54 -07:00
ExpectSpace();
}
VisitChild(enumCaseDeclaration->mEntries[i]);
}
}
void BfPrinter::Visit(BfTypeAliasDeclaration* typeDeclaration)
{
Visit(typeDeclaration->ToBase());
ExpectSpace();
VisitChild(typeDeclaration->mEqualsToken);
ExpectSpace();
VisitChild(typeDeclaration->mAliasToType);
VisitChild(typeDeclaration->mEndSemicolon);
}
void BfPrinter::Visit(BfFieldDtorDeclaration* fieldDtorDeclaration)
2022-07-26 13:27:03 -04:00
{
ExpectSpace();
if (fieldDtorDeclaration->mBody != NULL)
{
if (fieldDtorDeclaration->mBody->IsA<BfBlock>())
{
ExpectNewLine();
ExpectIndent();
VisitChild(fieldDtorDeclaration->mTildeToken);
VisitChild(fieldDtorDeclaration->mBody);
ExpectUnindent();
}
else
{
VisitChild(fieldDtorDeclaration->mTildeToken);
ExpectSpace();
VisitChild(fieldDtorDeclaration->mBody);
}
}
else
VisitChild(fieldDtorDeclaration->mTildeToken);
VisitChild(fieldDtorDeclaration->mNextFieldDtor);
}
2019-08-23 11:56:54 -07:00
void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration)
{
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDeclaration);
//Visit(typeDeclaration->ToBase());
bool isOneLine = true;
const char* src = typeDeclaration->GetSourceData()->mSrc;
for (int i = typeDeclaration->GetSrcStart(); i < typeDeclaration->GetSrcEnd(); i++)
{
if (src[i] == '\n')
{
isOneLine = false;
break;
}
}
2022-07-26 13:27:03 -04:00
ExpectNewLine();
2019-08-23 11:56:54 -07:00
QueueVisitChild(typeDeclaration->mAttributes);
if (!isOneLine)
2022-07-26 13:27:03 -04:00
ExpectNewLine();
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(typeDeclaration->mAbstractSpecifier);
ExpectSpace();
QueueVisitChild(typeDeclaration->mSealedSpecifier);
2022-07-26 13:27:03 -04:00
ExpectSpace();
2019-08-23 11:56:54 -07:00
QueueVisitChild(typeDeclaration->mProtectionSpecifier);
ExpectSpace();
QueueVisitChild(typeDeclaration->mStaticSpecifier);
ExpectSpace();
QueueVisitChild(typeDeclaration->mPartialSpecifier);
ExpectSpace();
bool isEnumDoc = false;
if ((mDocPrep) && (typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mTypeNode->mToken == BfToken_Enum))
{
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
if (auto enumEntryDecl = BfNodeDynCast<BfEnumEntryDeclaration>(defineBlock->GetFirst()))
{
}
else
{
isEnumDoc = true;
}
2022-07-26 13:27:03 -04:00
}
2019-08-23 11:56:54 -07:00
}
if (isEnumDoc)
{
FlushVisitChild();
Write(" struct");
}
else
QueueVisitChild(typeDeclaration->mTypeNode);
bool queueChildren = (typeDeclaration->mTypeNode != NULL) &&
((typeDeclaration->mTypeNode->mToken == BfToken_Delegate) || (typeDeclaration->mTypeNode->mToken == BfToken_Function));
ExpectSpace();
QueueVisitChild(typeDeclaration->mNameNode);
QueueVisitChild(typeDeclaration->mGenericParams);
2023-12-31 09:20:12 -05:00
2019-08-23 11:56:54 -07:00
if (typeDeclaration->mColonToken != NULL)
{
ExpectSpace();
QueueVisitChild(typeDeclaration->mColonToken);
2023-12-31 09:20:12 -05:00
}
if (typeDeclaration->mAutoCtor != NULL)
{
ExpectSpace();
QueueVisitChild(typeDeclaration->mAutoCtor);
}
if (typeDeclaration->mColonToken != NULL)
{
int nextCommaIdx = -1;
if (typeDeclaration->mAutoCtor != NULL)
nextCommaIdx++;
2019-08-23 11:56:54 -07:00
for (int i = 0; i < (int)typeDeclaration->mBaseClasses.size(); i++)
{
ExpectSpace();
QueueVisitChild(typeDeclaration->mBaseClasses[i]);
2023-12-31 09:20:12 -05:00
if (nextCommaIdx >= 0)
QueueVisitChild(typeDeclaration->mBaseClassCommas.GetSafe(nextCommaIdx));
2024-01-24 06:16:42 -05:00
nextCommaIdx++;
2019-08-23 11:56:54 -07:00
}
2024-01-24 06:16:42 -05:00
if (nextCommaIdx >= 0)
QueueVisitChild(typeDeclaration->mBaseClassCommas.GetSafe(nextCommaIdx));
2022-07-26 13:27:03 -04:00
ExpectSpace();
2019-08-23 11:56:54 -07:00
}
QueueVisitChild(typeDeclaration->mGenericConstraintsDeclaration);
if (queueChildren)
{
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
for (auto member : defineBlock->mChildArr)
{
SetAndRestoreValue<BfAstNode*> prevBlockMember(mCurBlockMember, member);
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(member))
{
QueueMethodDeclaration(methodDecl);
}
else
BF_FATAL("Error");
}
FlushVisitChild();
}
else
{
FlushVisitChild();
VisitChild(typeDeclaration->mDefineNode);
}
}
else
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
FlushVisitChild();
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
{
if (!isOneLine)
{
ExpectNewLine();
mNextStateModify.mDoingBlockOpen = true;
}
else
ExpectSpace();
VisitChild(defineBlock->mOpenBrace);
ExpectIndent();
for (auto member : defineBlock->mChildArr)
{
SetAndRestoreValue<BfAstNode*> prevBlockMember(mCurBlockMember, member);
2020-02-06 16:45:53 -08:00
if (auto fieldDecl = BfNodeDynCast<BfFieldDeclaration>(member))
ExpectNewLine();
else if (auto tokenNode = BfNodeDynCast<BfTokenNode>(member))
{
mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx;
mNextStateModify.mExpectingSpace = false;
}
2019-08-23 11:56:54 -07:00
VisitChild(member);
}
ExpectUnindent();
2022-07-26 13:27:03 -04:00
VisitChild(defineBlock->mCloseBrace);
}
2019-08-23 11:56:54 -07:00
else
{
FlushVisitChild();
VisitChild(typeDeclaration->mDefineNode);
}
2022-07-26 13:27:03 -04:00
}
ExpectNewLine();
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfUsingDirective* usingDirective)
{
//Visit(usingDirective->ToBase());
2022-07-26 13:27:03 -04:00
2019-08-23 11:56:54 -07:00
ExpectNewLine();
2022-07-26 13:27:03 -04:00
VisitChild(usingDirective->mUsingToken);
2019-08-23 11:56:54 -07:00
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(usingDirective->mNamespace);
2019-08-23 11:56:54 -07:00
2022-07-26 13:27:03 -04:00
VisitChild(usingDirective->mTrailingSemicolon);
2019-08-23 11:56:54 -07:00
ExpectNewLine();
}
void BfPrinter::Visit(BfUsingModDirective* usingDirective)
2019-08-23 11:56:54 -07:00
{
ExpectNewLine();
VisitChild(usingDirective->mUsingToken);
ExpectSpace();
VisitChild(usingDirective->mModToken);
2019-08-23 11:56:54 -07:00
ExpectSpace();
VisitChild(usingDirective->mTypeRef);
VisitChild(usingDirective->mTrailingSemicolon);
ExpectNewLine();
}
void BfPrinter::Visit(BfNamespaceDeclaration* namespaceDeclaration)
{
//Visit(namespaceDeclaration->ToBase());
ExpectNewLine();
VisitChild(namespaceDeclaration->mNamespaceNode);
ExpectSpace();
2022-07-26 13:27:03 -04:00
VisitChild(namespaceDeclaration->mNameNode);
2022-04-17 08:40:25 -07:00
VisitChild(namespaceDeclaration->mBody);
2019-08-23 11:56:54 -07:00
}
void BfPrinter::DoBlockOpen(BfAstNode* prevNode, BfTokenNode* blockOpen, BfTokenNode* blockClose, bool queue, BlockState& blockState)
2022-07-26 13:27:03 -04:00
{
blockState.mLastSpaceOffset = mLastSpaceOffset;
blockState.mIndentStart = mNextStateModify.mWantVirtualIndent;
2020-09-25 09:17:33 -07:00
2019-08-23 11:56:54 -07:00
bool doInlineBlock = true;
if (blockClose != NULL)
2019-08-23 11:56:54 -07:00
{
auto blockSrc = blockOpen->GetSourceData();
int srcEnd = blockClose->GetSrcEnd();
int srcStart = blockOpen->GetSrcStart();
if (prevNode != NULL)
srcStart = prevNode->GetSrcEnd();
for (int i = srcStart; i < srcEnd; i++)
2019-08-23 11:56:54 -07:00
{
if (blockSrc->mSrc[i] == '\n')
doInlineBlock = false;
}
}
if (!doInlineBlock)
{
ExpectNewLine();
mNextStateModify.mDoingBlockOpen = true;
if (prevNode != NULL)
ExpectIndent();
2019-08-23 11:56:54 -07:00
}
else
ExpectSpace();
if (queue)
QueueVisitChild(blockOpen);
2019-08-23 11:56:54 -07:00
else
VisitChild(blockOpen);
2019-08-23 11:56:54 -07:00
if (!doInlineBlock)
ExpectIndent();
else
ExpectSpace();
blockState.mDoInlineBlock = doInlineBlock;
2019-08-23 11:56:54 -07:00
}
void BfPrinter::DoBlockClose(BfAstNode* prevNode, BfTokenNode* blockOpen, BfTokenNode* blockClose, bool queue, BlockState& blockState)
2019-08-23 11:56:54 -07:00
{
if (!blockState.mDoInlineBlock)
2019-08-23 11:56:54 -07:00
{
2022-07-26 13:27:03 -04:00
ExpectUnindent();
2019-08-23 11:56:54 -07:00
mNextStateModify.mDoingBlockClose = true;
}
else
ExpectSpace();
if (queue)
QueueVisitChild(blockClose);
2019-08-23 11:56:54 -07:00
else
VisitChild(blockClose);
2022-07-26 13:27:03 -04:00
if (!blockState.mDoInlineBlock)
{
mNextStateModify.mWantVirtualIndent = blockState.mIndentStart;
mLastSpaceOffset = blockState.mLastSpaceOffset;
}
2019-08-23 11:56:54 -07:00
}
void BfPrinter::Visit(BfBlock* block)
2022-07-26 13:27:03 -04:00
{
BlockState blockState;
SetAndRestoreValue<BlockState*> prevBlockState(mCurBlockState, &blockState);
DoBlockOpen(NULL, block->mOpenBrace, block->mCloseBrace, false, blockState);
2019-08-23 11:56:54 -07:00
for (auto& childNodeRef : *block)
{
BfAstNode* child = childNodeRef;
2022-07-26 13:27:03 -04:00
SetAndRestoreValue<bool> prevForceTrivia(mForceUseTrivia);
SetAndRestoreValue<int> prevVirtualIndent(mNextStateModify.mWantVirtualIndent);
2019-08-23 11:56:54 -07:00
SetAndRestoreValue<BfAstNode*> prevBlockMember(mCurBlockMember, child);
CheckRawNode(child);
2019-08-23 11:56:54 -07:00
child->Accept(this);
}
DoBlockClose(NULL, block->mOpenBrace, block->mCloseBrace, false, blockState);
2019-08-23 11:56:54 -07:00
ExpectNewLine();
}
void BfPrinter::Visit(BfRootNode* rootNode)
2022-07-26 13:27:03 -04:00
{
2019-08-23 11:56:54 -07:00
for (auto child : rootNode->mChildArr)
{
SetAndRestoreValue<BfAstNode*> prevBlockMember(mCurBlockMember, child);
child->Accept(this);
}
// Flush whitespace at the end of the document
2019-08-23 11:56:54 -07:00
BfParserData* bfParser = rootNode->GetSourceData()->ToParserData();
if (bfParser != NULL)
2022-07-26 13:27:03 -04:00
{
2020-06-05 10:24:48 -07:00
BfAstNode* endNode = mSource->mAlloc.Alloc<BfAstNode>();
endNode->Init(rootNode->GetSrcEnd(), bfParser->mSrcLength, bfParser->mSrcLength);
Visit(endNode);
}
2019-08-23 11:56:54 -07:00
if (mCharMapping != NULL)
{
BF_ASSERT(mCharMapping->size() == mOutString.length());
}
}
void BfPrinter::Visit(BfInlineAsmStatement* asmStmt)
{
2022-07-26 13:27:03 -04:00
}