diff --git a/src/babel/babel-generator/buffer.hpp b/src/babel/babel-generator/buffer.hpp index aa86be9..595ffdc 100644 --- a/src/babel/babel-generator/buffer.hpp +++ b/src/babel/babel-generator/buffer.hpp @@ -494,10 +494,10 @@ namespace BabelGenerator::Buffer { } template void _normalizePosition(PTR(Node::Node) node, BASE::position_t columnOffset) { - auto const &pos = node->loc(); + auto const &has_pos = node->has_loc(); auto &target = this->_sourcePosition; - if (pos) { + if (has_pos) { // target.line = pos.line; // TODO: Fix https://github.com/babel/babel/issues/15712 in downstream // target.column = std::max(pos.column + columnOffset, 0); diff --git a/src/babel/babel-generator/generators/classes.hpp b/src/babel/babel-generator/generators/classes.hpp index 828e413..2fceb5f 100644 --- a/src/babel/babel-generator/generators/classes.hpp +++ b/src/babel/babel-generator/generators/classes.hpp @@ -158,8 +158,8 @@ namespace BabelGenerator::Generators { if (!node->isStatic() && !_this.format.preserveFormat) { // catch up to property key, avoid line break // between member TS modifiers and the property key. - // const endLine = node.key.loc?.end?.line; - // if (endLine) _this.catchUp(endLine); + auto endLine = node->key()->locEndLine(-1); + if (endLine >= 0) _this.catchUp(endLine); } classesTsPrintClassMemberModifiers(_this, node); @@ -201,8 +201,8 @@ namespace BabelGenerator::Generators { // catch up to property key, avoid line break // between member modifiers and the property key. - // const endLine = node.key.loc?.end?.line; - // if (endLine) _this.catchUp(endLine); + auto endLine = node->key()->locEndLine(-1); + if (endLine >= 0) _this.catchUp(endLine); // TS does not support class accessor property yet classesTsPrintClassMemberModifiers(_this, node); @@ -284,9 +284,8 @@ namespace BabelGenerator::Generators { if (!_this.format.preserveFormat) { // catch up to method key, avoid line break // between member modifiers/method heads and the method key. - // const endLine = node.key.loc?.end?.line; - // auto const& endLine = node->key->locEnd(); - // if (endLine) _this.catchUp(endLine); + auto endLine = node->key()->locEndLine(-1); + if (endLine >= 0) _this.catchUp(endLine); } classesTsPrintClassMemberModifiers(_this, node); diff --git a/src/babel/babel-generator/generators/typescript.hpp b/src/babel/babel-generator/generators/typescript.hpp index 4e52df3..1bab8a7 100644 --- a/src/babel/babel-generator/generators/typescript.hpp +++ b/src/babel/babel-generator/generators/typescript.hpp @@ -128,7 +128,7 @@ namespace BabelGenerator::Generators { template void maybePrintTrailingCommaOrSemicolon(Printer::Printer &printer, PTR(T) node) { - if (!(printer.tokenMap != nullptr) || !node->position().has_start || !node->position().has_end) { + if (!(printer.tokenMap != nullptr) || !node->position().has_start() || !node->position().has_end()) { printer.semicolon(); return; } diff --git a/src/babel/babel-generator/printer.hpp b/src/babel/babel-generator/printer.hpp index 8fd6932..0476675 100644 --- a/src/babel/babel-generator/printer.hpp +++ b/src/babel/babel-generator/printer.hpp @@ -691,29 +691,29 @@ namespace BabelGenerator::Printer { void _catchUp(PTR(Node::Node) node) { auto const &format = this->format; if (!format.preserveFormat) { - if (format.retainLines && node && node->loc()) { - // this->catchUp(loc[prop].line); + if (format.retainLines && node && node->has_loc()) { + this->catchUp(node->locLine(-1)); } return; } // catch up to this nodes newline if we're behind - auto const &pos = node ? node->loc() : std::nullopt; - if (pos != std::nullopt) - this->_catchUpTo(*pos); + auto const &pos = node ? node->has_loc() : false; + if (pos) + this->_catchUpTo(node->loc()); } void _catchUpTo(BabelParser::Util::Location::Position const &pos) { - // const count = line - this->_buf.getCurrentLine(); - // if (count > 0 && this->_noLineTerminator) { - // // We cannot inject new lines when _noLineTemrinator is set - // // to `true`, or we would generate invalid code. - // return; - // } + auto count = pos.line() - this->_buf.getCurrentLine(); + if (count > 0 && this->_noLineTerminator) { + // We cannot inject new lines when _noLineTemrinator is set + // to `true`, or we would generate invalid code. + return; + } - // for (let i = 0; i < count; i++) { - // this->_newline(); - // } + for (size_t i = 0; i < count; i++) { + this->_newline(); + } // const spacesCount = // count > 0 ? column : column - this->_buf.getCurrentColumn(); @@ -786,8 +786,7 @@ namespace BabelGenerator::Printer { // } auto oldInAux = this->_insideAux; - // this->_insideAux = node.loc == null; - this->_insideAux = false; + this->_insideAux = node->position().has_start() == false; this->_maybeAddAuxComment(this->_insideAux && !oldInAux); bool parenthesized = node->extra().parenthesized; @@ -819,21 +818,22 @@ namespace BabelGenerator::Printer { } bool indentParenthesized = false; - // if ( - // !shouldPrintParens && - // this->_noLineTerminator && - // (node.leadingComments?.some(commentIsNewline) || - // (this->format.retainLines && - // node.loc && - // node.loc.start.line > this->_buf.getCurrentLine())) - // ) { - // shouldPrintParens = true; - // indentParenthesized = true; - // } + if ( + !shouldPrintParens && + this->_noLineTerminator && + ( + // node.leadingComments?.some(commentIsNewline) || + (this->format.retainLines && + node->position().has_start() && + node->locStartLine(-1) > this->_buf.getCurrentLine())) + ) { + shouldPrintParens = true; + indentParenthesized = true; + } PTR(Node::Node) oldNoLineTerminatorAfterNode = nullptr; bool oldInForStatementInitWasTrue = false; - // if (!shouldPrintParens) { + if (!shouldPrintParens) { // noLineTerminatorAfter ||= // parent && // this->_noLineTerminatorAfterNode === parent && @@ -846,7 +846,7 @@ namespace BabelGenerator::Printer { // this->_noLineTerminatorAfterNode = node; // } // } - // } + } if (shouldPrintParens) { this->token(u"("); @@ -998,13 +998,12 @@ namespace BabelGenerator::Printer { if (iter_begin == iter_end) [[unlikely]] return; - bool indent; + bool indent = false; if (OPT.indent == BASE::Undefined && this->format.retainLines) { - // const startLine = nodes->at(0)->locStart()->line; - // if (startLine != null && startLine !== this->_buf.getCurrentLine()) { - // indent = true; - indent = true; - // } + auto position = (*iter_begin)->position(); + if (position.has_start() && position.locStart().line() != this->_buf.getCurrentLine()) { + indent = true; + } } else { indent = toBoolean(OPT.indent); } @@ -1047,7 +1046,7 @@ namespace BabelGenerator::Printer { this->newline(1); } else { auto nextNode = *iter_next; - // newlineOpts.nextNodeStartLine = nextNode.loc?.start.line || 0; + nextNodeStartLine = nextNode->locStartLine(0); this->_printNewline(true, nextNodeStartLine); } @@ -1365,27 +1364,27 @@ namespace BabelGenerator::Printer { ) { // const nodeLoc = node.loc; // const len = comments.length; - bool hasLoc = node->locStart().has_value(); - // const nodeStartLine = hasLoc ? nodeLoc.start.line : 0; - // const nodeEndLine = hasLoc ? nodeLoc.end.line : 0; + bool hasLoc = node->position().has_start(); + auto nodeStartLine = node->locStartLine(0); + auto nodeEndLine = node->locEndLine(0); int64_t lastLine = 0; int64_t leadingCommentNewline = 0; size_t i = 0; for (auto iter = commentsHead; iter != nullptr; iter = iter->next(), i++) { auto &comment = *iter; - if (comment->commentPos != commentPos) [[unlikely]] { - --i; - continue; - } + // if (comment->commentPos != commentPos) [[unlikely]] { + // --i; + // continue; + // } PRINT_COMMENT_HINT::Value shouldPrint = this->_shouldPrintComment(comment /*, nextToken*/); if (shouldPrint == PRINT_COMMENT_HINT::DEFER) { hasLoc = false; break; } if (hasLoc && shouldPrint == PRINT_COMMENT_HINT::ALLOW) { - auto commentStartLine = comment->locStart().line(); - auto commentEndLine = comment->locEnd().line(); + auto commentStartLine = comment->locStartLine(-1); + auto commentEndLine = comment->locEndLine(-1); if constexpr (commentPos == CommentPosition::Leading) { int64_t offset = 0; if (i == 0) { @@ -1404,29 +1403,29 @@ namespace BabelGenerator::Printer { if (comment.next() == nullptr) { this->maybeNewline(leadingCommentNewline); - // maybeNewline( - // Math.max(nodeStartLine - lastLine, leadingCommentNewline), - // ); - // lastLine = nodeStartLine; + maybeNewline( + std::max(nodeStartLine - lastLine, leadingCommentNewline) + ); + lastLine = nodeStartLine; } } else if constexpr (commentPos == CommentPosition::Inner) { - // const offset = - // commentStartLine - (i === 0 ? nodeStartLine : lastLine); + auto offset = + commentStartLine - (i == 0 ? nodeStartLine : lastLine); lastLine = commentEndLine; - // maybeNewline(offset); + maybeNewline(offset); this->_printComment(comment); if (comment.next() == nullptr) { - // maybeNewline(Math.min(1, nodeEndLine - lastLine)); // TODO: Improve here when inner comments processing is stronger - // lastLine = nodeEndLine; + maybeNewline(std::min(1, nodeEndLine - lastLine)); // TODO: Improve here when inner comments processing is stronger + lastLine = nodeEndLine; } } else { - // const offset = - // commentStartLine - (i === 0 ? nodeEndLine - lineOffset : lastLine); + auto offset = + commentStartLine - (i == 0 ? nodeEndLine - lineOffset : lastLine); lastLine = commentEndLine; - // maybeNewline(offset); + maybeNewline(offset); this->_printComment(comment); } } else { @@ -1436,7 +1435,7 @@ namespace BabelGenerator::Printer { } if (commentsHead->next() == nullptr) { - bool singleLine = comment->locStart().line() == comment->locEnd().line(); + bool singleLine = comment->locStartLine(-1) == comment->locEndLine(-1); bool shouldSkipNewline = singleLine && !BabelTypes::isStatement(node) && !BabelTypes::isClassBody(parent) && !BabelTypes::isTSInterfaceBody(parent) && !BabelTypes::isTSEnumMember(node); diff --git a/src/babel/babel-parser/parser/comments.hpp b/src/babel/babel-parser/parser/comments.hpp index 81aff85..0e36e98 100644 --- a/src/babel/babel-parser/parser/comments.hpp +++ b/src/babel/babel-parser/parser/comments.hpp @@ -111,14 +111,14 @@ namespace BabelParser { auto comments = commentWS.comments; if (commentWS.leadingNode != nullptr || commentWS.trailingNode != nullptr) { if (commentWS.leadingNode != nullptr) { - setTrailingComments(commentWS.leadingNode, comments); + setTrailingComments(commentWS.leadingNode->makeComments(this->allocator.node()), comments); } if (commentWS.trailingNode != nullptr) { - setLeadingComments(commentWS.trailingNode, comments); + setLeadingComments(commentWS.trailingNode->makeComments(this->allocator.node()), comments); } } else { /*:: invariant(commentWS.containingNode !== null) */ - auto node = commentWS.containingNode; + auto node = commentWS.containingNode->makeComments(this->allocator.node()); auto commentStart = commentWS.start; if (this->input[this->offsetToSourcePos(commentStart) - 1] == CharCodes::comma) { // If a commentWhitespace follows a comma and the containingNode allows @@ -173,16 +173,16 @@ namespace BabelParser { case Node::Type::ImportDeclaration: adjustInnerComments(node, NODES(NODEAS(node, ImportDeclaration)->specifiers), commentWS); break; - // case "TSEnumDeclaration": - // if (!process.env.BABEL_8_BREAKING) { - // adjustInnerComments(node, node.members, commentWS); - // } else { - // setInnerComments(node, comments); - // } - // break; - // case "TSEnumBody": - // adjustInnerComments(node, node.members, commentWS); - // break; + case Node::Type::TSEnumDeclaration: + if (!BASE::process::env.BABEL_8_BREAKING) { + adjustInnerComments(node, NODES(NODEAS(node, TSEnumDeclaration)->members), commentWS); + } else { + setInnerComments(node, comments); + } + break; + case Node::Type::TSEnumBody: + adjustInnerComments(node, NODES(NODEAS(node, TSEnumBody)->members), commentWS); + break; default: { setInnerComments(node, comments); diff --git a/src/babel/babel-parser/parser/expression.hpp b/src/babel/babel-parser/parser/expression.hpp index d6612c4..d396465 100644 --- a/src/babel/babel-parser/parser/expression.hpp +++ b/src/babel/babel-parser/parser/expression.hpp @@ -119,7 +119,7 @@ namespace BabelParser::ExpressionParser { // Store the first redefinition's position, otherwise ignore because // we are parsing ambiguous pattern if (refExpressionErrors->doubleProtoLoc == std::nullopt) { - refExpressionErrors->doubleProtoLoc = *key->locStart(); + refExpressionErrors->doubleProtoLoc = key->locStart(); } } else [[unlikely]] { this->raise(Errors::DuplicateProto, key); @@ -387,7 +387,7 @@ namespace BabelParser::ExpressionParser { this->raise(Errors::PrivateInExpectedIn, left, value->string()); } - this->classScope->usePrivateName(value, *left->locStart()); + this->classScope->usePrivateName(value, left->locStart()); } auto op = this->state.type; @@ -1318,7 +1318,7 @@ namespace BabelParser::ExpressionParser { // then this method will throw a `PipeTopicUnconfiguredToken` error. PTR(Node::Expression) finishTopicReference(Node::PositionInfo const &startInfo, Proposal::Value pipeProposal, TokenType tokenType) { - if (this->testTopicReferenceConfiguration(pipeProposal, *startInfo.locStart(), tokenType)) { + if (this->testTopicReferenceConfiguration(pipeProposal, startInfo.locStart(), tokenType)) { // The token matches the plugin’s configuration. // The token is therefore a topic reference. @@ -1331,7 +1331,7 @@ namespace BabelParser::ExpressionParser { // Raise recoverable errors. pipeProposal == Proposal::smart ? Errors::PrimaryTopicNotAllowed : // In this case, `pipeProposal === "hack"` is true. Errors::PipeTopicUnbound, - *startInfo.locStart() + startInfo.locStart() ); } // Register the topic reference so that its pipe body knows @@ -2170,7 +2170,7 @@ namespace BabelParser::ExpressionParser { // IdentifierReference // CoverInitializedName // Note: `{ eval } = {}` will be checked in `checkLVal` later. - this->checkReservedWord(NODEAS(prop.key, Identifier)->name, *prop.key->locStart(), true, false); + this->checkReservedWord(NODEAS(prop.key, Identifier)->name, prop.key->locStart(), true, false); if constexpr (TIsPattern) { prop.value = this->parseMaybeDefault(startLoc, NODEAS(this->cloneIdentifier(NODEAS(prop.key, Identifier)), Pattern)); @@ -2440,9 +2440,9 @@ namespace BabelParser::ExpressionParser { // @ts-expect-error key may not index node !!inter.key ? // @ts-expect-error node.key has been guarded - *inter.key->locEnd() + inter.key->locEnd() // : node, - : *inter.position.locEnd() + : inter.position.locEnd() ); } else { this->raise(Errors::IllegalLanguageModeDirective, inter.position); @@ -2755,7 +2755,7 @@ namespace BabelParser::ExpressionParser { PTR(Node::YieldExpression) parseYield() { auto startInfo = this->startNodeInfo(); - this->expressionScope->recordParameterInitializerError(Errors::YieldInParameter, *startInfo.locStart()); + this->expressionScope->recordParameterInitializerError(Errors::YieldInParameter, startInfo.locStart()); this->next(); bool delegating = false; diff --git a/src/babel/babel-parser/parser/lval.hpp b/src/babel/babel-parser/parser/lval.hpp index 54276d1..c0109c0 100644 --- a/src/babel/babel-parser/parser/lval.hpp +++ b/src/babel/babel-parser/parser/lval.hpp @@ -128,7 +128,7 @@ namespace BabelParser { // i.e. `([(a) = []] = []) => {}` // see also `recordArrowParameterBindingError` signature in packages/babel-parser/src/util/expression-scope.js if ((*parenthesized)->type() == Node::Type::Identifier) { - this->expressionScope->recordArrowParameterBindingError(Errors::InvalidParenthesizedAssignment, *node->locStart()); + this->expressionScope->recordArrowParameterBindingError(Errors::InvalidParenthesizedAssignment, node->locStart()); } else if ((*parenthesized)->type() != Node::Type::MemberExpression && !this->isOptionalMemberExpression(*parenthesized)) [[unlikely]] { // A parenthesized member expression can be in LHS but not in pattern. // If the LHS is later interpreted as a pattern, `checkLVal` will throw for member expression binding @@ -174,7 +174,7 @@ namespace BabelParser { auto const &key = NODEAS(node, ObjectProperty)->key(); auto &value = NODEAS(node, ObjectProperty)->value; if (this->isPrivateName(key)) [[unlikely]] { - this->classScope->usePrivateName(this->getPrivateNameSV(key), *key->locStart()); + this->classScope->usePrivateName(this->getPrivateNameSV(key), key->locStart()); } this->template toAssignable(value); break; @@ -200,7 +200,7 @@ namespace BabelParser { { auto const &assignExp = NODEAS(node, AssignmentExpression); if (assignExp->_operator != Node::AssignmentOperator::Value::Assign) [[unlikely]] { - this->raise(Errors::MissingEqInAssignment, *(assignExp->left->locEnd())); + this->raise(Errors::MissingEqInAssignment, assignExp->left->locEnd()); } auto assignPattern = this->template startNode(assignExp->position(), NODEAS(assignExp->left, Pattern), assignExp->right); @@ -504,7 +504,7 @@ namespace BabelParser { flags & ParseBindingListFlags::IS_FUNCTION_PARAMS) { this->parseFunctionParamType(left); } - auto elt = this->parseMaybeDefault(*left->locStart(), left); + auto elt = this->parseMaybeDefault(left->locStart(), left); if (decorators) [[unlikely]] { left->decorators = decorators; } @@ -777,7 +777,7 @@ namespace BabelParser { } void declareNameFromIdentifier(PTR(Node::Identifier) identifier, BindingFlag::Value binding) { - this->scope->declareName(identifier->name, binding, *identifier->locStart()); + this->scope->declareName(identifier->name, binding, identifier->locStart()); } template void checkToRestConversion(PTR(Node::Node) node) { diff --git a/src/babel/babel-parser/parser/node.hpp b/src/babel/babel-parser/parser/node.hpp index 104cfe3..a30926b 100644 --- a/src/babel/babel-parser/parser/node.hpp +++ b/src/babel/babel-parser/parser/node.hpp @@ -43,8 +43,8 @@ namespace BabelParser { } protected: - Node::PositionInfo startNodeInfo() { return Node::PositionInfo{this->state.start, 0, true, false}; } - Node::PositionInfo startNodeInfoAt(const Position &loc) { return Node::PositionInfo{loc.index(), 0, true, false}; } + Node::PositionInfo startNodeInfo() { return Node::PositionInfo{this->state.startLoc}; } + Node::PositionInfo startNodeInfoAt(const Position &loc) { return Node::PositionInfo{loc}; } Node::PositionInfo startNodeInfoAt(Node::PositionInfo const &nodeInfo) { return nodeInfo; } Node::PositionInfo startNodeInfoAt(PTR(Node::Node) node) { return node->position(); } @@ -113,8 +113,7 @@ namespace BabelParser { template PTR(T) finishNodeAt_impl(PTR(T) node, const Position &endLoc) { - node->position().end = endLoc.index(); - node->locEnd(true); + node->position().setEnd(endLoc); // if (this.optionFlags & OptionFlags.Ranges) node.range[1] = endLoc.index; if (this->state.lastCommentWSEnd < node->position().start) [[likely]] { DEBUG_PARSER_STAT_COUNT(CommentPosSkip) @@ -133,8 +132,7 @@ namespace BabelParser { template void resetStartLocation_impl(PTR(T) node, const Position &startLoc) { - node->position().start = startLoc.index(); - node->locStart(true); + node->position().setStart(startLoc); // if (this.optionFlags & OptionFlags.Ranges) node.range[0] = startLoc.index; } @@ -143,8 +141,7 @@ namespace BabelParser { } void resetStartLocation_impl(Node::PositionInfo &startInfo, const Position &startLoc) { - startInfo.start = startLoc.index(); - startInfo.locStart(true); + startInfo.setStart(startLoc); // if (this.optionFlags & OptionFlags.Ranges) node.range[0] = startLoc.index; } @@ -155,8 +152,7 @@ namespace BabelParser { template void resetEndLocation_impl(PTR(T) node, Position const &endLoc) { - node->position().end = endLoc.index(); - node->locEnd(true); + node->position().setEnd(endLoc); // if (this.optionFlags & OptionFlags.Ranges) node.range[1] = endLoc.index; } @@ -165,7 +161,7 @@ namespace BabelParser { */ template void resetStartLocationFromNode(Node::PositionInfo &startInfo, Location &&localtionNodeStartInfo) { - this->resetStartLocation(startInfo, *localtionNodeStartInfo.locStart()); + this->resetStartLocation(startInfo, localtionNodeStartInfo.locStart()); } }; } // namespace BabelParser diff --git a/src/babel/babel-parser/parser/statement.hpp b/src/babel/babel-parser/parser/statement.hpp index b6069ef..648d703 100644 --- a/src/babel/babel-parser/parser/statement.hpp +++ b/src/babel/babel-parser/parser/statement.hpp @@ -1325,7 +1325,7 @@ namespace BabelParser::StatementParser { if (kind == Node::VariableDeclarationKind::Using || kind == Node::VariableDeclarationKind::AwaitUsing) { auto type = id->type(); if (type == Node::Type::ArrayPattern || type == Node::Type::ObjectPattern) { - this->raise(Errors::UsingDeclarationHasBindingPattern, *id->locStart()); + this->raise(Errors::UsingDeclarationHasBindingPattern, id->locStart()); } } this->checkLVal( @@ -1456,7 +1456,7 @@ namespace BabelParser::StatementParser { !this->options.annexB || this->state.strict || node->generator || node->async ? this->scope->treatFunctionsAsVar() ? BindingFlag::TYPE_VAR : BindingFlag::TYPE_LEXICAL : BindingFlag::TYPE_FUNCTION, - *nodeId->locStart() + nodeId->locStart() ); } @@ -1914,7 +1914,7 @@ namespace BabelParser::StatementParser { classBody->body->push_back(node); this->classScope->declarePrivateName( - this->getPrivateNameSV(this->getClassPrivatePropertyKey(node)), ClassElementType::OTHER, *this->getClassPrivatePropertyKey(node)->locStart() + this->getPrivateNameSV(this->getClassPrivatePropertyKey(node)), ClassElementType::OTHER, this->getClassPrivatePropertyKey(node)->locStart() ); } template @@ -1929,7 +1929,7 @@ namespace BabelParser::StatementParser { classBody->body->push_back(node); if (isPrivate) { - this->classScope->declarePrivateName(this->getPrivateNameSV(node->key()), ClassElementType::OTHER, *node->key()->locStart()); + this->classScope->declarePrivateName(this->getPrivateNameSV(node->key()), ClassElementType::OTHER, node->key()->locStart()); } } template @@ -1981,7 +1981,7 @@ namespace BabelParser::StatementParser { } void declareClassPrivateMethodInScope_impl(PTR(Node::Node) node, ClassElementType::Value kind) { this->classScope->declarePrivateName( - this->getPrivateNameSV(this->getClassPrivateMethodKey(node)), kind, *this->getClassPrivateMethodKey(node)->locStart() + this->getPrivateNameSV(this->getClassPrivateMethodKey(node)), kind, this->getClassPrivateMethodKey(node)->locStart() ); } @@ -2406,7 +2406,7 @@ namespace BabelParser::StatementParser { this->raise(Errors::ExportBindingIsString, specifier, NODEAS(local, StringLiteral)->value, exportName->string()); } else { // check for keywords used as local names - this->checkReservedWord(NODEAS(local, Identifier)->name, *local->locStart(), true, false); + this->checkReservedWord(NODEAS(local, Identifier)->name, local->locStart(), true, false); // check if export is defined this->scope->checkLocalExport(NODEAS(local, Identifier)); } @@ -2561,19 +2561,19 @@ namespace BabelParser::StatementParser { auto singleBindingType = inter.specifiers->size() == 1 ? inter.specifiers->front()->type() : Node::Type::__Undefined; if (inter.phase == BASE::Id::$source) { if (singleBindingType != Node::Type::ImportDefaultSpecifier) { - this->raise(Errors::SourcePhaseImportRequiresDefault, *inter.specifiers->front()->locStart()); + this->raise(Errors::SourcePhaseImportRequiresDefault, inter.specifiers->front()->locStart()); } } else if (inter.phase == BASE::Id::$defer) { if (singleBindingType != Node::Type::ImportNamespaceSpecifier) { - this->raise(Errors::DeferImportRequiresNamespace, *inter.specifiers->front()->locStart()); + this->raise(Errors::DeferImportRequiresNamespace, inter.specifiers->front()->locStart()); } } if (inter._module.value_or(false)) { if (singleBindingType != Node::Type::ImportDefaultSpecifier) [[unlikely]] { - this->raise(Errors::ImportReflectionNotBinding, *inter.specifiers->front()->locStart()); + this->raise(Errors::ImportReflectionNotBinding, inter.specifiers->front()->locStart()); } if (inter.assertions && inter.assertions->size() > 0) [[unlikely]] { - this->raise(Errors::ImportReflectionHasAssertion, *inter.specifiers->front()->locStart()); + this->raise(Errors::ImportReflectionHasAssertion, inter.specifiers->front()->locStart()); } } } @@ -3036,7 +3036,7 @@ namespace BabelParser::StatementParser { if (importedIsString) [[unlikely]] { this->ThrowRaise(Errors::ImportBindingIsString, inter.position, NODEAS(imported, StringLiteral)->value); } - this->checkReservedWord(NODEAS(imported, Identifier)->name, *inter.position.locStart(), true, true); + this->checkReservedWord(NODEAS(imported, Identifier)->name, inter.position.locStart(), true, true); if (!inter.local) { inter.local = this->cloneIdentifier(REINTERPRET_PTR(Node::Identifier)(imported)); } diff --git a/src/babel/babel-parser/plugins/estree.hpp b/src/babel/babel-parser/plugins/estree.hpp index 1d88070..f1e792c 100644 --- a/src/babel/babel-parser/plugins/estree.hpp +++ b/src/babel/babel-parser/plugins/estree.hpp @@ -272,11 +272,10 @@ namespace BabelParser::Plugins::ESTree { // @ts-expect-error mutate AST types node.value = funcNode; auto typeParameters = node.typeParameters; - if (typeParameters) { + if (typeParameters) [[unlikely]] { node.typeParameters = nullptr; funcNode->typeParameters = typeParameters; - funcNode->position().start = typeParameters->position().start; - funcNode->locStart(true); + funcNode->position().setStart(typeParameters->position().locStart()); } if constexpr (BabelTypes::IsClassPrivateMethod) { node.computed = false; @@ -403,7 +402,7 @@ namespace BabelParser::Plugins::ESTree { auto const &key = NODEAS(node, EstreeProperty)->key(); auto &value = NODEAS(node, EstreeProperty)->value; if (this->isPrivateName(key)) { - this->classScope->usePrivateName(this->getPrivateNameSV(key), *key->locStart()); + this->classScope->usePrivateName(this->getPrivateNameSV(key), key->locStart()); } this->template toAssignable(value); } else { diff --git a/src/babel/babel-parser/plugins/typescript/index.hpp b/src/babel/babel-parser/plugins/typescript/index.hpp index e8e5c70..6364c7d 100644 --- a/src/babel/babel-parser/plugins/typescript/index.hpp +++ b/src/babel/babel-parser/plugins/typescript/index.hpp @@ -534,7 +534,7 @@ namespace BabelParser::Plugins::TypeScript { template PTRS(T) - tsParseDelimitedList(ParsingContext::Value kind, ParseElement &&parseElement, BASE::position_t *refTrailingCommaPos = nullptr) { + tsParseDelimitedList(ParsingContext::Value kind, ParseElement &&parseElement, Position *refTrailingCommaPos = nullptr) { return nonNull(this->tsParseDelimitedListWorker( kind, std::forward(parseElement), /* expectSuccess */ true, refTrailingCommaPos @@ -548,16 +548,16 @@ namespace BabelParser::Plugins::TypeScript { template PTRS(T) tsParseDelimitedListWorker( - ParsingContext::Value kind, ParseElement &&parseElement, bool expectSuccess, BASE::position_t *refTrailingCommaPos = nullptr + ParsingContext::Value kind, ParseElement &&parseElement, bool expectSuccess, Position *refTrailingCommaPos = nullptr ) { auto result = this->allocator.template buildNodeListOf(); - BASE::position_t trailingCommaPos = -1; + Position trailingCommaPos = Position{-1,-1,-1}; for (;;) { if (this->tsIsListTerminator(kind)) { break; } - trailingCommaPos = -1; + trailingCommaPos = Position{-1,-1,-1}; auto element = parseElement(); if (element == nullptr) { @@ -566,7 +566,7 @@ namespace BabelParser::Plugins::TypeScript { result->push_back(element); if (this->eat(TokenType::$_comma)) { - trailingCommaPos = this->state.lastTokStartLoc.index(); + trailingCommaPos = this->state.lastTokStartLoc; continue; } @@ -591,7 +591,7 @@ namespace BabelParser::Plugins::TypeScript { template PTRS(T) tsParseBracketedList( - ParsingContext::Value kind, ParseElement &&parseElement, bool bracket, bool skipFirstToken, BASE::position_t *refTrailingCommaPos = nullptr + ParsingContext::Value kind, ParseElement &&parseElement, bool bracket, bool skipFirstToken, Position *refTrailingCommaPos = nullptr ) { if (!skipFirstToken) { if (bracket) { @@ -801,7 +801,7 @@ namespace BabelParser::Plugins::TypeScript { this->unexpected(); } - BASE::position_t refTrailingCommaPos = -1; + Position refTrailingCommaPos{-1, -1, -1}; auto params = this->template tsParseBracketedList( ParsingContext::TypeParametersOrArguments, [&]() { return this->tsParseTypeParameter(parseModifiers); }, @@ -813,8 +813,8 @@ namespace BabelParser::Plugins::TypeScript { } auto node = this->template finishNode(nodeInfo, params); ; - if (refTrailingCommaPos != -1) { - node->setTrailingCommaLoc(Position{refTrailingCommaPos}); + if (refTrailingCommaPos.index() != -1) { + node->setTrailingCommaLoc(refTrailingCommaPos); } return node; } @@ -2310,7 +2310,7 @@ namespace BabelParser::Plugins::TypeScript { parseAssignableListItem_impl(PTRS(Node::Decorator) decoratorsMaybeNull) { // Store original location to include modifiers in range auto startLoc = this->state.startLoc; - Node::Declaration_ClassMethodOrDeclareMethodValue modified{Node::PositionInfo{0, 0, false, false}}; + Node::Declaration_ClassMethodOrDeclareMethodValue modified{Node::PositionInfo{}}; constexpr auto allowedModifiers = (Node::Modifier::Public | Node::Modifier::Private | Node::Modifier::Protected | Node::Modifier::Override | Node::Modifier::Readonly); this->tsParseModifiers( @@ -2329,7 +2329,7 @@ namespace BabelParser::Plugins::TypeScript { if (flags & ParseBindingListFlags::IS_FUNCTION_PARAMS) { this->parseFunctionParamType(left); } - auto elt = this->parseMaybeDefault(*left->locStart(), left); + auto elt = this->parseMaybeDefault(left->locStart(), left); if (accessibility || readonly || override) { auto pp = this->startNodeInfoAt(startLoc); if (elt->type() != Node::Type::Identifier && elt->type() != Node::Type::AssignmentPattern) { @@ -2610,7 +2610,7 @@ namespace BabelParser::Plugins::TypeScript { void checkImportReflection_impl(Node::ImportDeclaration::Value &node) { this->Super::checkImportReflection_impl(node); if (node._module && node.importKind != BabelTypes::Enum::ImportExportKind::_value) { - this->raise(TSErrors::ImportReflectionHasImportType, *node.specifiers->front()->locStart()); + this->raise(TSErrors::ImportReflectionHasImportType, node.specifiers->front()->locStart()); } } @@ -3289,7 +3289,7 @@ namespace BabelParser::Plugins::TypeScript { // A single type parameter must either have constraints // or a trailing comma, otherwise it's ambiguous with JSX. this->raise( - TSErrors::SingleTypeParameterWithoutTrailingComma, createPositionWithColumnOffset(*parameter->locEnd(), 1), + TSErrors::SingleTypeParameterWithoutTrailingComma, createPositionWithColumnOffset(parameter->locEnd(), 1), parameter->name_->name->string() ); } @@ -3461,7 +3461,7 @@ namespace BabelParser::Plugins::TypeScript { EXP: if (expression) { if constexpr (isLHS) { - this->expressionScope->recordArrowParameterBindingError(TSErrors::UnexpectedTypeCastInParameter, *node->locStart()); + this->expressionScope->recordArrowParameterBindingError(TSErrors::UnexpectedTypeCastInParameter, node->locStart()); } else { this->raise(TSErrors::UnexpectedTypeCastInParameter, node); } @@ -3669,7 +3669,7 @@ namespace BabelParser::Plugins::TypeScript { default: std::terminate(); } - this->resetEndLocation(expression, *node->typeAnnotation->locEnd()); + this->resetEndLocation(expression, node->typeAnnotation->locEnd()); return expression; } @@ -3930,14 +3930,14 @@ namespace BabelParser::Plugins::TypeScript { if (isImport) { leftOfAs = this->template parseIdentifier(); if (!this->isContextual(TokenType::$_as)) { - this->checkReservedWord(NODEAS(leftOfAs, Identifier)->name, *leftOfAs->locStart(), true, true); + this->checkReservedWord(NODEAS(leftOfAs, Identifier)->name, leftOfAs->locStart(), true, true); } } else { leftOfAs = this->parseModuleExportName(); } } if (hasTypeSpecifier && isInTypeOnlyImportExport) { - this->raise(isImport ? TSErrors::TypeModifierIsUsedInTypeImports : TSErrors::TypeModifierIsUsedInTypeExports, *loc); + this->raise(isImport ? TSErrors::TypeModifierIsUsedInTypeImports : TSErrors::TypeModifierIsUsedInTypeExports, loc); } leftOfAsKey(node) = leftOfAs; diff --git a/src/babel/babel-parser/tokenizer/state.hpp b/src/babel/babel-parser/tokenizer/state.hpp index ac58d62..d6142dc 100644 --- a/src/babel/babel-parser/tokenizer/state.hpp +++ b/src/babel/babel-parser/tokenizer/state.hpp @@ -88,7 +88,7 @@ namespace BabelParser::Tokenizer::State { BabelParser::Util::Location::Position lastTokEndLoc; BASE::position_t curLine; BASE::position_t lineStart; - BabelParser::Util::Location::Position curPosition() const { return {this->curLine, this->pos - this->lineStart, this->pos}; } + BabelParser::Util::Location::Position curPosition() const { return Position{this->curLine, this->pos - this->lineStart, this->pos}; } PositionWithLineColumn curPositionWithLineColumn() const { return PositionWithLineColumn{this->pos, this->curLine, this->pos - this->lineStart}; } }; @@ -275,7 +275,7 @@ namespace BabelParser::Tokenizer::State { // Used to track invalid escape sequences in template literals, // that must be reported if the template is not tagged. - BabelParser::Util::Location::Position firstInvalidTemplateEscapePos{-1}; + BabelParser::Util::Location::Position firstInvalidTemplateEscapePos{-1, -1, -1}; // This property is used to track the following errors // - StrictNumericEscape diff --git a/src/babel/babel-parser/tokenizer/tokenizer.hpp b/src/babel/babel-parser/tokenizer/tokenizer.hpp index 01a6a1c..6d4e1b3 100644 --- a/src/babel/babel-parser/tokenizer/tokenizer.hpp +++ b/src/babel/babel-parser/tokenizer/tokenizer.hpp @@ -109,11 +109,11 @@ namespace BabelParser::Tokenizer { if constexpr (std::is_same_v) { return node; } else if constexpr (std::is_same_v) { - return *node.locStart(); + return node.locStart(); } else if constexpr (std::is_base_of_v || std::is_same_v) { return *node.locStart(); } else if constexpr (std::is_base_of_v::type>) { - return *node->locStart(); + return node->locStart(); } else { std::terminate(); } @@ -394,7 +394,7 @@ namespace BabelParser::Tokenizer { auto input = this->input.data(); auto const &length = this->length; auto pos = state.pos; - auto curLine = state.pos; + auto curLine = state.curLine; auto lineStart = state.lineStart; constexpr static SkipSpaceTable table = InitSkipSpaceTable(); diff --git a/src/babel/babel-parser/types.hpp b/src/babel/babel-parser/types.hpp index cfb9d2f..b7f8351 100644 --- a/src/babel/babel-parser/types.hpp +++ b/src/babel/babel-parser/types.hpp @@ -27,28 +27,71 @@ namespace BabelParser::Node { struct PositionInfo { BASE::position_t start; BASE::position_t end; - bool has_start; - bool has_end; - explicit PositionInfo(BASE::position_t start, BASE::position_t end, bool has_start, bool has_end) : - start(start), - end(end), - has_start(has_start), - has_end(has_end) {} - [[nodiscard]] std::optional locStart() const { return has_start ? std::optional(Position{start}) : std::nullopt; } - [[nodiscard]] std::optional locEnd() const { return has_end ? std::optional(Position{end}) : std::nullopt; } - void locStart(bool v) { this->has_start = v; } - void locEnd(bool v) { this->has_end = v; } + BASE::position_t start_line; + // BASE::position_t start_column; + BASE::position_t end_line; + // BASE::position_t end_column; + + explicit PositionInfo() : + start(-1), + end(-1) {} + explicit PositionInfo(Position start) : + start(start.index()), + start_line(start.line()), + // start_column(start.column()), + end(-1) + {} + explicit PositionInfo(Position start, Position end) : + start(start.index()), + start_line(start.line()), + // start_column(start.column()), + end(end.index()), + end_line(end.line()) + // end_column(end.column()) + {} + bool has_start() const { return start >= 0; } + bool has_end() const { return end >= 0; } + [[nodiscard]] Position locStart() const { return Position{start_line, -1, start}; } + [[nodiscard]] BASE::position_t locStartLine(BASE::position_t default_value) const { return start >= 0 ? start_line : default_value; } + [[nodiscard]] Position locEnd() const { return Position{end_line, -1, end}; } + [[nodiscard]] BASE::position_t locEndLine(BASE::position_t default_value) const { return end >= 0 ? end_line : default_value; } + void setStart(Position start) { + this->start = start.index(); + this->start_line = start.line(); + // this->start_column = start.column(); + } + void setEnd(Position end) { + this->end = end.index(); + this->end_line = end.line(); + // this->end_column = end.column(); + } + }; struct NodeExtra { bool parenthesized = false; void setParenthesized() { this->parenthesized = true; } }; + struct CommentInfo { + BASE::LinkedItem* leading; + BASE::LinkedItem* inner; + BASE::LinkedItem* trailing; + template + BASE::LinkedItem*& ref() { + if constexpr (TYPE == CommentPosition::Leading) return this->leading; + else if constexpr (TYPE == CommentPosition::Inner) return this->inner; + else if constexpr (TYPE == CommentPosition::Trailing) return this->trailing; + else { + unreachable(); + } + } + }; class Node { Type type_; - CommentPosition::Type commentPosBits = CommentPosition::Unknown; + // CommentPosition::Type commentPosBits = CommentPosition::Unknown; NodeExtra extra_; PositionInfo pos_; - BASE::LinkedItem *comment = nullptr; + CommentInfo *comments = nullptr; + // BASE::LinkedItem *comment = nullptr; #ifdef NDEBUG #else virtual Type vtype() const { return this->type_; } @@ -64,22 +107,44 @@ namespace BabelParser::Node { [[nodiscard]] PositionInfo &position() { return this->pos_; } [[nodiscard]] NodeExtra const &extra() const { return this->extra_; } [[nodiscard]] NodeExtra &extra() { return this->extra_; } - [[nodiscard]] std::optional locStart() const { return this->pos_.locStart(); } - [[nodiscard]] std::optional locEnd() const { return this->pos_.locEnd(); } - void locStart(bool v) { this->pos_.locStart(v); } - void locEnd(bool v) { this->pos_.locEnd(v); } + [[nodiscard]] Position locStart() const { return this->pos_.locStart(); } + [[nodiscard]] BASE::position_t locStartLine(BASE::position_t default_value) const { return this->pos_.locStartLine(default_value); } + [[nodiscard]] BASE::position_t locEndLine(BASE::position_t default_value) const { return this->pos_.locEndLine(default_value); } + [[nodiscard]] Position locEnd() const { return this->pos_.locEnd(); } template - std::optional loc() const { + Position loc() const { if constexpr (P == PositionType::Start) { return this->locStart(); } else { return this->locEnd(); } } + template + BASE::position_t locLine(BASE::position_t default_value) const { + if constexpr (P == PositionType::Start) { + return this->locStartLine(default_value); + } else { + return this->locEndLine(default_value); + } + } + template + bool has_loc() const { + if constexpr (P == PositionType::Start) { + return this->position().has_start(); + } else { + return this->position().has_end(); + } + } template inline void unshiftComments(BASE::LinkedItem *comment); template [[nodiscard]] inline BASE::LinkedItem *getComments() const; + Node* makeComments(BASE::Memory::Allocator* allocator) { + if (!this->comments) { + this->comments = allocator->template allocate(1); + } + return this; + } void unshiftLeadingComments(BASE::LinkedItem *comment) { this->unshiftComments(comment); } void unshiftInnerComments(BASE::LinkedItem *comment) { this->unshiftComments(comment); } void unshiftTrailingComments(BASE::LinkedItem *comment) { this->unshiftComments(comment); } @@ -96,16 +161,16 @@ namespace BabelParser::Node { writer.field("start", this->position().start); writer.field("end", this->position().end); - if (auto _start = this->locStart()) { - auto start = _start->withLineColumn(writer.input()); + if (this->position().has_start()) { + auto start = this->locStart().withLineColumn(writer.input()); writer.field("loc.start.line", start.line()); writer.field("loc.start.column", start.column()); if (!writer.estree()) { writer.field("loc.start.index", start.index()); } } - if (auto _end = this->locEnd()) { - auto end = _end->withLineColumn(writer.input()); + if (this->position().has_end()) { + auto end = this->locEnd().withLineColumn(writer.input()); writer.field("loc.end.line", end.line()); writer.field("loc.end.column", end.column()); if (!writer.estree()) { @@ -141,14 +206,14 @@ public: class Comment : public Node { public: - CommentPosition::Value commentPos = CommentPosition::Unknown; + // CommentPosition::Value commentPos = CommentPosition::Unknown; BASE::UStringView value; PositionWithLineColumn start_; PositionWithLineColumn end_; bool ignore = false; bool printed = false; explicit Comment(Type type, PositionWithLineColumn const &start, PositionWithLineColumn const &end, BASE::UStringView value) : - Node(type, PositionInfo{start.index(), end.index(), true, true}), + Node(type, PositionInfo{start, end}), value(value), start_(start), end_(end) {} @@ -3604,31 +3669,26 @@ public: // impl template inline void Node::unshiftComments(BASE::LinkedItem *comment) { - this->commentPosBits |= TYPE; auto next = &comment; while (*next) { - (***next).commentPos = TYPE; + // (***next).commentPos = TYPE; next = &(*next)->next(); } - if (this->comment == nullptr) { - this->comment = comment; + auto& ref = this->comments->ref(); + if (ref == nullptr) { + ref = comment; } else { - *next = this->comment; - this->comment = comment; + *next = ref; + ref = comment; } } template [[nodiscard]] inline BASE::LinkedItem *Node::getComments() const { - if (this->commentPosBits & TYPE) [[unlikely]] { - auto comment = this->comment; - while (comment != nullptr) [[unlikely]] { - if ((*comment)->commentPos == TYPE) { - return comment; - } - comment = comment->next(); - } + if (this->comments) { + return this->comments->ref(); + } else { + return nullptr; } - return nullptr; } inline void ExpressionStatement::format(Writer::NodeWriter &writer) const { writer.node("expression", this->expression); diff --git a/src/babel/babel-parser/util/location.hpp b/src/babel/babel-parser/util/location.hpp index 8e6c627..d5d19da 100644 --- a/src/babel/babel-parser/util/location.hpp +++ b/src/babel/babel-parser/util/location.hpp @@ -6,14 +6,18 @@ namespace BabelParser::Util::Location { class PositionWithLineColumn; class Position { + protected: BASE::position_t index_; + BASE::position_t line_; + // BASE::position_t column_; public: Position() = default; - Position(BASE::position_t _line, BASE::position_t _column, BASE::position_t index) : index_(index) {} - explicit Position(BASE::position_t index) : index_(index) {} + explicit Position(BASE::position_t _line, BASE::position_t _column, BASE::position_t index) : line_(_line) /*, column_(_column)*/, index_(index) {} + // explicit Position(BASE::position_t index) : index_(index) {} [[nodiscard]] BASE::position_t index() const { return index_; } - + [[nodiscard]] BASE::position_t line() const { return line_; } + // [[nodiscard]] BASE::position_t column() const { return column_; } [[nodiscard]] PositionWithLineColumn withLineColumn(BASE::UStringView input) const; }; inline std::pair resolveLineColumnFromIndex(BASE::UStringView input, BASE::position_t expectIndex) { @@ -46,12 +50,12 @@ namespace BabelParser::Util::Location { return std::make_pair(line, column); } class PositionWithLineColumn : public Position { - BASE::position_t line_; + // BASE::position_t line_; BASE::position_t column_; public: - PositionWithLineColumn(BASE::position_t index, BASE::position_t line, BASE::position_t column) : Position(index), line_(line), column_(column) {} - PositionWithLineColumn(BASE::UStringView input, BASE::position_t index) : Position(index) { + PositionWithLineColumn(BASE::position_t index, BASE::position_t line, BASE::position_t column) : Position(line, column, index)/*, line_(line)*/, column_(column) {} + PositionWithLineColumn(BASE::UStringView input, BASE::position_t index) : Position(0, 0, index) { auto [line, column] = resolveLineColumnFromIndex(input, index); line_ = line; column_ = column; @@ -62,6 +66,6 @@ namespace BabelParser::Util::Location { inline PositionWithLineColumn Position::withLineColumn(BASE::UStringView input) const { return PositionWithLineColumn{input, this->index()}; } inline Position createPositionWithColumnOffset(const Position &position, BASE::position_t columnOffset) { - return Position{position.index() + columnOffset}; + return Position{position.line(), -1, position.index() + columnOffset}; } } // namespace BabelParser::Util::Location diff --git a/src/babel/babel-parser/util/scope.hpp b/src/babel/babel-parser/util/scope.hpp index 9308dbb..93ec4bf 100644 --- a/src/babel/babel-parser/util/scope.hpp +++ b/src/babel/babel-parser/util/scope.hpp @@ -296,7 +296,7 @@ namespace BabelParser::Util::Scope { // Modules are strict by default, but the `scriptMode` option // can overwrite this behavior. !topLevelScope->template contains(name)) { - this->undefinedExports.insert(std::make_pair(name, *id->locStart())); + this->undefinedExports.insert(std::make_pair(name, id->locStart())); this->undefinedExportIds.push_back(name); } }