blob: 023d01158bae2c07c31535f9cd6f8971cfd9c1b7 [file] [log] [blame]
//===--- HiddenLibSyntaxAction.cpp ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/Parse/HiddenLibSyntaxAction.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/DiagnosticsParse.h"
#include "swift/AST/Module.h"
#include "swift/Basic/OwnedString.h"
#include "swift/Parse/ParsedTrivia.h"
#include "swift/Parse/SyntaxParsingCache.h"
#include "swift/Parse/Token.h"
#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/SyntaxVisitor.h"
#include "swift/Syntax/Trivia.h"
#include "llvm/ADT/SmallVector.h"
using namespace swift;
using namespace swift::syntax;
using namespace llvm;
OpaqueSyntaxNode
HiddenLibSyntaxAction::makeHiddenNode(OpaqueSyntaxNode explicitActionNode,
OpaqueSyntaxNode libSyntaxNode) {
auto dat = NodeAllocator.Allocate();
return new (dat) Node(explicitActionNode, libSyntaxNode);
}
OpaqueSyntaxNode HiddenLibSyntaxAction::recordToken(
tok tokenKind, ArrayRef<ParsedTriviaPiece> leadingTrivia,
ArrayRef<ParsedTriviaPiece> trailingTrivia, CharSourceRange range) {
OpaqueSyntaxNode primaryNode = ExplicitAction->recordToken(
tokenKind, leadingTrivia, trailingTrivia, range);
OpaqueSyntaxNode secondaryNode = nullptr;
if (areBothLibSyntax()) {
secondaryNode = primaryNode;
} else {
secondaryNode = LibSyntaxAction->recordToken(tokenKind, leadingTrivia,
trailingTrivia, range);
}
return makeHiddenNode(primaryNode, secondaryNode);
}
OpaqueSyntaxNode HiddenLibSyntaxAction::recordMissingToken(tok tokenKind,
SourceLoc loc) {
OpaqueSyntaxNode primaryNode =
ExplicitAction->recordMissingToken(tokenKind, loc);
OpaqueSyntaxNode secondaryNode = nullptr;
if (areBothLibSyntax()) {
secondaryNode = primaryNode;
} else {
secondaryNode = LibSyntaxAction->recordMissingToken(tokenKind, loc);
}
return makeHiddenNode(primaryNode, secondaryNode);
}
OpaqueSyntaxNode
HiddenLibSyntaxAction::recordRawSyntax(syntax::SyntaxKind kind,
ArrayRef<OpaqueSyntaxNode> elements,
CharSourceRange range) {
OpaqueSyntaxNode primaryNode = nullptr;
OpaqueSyntaxNode secondaryNode = nullptr;
{
SmallVector<OpaqueSyntaxNode, 4> primaryElements;
primaryElements.reserve(elements.size());
for (auto element : elements) {
OpaqueSyntaxNode primaryElement = nullptr;
if (element)
primaryElement = ((Node *)element)->ExplicitActionNode;
primaryElements.push_back(primaryElement);
}
primaryNode = ExplicitAction->recordRawSyntax(kind, primaryElements, range);
}
if (areBothLibSyntax()) {
secondaryNode = primaryNode;
} else {
SmallVector<OpaqueSyntaxNode, 4> secondaryElements;
secondaryElements.reserve(elements.size());
for (auto element : elements) {
OpaqueSyntaxNode secondaryElement = nullptr;
if (element)
secondaryElement = ((Node *)element)->LibSyntaxNode;
secondaryElements.push_back(secondaryElement);
}
secondaryNode =
LibSyntaxAction->recordRawSyntax(kind, secondaryElements, range);
}
return makeHiddenNode(primaryNode, secondaryNode);
}
std::pair<size_t, OpaqueSyntaxNode>
HiddenLibSyntaxAction::lookupNode(size_t lexerOffset, syntax::SyntaxKind kind) {
size_t length;
OpaqueSyntaxNode n;
std::tie(length, n) = ExplicitAction->lookupNode(lexerOffset, kind);
if (length == 0)
return {0, nullptr};
return {length, makeHiddenNode(n, nullptr)};
}
RawSyntax *HiddenLibSyntaxAction::getLibSyntaxNodeFor(OpaqueSyntaxNode node) {
auto hiddenNode = (Node *)node;
return (RawSyntax *)hiddenNode->LibSyntaxNode;
}
OpaqueSyntaxNode
HiddenLibSyntaxAction::getExplicitNodeFor(OpaqueSyntaxNode node) {
auto hiddenNode = (Node *)node;
return hiddenNode->ExplicitActionNode;
}
void HiddenLibSyntaxAction::discardRecordedNode(OpaqueSyntaxNode opaqueN) {
if (!opaqueN)
return;
auto node = static_cast<Node *>(opaqueN);
if (!areBothLibSyntax())
LibSyntaxAction->discardRecordedNode(node->LibSyntaxNode);
ExplicitAction->discardRecordedNode(node->ExplicitActionNode);
}