@@ -450,6 +450,28 @@ await CommandHelpers.GetCommandInfo(
450450 }
451451 }
452452
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+
453475 #endregion
454476
455477 #region Private Fields
@@ -569,6 +591,55 @@ private SymbolReference FindDeclarationForBuiltinCommand(
569591 return foundDefinition ;
570592 }
571593
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+
572643 #endregion
573644 }
574645}
0 commit comments