3
3
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4
4
//
5
5
6
+ using System ;
6
7
using System . Collections . Generic ;
8
+ using System . IO ;
7
9
using System . Management . Automation . Language ;
10
+ using System . Text . RegularExpressions ;
8
11
using Microsoft . PowerShell . EditorServices . Utility ;
9
12
10
13
namespace Microsoft . PowerShell . EditorServices
@@ -14,14 +17,17 @@ namespace Microsoft.PowerShell.EditorServices
14
17
/// </summary>
15
18
internal class FindDotSourcedVisitor : AstVisitor
16
19
{
20
+ private readonly string _scriptDirectory ;
21
+
17
22
/// <summary>
18
23
/// A hash set of the dot sourced files (because we don't want duplicates)
19
24
/// </summary>
20
25
public HashSet < string > DotSourcedFiles { get ; private set ; }
21
26
22
- public FindDotSourcedVisitor ( )
27
+ public FindDotSourcedVisitor ( string scriptPath )
23
28
{
24
- this . DotSourcedFiles = new HashSet < string > ( ) ;
29
+ DotSourcedFiles = new HashSet < string > ( StringComparer . CurrentCultureIgnoreCase ) ;
30
+ _scriptDirectory = Path . GetDirectoryName ( scriptPath ) ;
25
31
}
26
32
27
33
/// <summary>
@@ -33,15 +39,44 @@ public FindDotSourcedVisitor()
33
39
/// or a decision to continue if it wasn't found</returns>
34
40
public override AstVisitAction VisitCommand ( CommandAst commandAst )
35
41
{
36
- if ( commandAst . InvocationOperator . Equals ( TokenKind . Dot ) &&
37
- commandAst . CommandElements [ 0 ] is StringConstantExpressionAst )
42
+ CommandElementAst commandElementAst = commandAst . CommandElements [ 0 ] ;
43
+ if ( commandAst . InvocationOperator . Equals ( TokenKind . Dot ) )
38
44
{
39
- // Strip any quote characters off of the string
40
- string fileName = PathUtils . NormalizePathSeparators ( commandAst . CommandElements [ 0 ] . Extent . Text . Trim ( '\' ' , '"' ) ) ;
41
- DotSourcedFiles . Add ( fileName ) ;
45
+ if ( commandElementAst is StringConstantExpressionAst stringConstantExpressionAst )
46
+ {
47
+ // Strip any quote characters off of the string
48
+ DotSourcedFiles . Add ( PathUtils . NormalizePathSeparators ( stringConstantExpressionAst . Value ) ) ;
49
+ }
50
+ else if ( commandElementAst is ExpandableStringExpressionAst expandableStringExpressionAst )
51
+ {
52
+ var path = GetPathFromExpandableStringExpression ( expandableStringExpressionAst ) ;
53
+ if ( path != null )
54
+ {
55
+ DotSourcedFiles . Add ( PathUtils . NormalizePathSeparators ( path ) ) ;
56
+ }
57
+ }
42
58
}
43
59
44
60
return base . VisitCommand ( commandAst ) ;
45
61
}
62
+
63
+ private string GetPathFromExpandableStringExpression ( ExpandableStringExpressionAst expandableStringExpressionAst )
64
+ {
65
+ var path = expandableStringExpressionAst . Value ;
66
+ foreach ( var nestedExpression in expandableStringExpressionAst . NestedExpressions )
67
+ {
68
+ if ( nestedExpression is VariableExpressionAst variableExpressionAst
69
+ && variableExpressionAst . VariablePath . UserPath . Equals ( "PSScriptRoot" , StringComparison . CurrentCultureIgnoreCase ) )
70
+ {
71
+ path = path . Replace ( variableExpressionAst . ToString ( ) , _scriptDirectory ) ;
72
+ }
73
+ else
74
+ {
75
+ return null ; // We're going to get an invalid path anyway.
76
+ }
77
+ }
78
+
79
+ return path ;
80
+ }
46
81
}
47
82
}
0 commit comments