@@ -884,6 +884,15 @@ class DCDExtComponent : ComponentWrapper
884
884
if (token >= tokens.length || ! tokens[token].isLikeIdentifier)
885
885
return null ;
886
886
887
+ Module _parsed;
888
+ RollbackAllocator rba;
889
+ Module parsed ()
890
+ {
891
+ if (_parsed)
892
+ return _parsed;
893
+ return _parsed = parseModule(tokens, " stdin" , &rba);
894
+ }
895
+
887
896
Related[] ret;
888
897
889
898
switch (tokens[token].type)
@@ -908,8 +917,6 @@ class DCDExtComponent : ComponentWrapper
908
917
// if lister
909
918
auto finder = new IfFinder();
910
919
finder.target = tokens[token].index;
911
- RollbackAllocator rba;
912
- auto parsed = parseModule(tokens, " stdin" , &rba);
913
920
finder.visit(parsed);
914
921
foreach (ifToken; finder.foundIf)
915
922
ret ~= Related(Related.Type.controlFlow, [ifToken.index, ifToken.index + ifToken.tokenText.length]);
@@ -929,8 +936,6 @@ class DCDExtComponent : ComponentWrapper
929
936
finder.isLoop = ! (tokens[token].type == tok! " break" || tokens[token].type == tok! " continue" );
930
937
if (token + 1 < tokens.length && tokens[token + 1 ].type == tok! " identifier" )
931
938
finder.label = tokens[token + 1 ].text;
932
- RollbackAllocator rba;
933
- auto parsed = parseModule(tokens, " stdin" , &rba);
934
939
finder.visit(parsed);
935
940
936
941
if (finder.isLoop && finder.foundBlock.length)
@@ -951,8 +956,6 @@ class DCDExtComponent : ComponentWrapper
951
956
// switch/case lister
952
957
auto finder = new SwitchFinder();
953
958
finder.target = tokens[token].index;
954
- RollbackAllocator rba;
955
- auto parsed = parseModule(tokens, " stdin" , &rba);
956
959
finder.visit(parsed);
957
960
foreach (switchToken; finder.foundSwitch)
958
961
ret ~= Related(Related.Type.controlFlow, [switchToken.index, switchToken.index + switchToken.tokenText.length]);
@@ -961,8 +964,6 @@ class DCDExtComponent : ComponentWrapper
961
964
// return effect lister
962
965
auto finder = new ReturnFinder();
963
966
finder.target = tokens[token].index;
964
- RollbackAllocator rba;
965
- auto parsed = parseModule(tokens, " stdin" , &rba);
966
967
finder.visit(parsed);
967
968
foreach (switchToken; finder.related)
968
969
ret ~= Related(Related.Type.controlFlow, [switchToken.index, switchToken.index + switchToken.tokenText.length]);
@@ -2149,6 +2150,9 @@ final class IfFinder : ASTVisitor
2149
2150
2150
2151
alias visit = ASTVisitor.visit;
2151
2152
2153
+ mixin ASTSearchScopeLimit! (" target" , FunctionBody);
2154
+ mixin ASTFinisher;
2155
+
2152
2156
static foreach (If; AliasSeq! (IfStatement, ConditionalStatement))
2153
2157
override void visit (const If ifStatement)
2154
2158
{
@@ -2279,6 +2283,7 @@ final class IfFinder : ASTVisitor
2279
2283
if (v.index == target)
2280
2284
{
2281
2285
foundIf = currentIf;
2286
+ exitVisitor = true ;
2282
2287
return ;
2283
2288
}
2284
2289
}
@@ -2340,6 +2345,9 @@ final class SwitchFinder : ASTVisitor
2340
2345
2341
2346
alias visit = ASTVisitor.visit;
2342
2347
2348
+ mixin ASTSearchScopeLimit! (" target" , FunctionBody);
2349
+ mixin ASTFinisher;
2350
+
2343
2351
override void visit (const SwitchStatement stmt)
2344
2352
{
2345
2353
if (foundSwitch.length)
@@ -2404,6 +2412,7 @@ final class SwitchFinder : ASTVisitor
2404
2412
if (v.index == target)
2405
2413
{
2406
2414
foundSwitch = currentSwitch;
2415
+ exitVisitor = true ;
2407
2416
return ;
2408
2417
}
2409
2418
}
@@ -2457,6 +2466,9 @@ final class BreakFinder : ASTVisitor
2457
2466
2458
2467
alias visit = ASTVisitor.visit;
2459
2468
2469
+ mixin ASTSearchScopeLimit! (" target" , FunctionBody);
2470
+ mixin ASTFinisher;
2471
+
2460
2472
override void visit (const LabeledStatement stmt)
2461
2473
{
2462
2474
if (foundBlock.length)
@@ -2622,6 +2634,7 @@ final class BreakFinder : ASTVisitor
2622
2634
if (v.index == target)
2623
2635
{
2624
2636
foundBlock = currentBlock;
2637
+ exitVisitor = true ;
2625
2638
return ;
2626
2639
}
2627
2640
}
0 commit comments