@@ -450,6 +450,28 @@ await CommandHelpers.GetCommandInfo(
450
450
}
451
451
}
452
452
453
+ /// <summary>
454
+ /// Gets the smallest statment ast that contains the given script position as
455
+ /// indicated by lineNumber and columnNumber parameters.
456
+ /// </summary>
457
+ /// <param name="scriptFile">Open script file.</param>
458
+ /// <param name="lineNumber">1-based line number of the position.</param>
459
+ /// <param name="columnNumber">1-based column number of the position.</param>
460
+ /// <returns></returns>
461
+ public ScriptRegion GetSmallestStatementAstRegion (
462
+ ScriptFile scriptFile ,
463
+ int lineNumber ,
464
+ int columnNumber )
465
+ {
466
+ var ast = GetSmallestStatementAst ( scriptFile , lineNumber , columnNumber ) ;
467
+ if ( ast == null )
468
+ {
469
+ return null ;
470
+ }
471
+
472
+ return ScriptRegion . Create ( ast . Extent ) ;
473
+ }
474
+
453
475
#endregion
454
476
455
477
#region Private Fields
@@ -569,6 +591,55 @@ private SymbolReference FindDeclarationForBuiltinCommand(
569
591
return foundDefinition ;
570
592
}
571
593
594
+ private Ast GetSmallestStatementAst ( ScriptFile scriptFile , int lineNumber , int columnNumber )
595
+ {
596
+ var asts = scriptFile . ScriptAst . FindAll ( ast =>
597
+ {
598
+ if ( ! ( ast is StatementAst ) )
599
+ {
600
+ return false ;
601
+ }
602
+
603
+ var scriptExtent = ast . Extent ;
604
+ if ( scriptExtent . StartLineNumber > lineNumber || scriptExtent . EndLineNumber < lineNumber )
605
+ {
606
+ return false ;
607
+ }
608
+
609
+ if ( scriptExtent . StartLineNumber == lineNumber )
610
+ {
611
+ return scriptExtent . StartColumnNumber <= columnNumber ;
612
+ }
613
+
614
+ if ( scriptExtent . EndLineNumber == lineNumber )
615
+ {
616
+ return scriptExtent . EndColumnNumber >= columnNumber ;
617
+ }
618
+
619
+ return true ;
620
+ } , true ) ;
621
+
622
+ if ( asts == null || asts . Count ( ) == 0 )
623
+ {
624
+ return null ;
625
+ }
626
+
627
+ Func < IScriptExtent , int > getExtentWitdh = extent => extent . EndOffset - extent . StartOffset ;
628
+ var minDiff = getExtentWitdh ( scriptFile . ScriptAst . Extent ) ;
629
+ Ast minAst = scriptFile . ScriptAst ;
630
+ foreach ( var ast in asts )
631
+ {
632
+ var diff = getExtentWitdh ( ast . Extent ) ;
633
+ if ( diff < minDiff )
634
+ {
635
+ minDiff = diff ;
636
+ minAst = ast ;
637
+ }
638
+ }
639
+
640
+ return minAst ;
641
+ }
642
+
572
643
#endregion
573
644
}
574
645
}
0 commit comments