Skip to content

Commit 694e815

Browse files
committed
[Parser] Include all AST nodes from every #if region in ParserUnit
'ParserUnit' is used for analyzing syntax structures _mainly_ in SourceKit. Since we removed IfConfigDecl from AST, ParserUnit didn't inclue any AST in #if ... #endif regions even for active region because it used to consider all inactive. Instead, consider every region "active" and include all the AST nodes. rdar://117387631
1 parent 3afe8eb commit 694e815

12 files changed

+914
-11
lines changed

include/swift/AST/SourceFile.h

+3
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ class SourceFile final : public FileUnit {
9898

9999
/// Validate the new SwiftSyntax parser diagnostics.
100100
ValidateNewParserDiagnostics = 1 << 6,
101+
102+
/// Consider every #if ... #endif region active.
103+
PoundIfAllActive = 1 << 7,
101104
};
102105
using ParsingOptions = OptionSet<ParsingFlags>;
103106

lib/Parse/ParseIfConfig.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,11 @@ Result Parser::parseIfConfigRaw(
834834
// determined solely by which block has the completion token.
835835
!ideInspectionClauseLoc.isValid();
836836

837+
// For constructing syntactic structures, we need AST nodes even for
838+
// non-active regions.
839+
bool allActive = SF.getParsingOptions().contains(
840+
SourceFile::ParsingFlags::PoundIfAllActive);
841+
837842
bool foundActive = false;
838843
bool isVersionCondition = false;
839844
CharSourceRange activeBodyRange;
@@ -893,6 +898,9 @@ Result Parser::parseIfConfigRaw(
893898
if (ideInspectionClauseLoc.isValid() && !foundActive)
894899
isActive = (ClauseLoc == ideInspectionClauseLoc);
895900

901+
if (allActive)
902+
isActive = true;
903+
896904
foundActive |= isActive;
897905

898906
if (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) {

lib/Parse/ParseStmt.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
381381
IsFollowingGuard);
382382

383383
if (IsActive)
384-
activeElements = std::move(elements);
384+
activeElements.append(elements);
385385
});
386386
if (IfConfigResult.hasCodeCompletion() && isIDEInspectionFirstPass()) {
387387
consumeDecl(BeginParserPosition, IsTopLevel);

lib/Parse/Parser.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,7 @@ struct ParserUnit::Implementation {
11451145
auto parsingOpts = SourceFile::getDefaultParsingOptions(LangOpts);
11461146
parsingOpts |= ParsingFlags::DisableDelayedBodies;
11471147
parsingOpts |= ParsingFlags::DisablePoundIfEvaluation;
1148+
parsingOpts |= ParsingFlags::PoundIfAllActive;
11481149

11491150
auto *M = ModuleDecl::createEmpty(Ctx.getIdentifier(ModuleName), Ctx);
11501151
SF = new (Ctx) SourceFile(*M, SFKind, BufferID, parsingOpts);

test/IDE/coloring_configs.swift

+321
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,326 @@
11
// RUN: %target-swift-ide-test -syntax-coloring -source-filename %s -D CONF | %FileCheck %s
22

3+
// CHECK: <kw>var</kw> f : <type>Int</type>
4+
var f : Int
5+
6+
// CHECK: <#kw>#if</#kw> os(macOS)
7+
#if os(macOS)
8+
#endif
9+
10+
// CHECK: <#kw>#if</#kw> CONF
11+
#if CONF
12+
// CHECK: <kw>var</kw> x : <type>Int</type>
13+
var x : Int
14+
// CHECK: <#kw>#else</#kw>
15+
#else
16+
// CHECK: <kw>var</kw> x : <type>Float</type>
17+
var x : Float
18+
// CHECK: <#kw>#endif</#kw>
19+
#endif
20+
21+
// CHECK: <#kw>#if</#kw> CONF
22+
#if CONF
23+
// CHECK: <kw>var</kw> x2 : <type>Int</type>
24+
var x2 : Int
25+
// CHECK: <#kw>#endif</#kw>
26+
#endif
27+
28+
// CHECK: <#kw>#if</#kw> !CONF
29+
#if !CONF
30+
// CHECK: <kw>var</kw> x3 : <type>Int</type>
31+
var x3 : Int
32+
// CHECK: <#kw>#else</#kw>
33+
#else
34+
// CHECK: <kw>var</kw> x3 : <type>Float</type>
35+
var x3 : Float
36+
// CHECK: <#kw>#endif</#kw>
37+
#endif
38+
39+
// CHECK: <#kw>#if</#kw> !CONF
40+
#if !CONF
41+
// CHECK: <kw>var</kw> x4 : <type>Int</type>
42+
var x4 : Int
43+
// CHECK: <#kw>#endif</#kw>
44+
#endif
45+
46+
// CHECK: <#kw>#if</#kw> CONF
47+
#if CONF
48+
// CHECK: <kw>var</kw> y1 : <type>Int</type>
49+
var y1 : Int
50+
// CHECK: <#kw>#elseif</#kw> BAZ
51+
#elseif BAZ
52+
// CHECK: <kw>var</kw> y1 : <type>String</type>
53+
var y1 : String
54+
// CHECK: <#kw>#else</#kw>
55+
#else
56+
// CHECK: <kw>var</kw> y1 : <type>Float</type>
57+
var y1 : Float
58+
// CHECK: <#kw>#endif</#kw>
59+
#endif
60+
61+
// CHECK: <#kw>#if</#kw> !CONF
62+
#if !CONF
63+
// CHECK: <kw>var</kw> y2 : <type>Int</type>
64+
var y2 : Int
65+
// CHECK: <#kw>#elseif</#kw> BAZ
66+
#elseif BAZ
67+
// CHECK: <kw>var</kw> y2 : <type>String</type>
68+
var y2 : String
69+
// CHECK: <#kw>#else</#kw>
70+
#else
71+
// CHECK: <kw>var</kw> y2 : <type>Float</type>
72+
var y2 : Float
73+
// CHECK: <#kw>#endif</#kw>
74+
#endif
75+
76+
// CHECK: <#kw>#if</#kw> !CONF
77+
#if !CONF
78+
// CHECK: <kw>var</kw> y3 : <type>Int</type>
79+
var y3 : Int
80+
// CHECK: <#kw>#elseif</#kw> CONF
81+
#elseif CONF
82+
// CHECK: <kw>var</kw> y3 : <type>String</type>
83+
var y3 : String
84+
// CHECK: <#kw>#else</#kw>
85+
#else
86+
// CHECK: <kw>var</kw> y3 : <type>Float</type>
87+
var y3 : Float
88+
// CHECK: <#kw>#endif</#kw>
89+
#endif
90+
91+
// CHECK: <kw>var</kw> l : <type>Int</type>
92+
var l : Int
93+
94+
// CHECK: <kw>class</kw> C1 {
95+
class C1 {
96+
// CHECK: <kw>var</kw> f : <type>Int</type>
97+
var f : Int
98+
99+
// CHECK: <#kw>#if</#kw> CONF
100+
#if CONF
101+
// CHECK: <kw>var</kw> x : <type>Int</type>
102+
var x : Int
103+
// CHECK: <#kw>#else</#kw>
104+
#else
105+
// CHECK: <kw>var</kw> x : <type>Float</type>
106+
var x : Float
107+
// CHECK: <#kw>#endif</#kw>
108+
#endif
109+
110+
// CHECK: <#kw>#if</#kw> CONF
111+
#if CONF
112+
// CHECK: <kw>var</kw> x2 : <type>Int</type>
113+
var x2 : Int
114+
// CHECK: <#kw>#endif</#kw>
115+
#endif
116+
117+
// CHECK: <#kw>#if</#kw> !CONF
118+
#if !CONF
119+
// CHECK: <kw>var</kw> x3 : <type>Int</type>
120+
var x3 : Int
121+
// CHECK: <#kw>#else</#kw>
122+
#else
123+
// CHECK: <kw>var</kw> x3 : <type>Float</type>
124+
var x3 : Float
125+
// CHECK: <#kw>#endif</#kw>
126+
#endif
127+
128+
// CHECK: <#kw>#if</#kw> !CONF
129+
#if !CONF
130+
// CHECK: <kw>var</kw> x4 : <type>Int</type>
131+
var x4 : Int
132+
// CHECK: <#kw>#endif</#kw>
133+
#endif
134+
135+
// CHECK: <#kw>#if</#kw> CONF
136+
#if CONF
137+
// CHECK: <kw>var</kw> y1 : <type>Int</type>
138+
var y1 : Int
139+
// CHECK: <#kw>#elseif</#kw> BAZ
140+
#elseif BAZ
141+
// CHECK: <kw>var</kw> y1 : <type>String</type>
142+
var y1 : String
143+
// CHECK: <#kw>#else</#kw>
144+
#else
145+
// CHECK: <kw>var</kw> y1 : <type>Float</type>
146+
var y1 : Float
147+
// CHECK: <#kw>#endif</#kw>
148+
#endif
149+
150+
// CHECK: <#kw>#if</#kw> !CONF
151+
#if !CONF
152+
// CHECK: <kw>var</kw> y2 : <type>Int</type>
153+
var y2 : Int
154+
// CHECK: <#kw>#elseif</#kw> BAZ
155+
#elseif BAZ
156+
// CHECK: <kw>var</kw> y2 : <type>String</type>
157+
var y2 : String
158+
// CHECK: <#kw>#else</#kw>
159+
#else
160+
// CHECK: <kw>var</kw> y2 : <type>Float</type>
161+
var y2 : Float
162+
// CHECK: <#kw>#endif</#kw>
163+
#endif
164+
165+
// CHECK: <#kw>#if</#kw> !CONF
166+
#if !CONF
167+
// CHECK: <kw>var</kw> y3 : <type>Int</type>
168+
var y3 : Int
169+
// CHECK: <#kw>#elseif</#kw> CONF
170+
#elseif CONF
171+
// CHECK: <kw>var</kw> y3 : <type>String</type>
172+
var y3 : String
173+
// CHECK: <#kw>#else</#kw>
174+
#else
175+
// CHECK: <kw>var</kw> y3 : <type>Float</type>
176+
var y3 : Float
177+
// CHECK: <#kw>#endif</#kw>
178+
#endif
179+
180+
// CHECK: <kw>var</kw> l : <type>Int</type>
181+
var l : Int
182+
}
183+
184+
// CHECK: <kw>func</kw> test1() {
185+
func test1() {
186+
// CHECK: <kw>var</kw> f : <type>Int</type>
187+
var f : Int
188+
189+
// CHECK: <#kw>#if</#kw> CONF
190+
#if CONF
191+
// CHECK: <kw>var</kw> x : <type>Int</type>
192+
var x : Int
193+
// CHECK: <#kw>#else</#kw>
194+
#else
195+
// CHECK: <kw>var</kw> x : <type>Float</type>
196+
var x : Float
197+
// CHECK: <#kw>#endif</#kw>
198+
#endif
199+
200+
// CHECK: <#kw>#if</#kw> CONF
201+
#if CONF
202+
// CHECK: <kw>var</kw> x2 : <type>Int</type>
203+
var x2 : Int
204+
// CHECK: <#kw>#endif</#kw>
205+
#endif
206+
207+
// CHECK: <#kw>#if</#kw> !CONF
208+
#if !CONF
209+
// CHECK: <kw>var</kw> x3 : <type>Int</type>
210+
var x3 : Int
211+
// CHECK: <#kw>#else</#kw>
212+
#else
213+
// CHECK: <kw>var</kw> x3 : <type>Float</type>
214+
var x3 : Float
215+
// CHECK: <#kw>#endif</#kw>
216+
#endif
217+
218+
// CHECK: <#kw>#if</#kw> !CONF
219+
#if !CONF
220+
// CHECK: <kw>var</kw> x4 : <type>Int</type>
221+
var x4 : Int
222+
// CHECK: <#kw>#endif</#kw>
223+
#endif
224+
225+
// CHECK: <#kw>#if</#kw> CONF
226+
#if CONF
227+
// CHECK: <kw>var</kw> y1 : <type>Int</type>
228+
var y1 : Int
229+
// CHECK: <#kw>#elseif</#kw> BAZ
230+
#elseif BAZ
231+
// CHECK: <kw>var</kw> y1 : <type>String</type>
232+
var y1 : String
233+
// CHECK: <#kw>#else</#kw>
234+
#else
235+
// CHECK: <kw>var</kw> y1 : <type>Float</type>
236+
var y1 : Float
237+
// CHECK: <#kw>#endif</#kw>
238+
#endif
239+
240+
// CHECK: <#kw>#if</#kw> !CONF
241+
#if !CONF
242+
// CHECK: <kw>var</kw> y2 : <type>Int</type>
243+
var y2 : Int
244+
// CHECK: <#kw>#elseif</#kw> BAZ
245+
#elseif BAZ
246+
// CHECK: <kw>var</kw> y2 : <type>String</type>
247+
var y2 : String
248+
// CHECK: <#kw>#else</#kw>
249+
#else
250+
// CHECK: <kw>var</kw> y2 : <type>Float</type>
251+
var y2 : Float
252+
// CHECK: <#kw>#endif</#kw>
253+
#endif
254+
255+
// CHECK: <#kw>#if</#kw> !CONF
256+
#if !CONF
257+
// CHECK: <kw>var</kw> y3 : <type>Int</type>
258+
var y3 : Int
259+
// CHECK: <#kw>#elseif</#kw> CONF
260+
#elseif CONF
261+
// CHECK: <kw>var</kw> y3 : <type>String</type>
262+
var y3 : String
263+
// CHECK: <#kw>#else</#kw>
264+
#else
265+
// CHECK: <kw>var</kw> y3 : <type>Float</type>
266+
var y3 : Float
267+
// CHECK: <#kw>#endif</#kw>
268+
#endif
269+
270+
// CHECK: <kw>var</kw> l : <type>Int</type>
271+
var l : Int
272+
}
273+
274+
// CHECK: <kw>class</kw> C2 {
275+
class C2 {
276+
// CHECK: <#kw>#if</#kw> os(iOS)
277+
#if os(iOS)
278+
// CHECK: <kw>func</kw> foo() {}
279+
func foo() {}
280+
#endif
281+
}
282+
283+
class NestedPoundIf {
284+
// CHECK: <kw>class</kw> NestedPoundIf {
285+
func foo1() {
286+
// CHECK: <kw>func</kw> foo1() {
287+
#if os(macOS)
288+
// CHECK: <#kw>#if</#kw> os(macOS)
289+
var a = 1
290+
// CHECK: <kw>var</kw> a = <int>1</int>
291+
#if USE_METAL
292+
// CHECK: <#kw>#if</#kw> USE_METAL
293+
var b = 2
294+
// CHECK: <kw>var</kw> b = <int>2</int>
295+
#if os(iOS)
296+
// CHECK: <#kw>#if</#kw> os(iOS)
297+
var c = 3
298+
// CHECK: <kw>var</kw> c = <int>3</int>
299+
#else
300+
// CHECK: <#kw>#else</#kw>
301+
var c = 3
302+
// CHECK: <kw>var</kw> c = <int>3</int>
303+
#endif
304+
// CHECK: <#kw>#endif</#kw>
305+
#else
306+
// CHECK: <#kw>#else</#kw>
307+
var b = 2
308+
// CHECK: <kw>var</kw> b = <int>2</int>
309+
#endif
310+
// CHECK: <#kw>#endif</#kw>
311+
#else
312+
// CHECK: <#kw>#else</#kw>
313+
var a = 1
314+
// CHECK: <kw>var</kw> a = <int>1</int>
315+
#endif
316+
// CHECK: <#kw>#endif</#kw>
317+
}
318+
func foo2() {}
319+
// CHECK: <kw>func</kw> foo2() {}
320+
func foo3() {}
321+
// CHECK: <kw>func</kw> foo3() {}
322+
}
323+
3324
// CHECK: <#kw>#error</#kw>(<str>"Error"</str>)
4325
#error("Error")
5326
// CHECK: <#kw>#warning</#kw>(<str>"Warning"</str>)
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-ide-test -syntax-coloring -source-filename %s | %FileCheck %s
2+
// RUN: %target-swift-ide-test -syntax-coloring -typecheck -source-filename %s | %FileCheck %s
3+
4+
// CHECK: <#kw>#if</#kw> d
5+
// CHECK-NEXT: <kw>func</kw> bar() {
6+
// CHECK-NEXT: <#kw>#if</#kw> d
7+
// CHECK-NEXT: }
8+
// CHECK-NEXT: <kw>func</kw> foo() {}
9+
10+
#if d
11+
func bar() {
12+
#if d
13+
}
14+
func foo() {}

0 commit comments

Comments
 (0)