mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
169 lines
4.1 KiB
C++
169 lines
4.1 KiB
C++
//===--- RawSyntax.cpp - Swift Raw Syntax Implementation ------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 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/Basic/ColorUtils.h"
|
|
#include "swift/Syntax/RawSyntax.h"
|
|
#include "swift/Syntax/TokenSyntax.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <algorithm>
|
|
|
|
using llvm::dyn_cast;
|
|
using namespace swift::syntax;
|
|
|
|
namespace {
|
|
static bool isTrivialSyntaxKind(SyntaxKind Kind) {
|
|
if (isUnknownKind(Kind))
|
|
return true;
|
|
if (isCollectionKind(Kind))
|
|
return true;
|
|
switch(Kind) {
|
|
case SyntaxKind::SourceFile:
|
|
case SyntaxKind::TopLevelCodeDecl:
|
|
case SyntaxKind::ExpressionStmt:
|
|
case SyntaxKind::DeclarationStmt:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static void printSyntaxKind(SyntaxKind Kind, llvm::raw_ostream &OS,
|
|
SyntaxPrintOptions Opts, bool Open) {
|
|
std::unique_ptr<swift::OSColor> Color;
|
|
if (Opts.Visual) {
|
|
Color.reset(new swift::OSColor(OS, llvm::raw_ostream::GREEN));
|
|
}
|
|
OS << "<";
|
|
if (!Open)
|
|
OS << "/";
|
|
dumpSyntaxKind(OS, Kind);
|
|
OS << ">";
|
|
}
|
|
|
|
} // end of anonymous namespace
|
|
void RawSyntax::print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const {
|
|
if (isMissing())
|
|
return;
|
|
|
|
const bool PrintKind = Opts.PrintSyntaxKind && !isToken() &&
|
|
!isTrivialSyntaxKind(Kind);
|
|
if (PrintKind) {
|
|
printSyntaxKind(Kind, OS, Opts, true);
|
|
}
|
|
|
|
if (const auto Tok = dyn_cast<RawTokenSyntax>(this)) {
|
|
Tok->print(OS);
|
|
}
|
|
|
|
for (const auto &LE : Layout) {
|
|
LE->print(OS, Opts);
|
|
}
|
|
if (PrintKind) {
|
|
printSyntaxKind(Kind, OS, Opts, false);
|
|
}
|
|
}
|
|
|
|
void RawSyntax::dump() const {
|
|
return RawSyntax::dump(llvm::errs(), /*Indent*/ 0);
|
|
}
|
|
|
|
void RawSyntax::dump(llvm::raw_ostream &OS, unsigned Indent) const {
|
|
auto indent = [&](unsigned Amount) {
|
|
for (decltype(Amount) i = 0; i < Amount; ++i) {
|
|
OS << ' ';
|
|
}
|
|
};
|
|
|
|
indent(Indent);
|
|
OS << '(';
|
|
|
|
dumpSyntaxKind(OS, Kind);
|
|
|
|
if (isMissing())
|
|
OS << " [missing] ";
|
|
|
|
OS << '\n';
|
|
for (auto LE = Layout.begin(); LE != Layout.end(); ++LE) {
|
|
if (LE != Layout.begin()) {
|
|
OS << '\n';
|
|
}
|
|
switch ((*LE)->Kind) {
|
|
case SyntaxKind::Token:
|
|
llvm::cast<RawTokenSyntax>(*LE)->dump(OS, Indent + 1);
|
|
break;
|
|
default:
|
|
(*LE)->dump(OS, Indent + 1);
|
|
break;
|
|
}
|
|
}
|
|
OS << ')';
|
|
}
|
|
|
|
bool RawSyntax::accumulateAbsolutePosition(
|
|
AbsolutePosition &Pos, const RawSyntax *UpToTargetNode) const {
|
|
auto Found = this == UpToTargetNode;
|
|
for (auto LE : Layout) {
|
|
switch (LE->Kind) {
|
|
case SyntaxKind::Token: {
|
|
auto Tok = llvm::cast<RawTokenSyntax>(LE);
|
|
for (auto Leader : Tok->LeadingTrivia) {
|
|
Leader.accumulateAbsolutePosition(Pos);
|
|
}
|
|
|
|
if (Found) {
|
|
return true;
|
|
}
|
|
|
|
Pos.addText(Tok->getText());
|
|
|
|
for (auto Trailer : Tok->TrailingTrivia) {
|
|
Trailer.accumulateAbsolutePosition(Pos);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
if (Found)
|
|
return true;
|
|
LE->accumulateAbsolutePosition(Pos, UpToTargetNode);
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
AbsolutePosition RawSyntax::getAbsolutePosition(RC<RawSyntax> Root) const {
|
|
AbsolutePosition Pos;
|
|
Root->accumulateAbsolutePosition(Pos, this);
|
|
return Pos;
|
|
}
|
|
|
|
void AbsolutePosition::printLineAndColumn(llvm::raw_ostream &OS) const {
|
|
OS << getLine() << ':' << getColumn();
|
|
}
|
|
|
|
void AbsolutePosition::dump(llvm::raw_ostream &OS) const {
|
|
OS << "(absolute_position ";
|
|
OS << "offset=" << getOffset() << " ";
|
|
OS << "line=" << getLine() << " ";
|
|
OS << "column=" << getColumn();
|
|
OS << ')';
|
|
}
|
|
|
|
swift::RC<RawSyntax>
|
|
RawSyntax::append(RC<RawSyntax> NewLayoutElement) const {
|
|
auto NewLayout = Layout;
|
|
NewLayout.push_back(NewLayoutElement);
|
|
return RawSyntax::make(Kind, NewLayout, SourcePresence::Present);
|
|
}
|