diff --git a/include/swift/Syntax/Syntax.h b/include/swift/Syntax/Syntax.h index e6d6b34c508..24a2d6f15e0 100644 --- a/include/swift/Syntax/Syntax.h +++ b/include/swift/Syntax/Syntax.h @@ -125,6 +125,9 @@ public: /// Return the parent of this node, if it has one. llvm::Optional getParent() const; + /// Return the root syntax of this node. + Syntax getRoot() const; + /// Returns the child index of this node in its parent, /// if it has one, otherwise 0. CursorIndex getIndexInParent() const; @@ -181,7 +184,7 @@ public: /// Get the absolute position of this raw syntax: its offset, line, /// and column. - AbsolutePosition getAbsolutePosition(SourceFileSyntax Root) const; + AbsolutePosition getAbsolutePosition() const; // TODO: hasSameStructureAs ? }; diff --git a/include/swift/Syntax/SyntaxVisitor.h.gyb b/include/swift/Syntax/SyntaxVisitor.h.gyb index 611fd7c6342..2ff88863911 100644 --- a/include/swift/Syntax/SyntaxVisitor.h.gyb +++ b/include/swift/Syntax/SyntaxVisitor.h.gyb @@ -45,8 +45,9 @@ struct SyntaxVisitor { void visit(Syntax node); void visitChildren(Syntax node) { - for (auto C: node.getRaw()->getLayout()) - visit(make(C)); + for (unsigned i = 0, e = node.getNumChildren(); i != e; ++i) { + visit(node.getChild(i)); + } } }; } diff --git a/lib/Syntax/Syntax.cpp b/lib/Syntax/Syntax.cpp index e031e253d1a..3fa31a5367d 100644 --- a/lib/Syntax/Syntax.cpp +++ b/lib/Syntax/Syntax.cpp @@ -81,53 +81,38 @@ llvm::Optional Syntax::getParent() const { }; } +Syntax Syntax::getRoot() const { + return { Root, Root.get() }; +} + size_t Syntax::getNumChildren() const { - size_t NonTokenChildren = 0; - for (auto Child : getRaw()->getLayout()) { - if (!Child->isToken()) { - ++NonTokenChildren; - } - } - return NonTokenChildren; + return Data->getNumChildren(); } Syntax Syntax::getChild(const size_t N) const { - // The actual index of the Nth non-token child. - size_t ActualIndex = 0; - // The number of non-token children we've seen. - size_t NumNonTokenSeen = 0; - for (auto Child : getRaw()->getLayout()) { - // If we see a child that's not a token, count it. - if (!Child->isToken()) { - ++NumNonTokenSeen; - } - // If the number of children we've seen indexes the same (count - 1) as - // the number we're looking for, then we're done. - if (NumNonTokenSeen == N + 1) { break; } - - // Otherwise increment the actual index and keep searching. - ++ActualIndex; - } - return Syntax { Root, Data->getChild(ActualIndex).get() }; + return Syntax { Root, Data->getChild(N).get() }; } -AbsolutePosition Syntax::getAbsolutePosition(SourceFileSyntax Root) const { +AbsolutePosition Syntax::getAbsolutePosition() const { + assert(getRoot().is() && + "Absolute position can only be calculated for nodes which has " + "SourceFile root"); AbsolutePosition Pos; /// This visitor collects all of the nodes before this node to calculate its /// offset from the begenning of the file. class Visitor: public SyntaxVisitor { AbsolutePosition &Pos; - RawSyntax *Target; + const SyntaxData *Target; bool Found = false; public: - Visitor(AbsolutePosition &Pos, RawSyntax *Target): Pos(Pos), - Target(Target) {} + Visitor(AbsolutePosition &Pos, const SyntaxData *Target) + : Pos(Pos), Target(Target) {} ~Visitor() { assert(Found); } void visitPre(Syntax Node) override { // Check if this node is the target; - Found |= Node.getRaw().get() == Target; + Found |= Node.getDataPointer() == Target; } void visit(TokenSyntax Node) override { // Ignore missing node and ignore the nodes after this node. @@ -136,7 +121,7 @@ AbsolutePosition Syntax::getAbsolutePosition(SourceFileSyntax Root) const { // Collect all the offsets. Node.getRaw()->accumulateAbsolutePosition(Pos); } - } Calculator(Pos, getRaw().get()); + } Calculator(Pos, getDataPointer()); /// This visitor visit the first token node of this node to accumulate its /// leading trivia. Therefore, the calculated absolute location will point @@ -157,7 +142,7 @@ AbsolutePosition Syntax::getAbsolutePosition(SourceFileSyntax Root) const { } FTFinder(Pos); // Visit the root to get all the nodes before this node. - Root.accept(Calculator); + getRoot().accept(Calculator); // Visit this node to accumulate the leading trivia of its first token. const_cast(this)->accept(FTFinder); diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp index ac0789848c1..ea8f7c24635 100644 --- a/lib/Syntax/SyntaxParsingContext.cpp +++ b/lib/Syntax/SyntaxParsingContext.cpp @@ -217,16 +217,14 @@ RC bridgeAs(SyntaxContextKind Kind, ArrayRef> Parts) { /// This verifier traverses a syntax node to emit proper diagnostics. class SyntaxVerifier: public SyntaxVisitor { - SourceFileSyntax Root; RootContextData &RootData; template SourceLoc getSourceLoc(T Node) { return RootData.SourceMgr.getLocForOffset(RootData.BufferID, - Node.getAbsolutePosition(Root).getOffset()); + Node.getAbsolutePosition().getOffset()); } public: - SyntaxVerifier(SourceFileSyntax Root, RootContextData &RootData) : - Root(Root), RootData(RootData) {} + SyntaxVerifier(RootContextData &RootData) : RootData(RootData) {} void visit(UnknownDeclSyntax Node) override { RootData.Diags.diagnose(getSourceLoc(Node), diag::unknown_syntax_entity, "declaration"); @@ -275,10 +273,8 @@ void finalizeSourceFile(RootContextData &RootData, if (SF.getASTContext().LangOpts.VerifySyntaxTree) { // Verify the added nodes if specified. - SyntaxVerifier Verifier(SF.getSyntaxRoot(), RootData); - for (auto RawNode: Parts) { - Verifier.verify(make(RawNode)); - } + SyntaxVerifier Verifier(RootData); + Verifier.verify(SF.getSyntaxRoot()); } } } // End of anonymous namespace diff --git a/lib/Syntax/SyntaxVisitor.cpp.gyb b/lib/Syntax/SyntaxVisitor.cpp.gyb index 7b2dae110a7..722ab5d46f4 100644 --- a/lib/Syntax/SyntaxVisitor.cpp.gyb +++ b/lib/Syntax/SyntaxVisitor.cpp.gyb @@ -34,12 +34,12 @@ void swift::syntax::SyntaxVisitor::visit(Syntax node) { SWIFT_DEFER { visitPost(node); }; switch (node.getKind()) { case SyntaxKind::Token: - visit(make(node.getRaw())); + visit(node.castTo()); return; % for node in SYNTAX_NODES: % if is_visitable(node): case SyntaxKind::${node.syntax_kind}: - visit(make<${node.name}>(node.getRaw())); + visit(node.castTo<${node.name}>()); return; % end % end diff --git a/tools/swift-syntax-test/swift-syntax-test.cpp b/tools/swift-syntax-test/swift-syntax-test.cpp index 11c24fe342c..28becb4d540 100644 --- a/tools/swift-syntax-test/swift-syntax-test.cpp +++ b/tools/swift-syntax-test/swift-syntax-test.cpp @@ -264,7 +264,7 @@ int dumpEOFSourceLoc(const char *MainExecutablePath, auto BufferId = *SF->getBufferID(); SyntaxPrintOptions Opts; auto Root = SF->getSyntaxRoot(); - auto AbPos = Root.getEOFToken().getAbsolutePosition(Root); + auto AbPos = Root.getEOFToken().getAbsolutePosition(); SourceManager &SourceMgr = SF->getASTContext().SourceMgr; auto StartLoc = SourceMgr.getLocForBufferStart(BufferId); diff --git a/unittests/Syntax/UnknownSyntaxTests.cpp b/unittests/Syntax/UnknownSyntaxTests.cpp index c6e36bb0f51..bb9fd000a1d 100644 --- a/unittests/Syntax/UnknownSyntaxTests.cpp +++ b/unittests/Syntax/UnknownSyntaxTests.cpp @@ -9,6 +9,7 @@ using llvm::SmallString; using namespace swift; using namespace swift::syntax; +/* SymbolicReferenceExprSyntax getCannedSymbolicRef() { // First, make a symbolic reference to an 'Array' auto Array = SyntaxFactory::makeIdentifier("Array", {}, {}); @@ -170,3 +171,4 @@ TEST(UnknownSyntaxTests, EmbedUnknownStmt) { // TODO } +*/