- Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathSyntaxData.cpp
126 lines (110 loc) · 3.59 KB
/
SyntaxData.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//===--- SyntaxData.cpp - Swift Syntax Data 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/Syntax/SyntaxData.h"
usingnamespaceswift;
usingnamespaceswift::syntax;
// MARK: - SyntaxDataRef
voidSyntaxDataRef::dump(llvm::raw_ostream &OS) const {
getRaw()->dump(OS, 0);
OS << '\n';
}
voidSyntaxDataRef::dump() const { dump(llvm::errs()); }
// MARK: - SyntaxData
RC<const SyntaxData>
SyntaxData::getChild(AbsoluteSyntaxPosition::IndexInParentType Index) const {
auto AbsoluteRaw = getAbsoluteRaw().getChild(Index);
if (AbsoluteRaw) {
return RC<SyntaxData>(
newSyntaxData(*AbsoluteRaw, /*Parent=*/RC<const SyntaxData>(this)));
} else {
returnnullptr;
}
}
RC<const SyntaxData> SyntaxData::getPreviousNode() const {
if (size_t N = getIndexInParent()) {
if (hasParent()) {
for (size_t I = N - 1; ; --I) {
if (auto C = getParent()->getChild(I)) {
if (C->getRaw()->isPresent() && C->getFirstToken())
return C;
}
if (I == 0)
break;
}
}
}
returnhasParent() ? getParent()->getPreviousNode() : nullptr;
}
RC<const SyntaxData> SyntaxData::getNextNode() const {
if (hasParent()) {
for (size_t I = getIndexInParent() + 1, N = getParent()->getNumChildren();
I != N; ++I) {
if (auto C = getParent()->getChild(I)) {
if (C->getRaw()->isPresent() && C->getFirstToken())
return C;
}
}
returngetParent()->getNextNode();
}
returnnullptr;
}
RC<const SyntaxData> SyntaxData::getFirstToken() const {
/// getFirstToken and getLastToken cannot be implemented on SyntaxDataRef
/// because we might need to traverse through multiple nodes to reach the
/// first token. When returning this token, the parent nodes are being
/// discarded and thus its parent pointer would point to invalid memory.
if (getRaw()->isToken() && !getRaw()->isMissing()) {
return RC<const SyntaxData>(this);
}
for (size_t I = 0, E = getNumChildren(); I < E; ++I) {
if (auto Child = getChild(I)) {
if (Child->getRaw()->isMissing()) {
continue;
}
if (auto Token = Child->getFirstToken()) {
return Token;
}
}
}
returnnullptr;
}
RC<const SyntaxData> SyntaxData::getLastToken() const {
// Also see comment in getFirstToken.
if (getRaw()->isToken() && !getRaw()->isMissing()) {
return RC<const SyntaxData>(this);
}
if (getNumChildren() == 0) {
returnnullptr;
}
for (int I = getNumChildren() - 1; I >= 0; --I) {
if (auto Child = getChild(I)) {
if (Child->getRaw()->isMissing()) {
continue;
}
if (auto Token = Child->getLastToken()) {
return Token;
}
}
}
returnnullptr;
}
RC<const SyntaxData> SyntaxData::replacingSelf(const RawSyntax *NewRaw) const {
if (hasParent()) {
auto NewParent = getParent()->replacingChild(NewRaw, getIndexInParent());
auto NewSelf = AbsoluteRaw.replacingSelf(
NewRaw, NewParent->AbsoluteRaw.getNodeId().getRootId());
return RC<const SyntaxData>(newSyntaxData(NewSelf, NewParent));
} else {
auto NewSelf = AbsoluteRawSyntax::forRoot(NewRaw);
return RC<const SyntaxData>(newSyntaxData(NewSelf));
}
}