Skip to content

Commit

Permalink
Merge pull request #4145 from masatake/powershell-herestr
Browse files Browse the repository at this point in the history
PowerShell: recognize herestrings
  • Loading branch information
masatake authored Dec 4, 2024
2 parents 9a7cfa3 + 32ee6ab commit e5650e9
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions Units/parser-powershell.r/herestring.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--sort=no
11 changes: 11 additions & 0 deletions Units/parser-powershell.r/herestring.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
a input.ps1 /^function a$/;" f
b input.ps1 /^function b$/;" f
c input-0.ps1 /^function c$/;" f
d input-0.ps1 /^function d$/;" f
e input-1.ps1 /^function e$/;" f
f input-2.ps1 /^function f$/;" f
g input-3.ps1 /^function g$/;" f
h input-4.ps1 /^function h$/;" f
i input-5.ps1 /^function i$/;" f
j input-6.ps1 /^function j$/;" f
k input-6.ps1 /^function k$/;" f
16 changes: 16 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-0.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function c
{
$i = 1
$heredoc0 =
@'
'"' $i
'@
Write-Host $heredoc
}
function d
{
Write-Host d
}
c
d
pause
18 changes: 18 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-1.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function e
{
$i = 1
$heredoc0 =
@'
Write-Host $heredoc
}
function inherestr
{
Write-Host d
}
c
d
pause
'"' $i
'@
}
8 changes: 8 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-2.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function f
{
$i = 1
$heredoc0 =
@'
Write-Host $heredoc
@
@'
9 changes: 9 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-3.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function g
{
$i = 1
$heredoc0 =
@'
Write-Host $heredoc
@
@
8 changes: 8 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-4.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function h
{
$i = 1
$heredoc0 =
@"
Write-Host $heredoc
@
@"
13 changes: 13 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-5.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function i
{
$i = 1
$heredoc0 =
@'
Write-Host $heredoc
@
@"
}
function donttagme
{
}
12 changes: 12 additions & 0 deletions Units/parser-powershell.r/herestring.d/input-6.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function j
{
$i = 1
$heredoc0 =
@brokeninput
# So ctags can do as it wants but the current implementation
# intents extracting the next `k`.
}

function k
{
}
16 changes: 16 additions & 0 deletions Units/parser-powershell.r/herestring.d/input.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function a
{
$i = 1
$heredoc =
@"
""" $i
"@
Write-Host $heredoc
}
function b
{
Write-Host b
}
a
b
pause
67 changes: 67 additions & 0 deletions parsers/powershell.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
*
* This module contains code for generating tags for Windows PowerShell scripts
* (https://en.wikipedia.org/wiki/PowerShell).
*
* References:
* - https://learn.microsoft.com/en-us/powershell/scripting/developer/windows-powershell-reference
* - https://learn.microsoft.com/en-us/powershell/scripting/lang-spec/chapter-01
*/

/*
Expand Down Expand Up @@ -102,6 +106,7 @@ typedef struct {
unsigned long lineNumber;
MIOPos filePosition;
int parentKind; /* KIND_GHOST_INDEX if none */
bool herestring; /* Meaningful only when type is TOKEN_STRING. */
} tokenInfo;


Expand Down Expand Up @@ -258,6 +263,43 @@ static void parseString (vString *const string, const int delimiter)
}
}

static bool parseHereString (vString *const string, const int delimiter)
{
enum phs_state {
PHS_INIT,
PHS_NEWLINE0,
PHS_QUOTE,
PHS_AT,
PHS_NEWLINE1,
PHS_END = PHS_NEWLINE1
} s = PHS_INIT;

while (s != PHS_END)
{
int c = getcFromInputFile ();

if (c == EOF)
return false;

vStringPut (string, c);

if (s == PHS_INIT && c == '\n')
s = PHS_NEWLINE0;
else if (s == PHS_NEWLINE0 && c == delimiter)
s = PHS_QUOTE;
else if (s == PHS_QUOTE && c == '@')
s = PHS_AT;
else if (s == PHS_AT && c == '\n')
s = PHS_NEWLINE1;
else
s = PHS_INIT;
}

Assert (vStringLength (string) >= 4);
vStringTruncate (string, vStringLength (string) - 4);
return true;
}

/* parse a identifier that may contain scopes, such as function names and
* variable names.
*
Expand Down Expand Up @@ -356,8 +398,33 @@ static void readTokenFull (tokenInfo *const token, bool includingScope)
parseString (token->string, c);
token->lineNumber = getInputLineNumber ();
token->filePosition = getInputFilePosition ();
token->herestring = false;
break;

case '@':
{
int d = getcFromInputFile ();
if (d == '\'' || d == '"')
{
bool is_herestr;
token->type = TOKEN_STRING;
is_herestr = parseHereString (token->string, d);
token->lineNumber = getInputLineNumber ();
token->filePosition = getInputFilePosition ();
if (is_herestr)
token->herestring = true;
else
token->type = TOKEN_UNDEFINED;
}
else if (d == EOF)
token->type = TOKEN_UNDEFINED;
else
{
ungetcToInputFile (d);
token->type = TOKEN_UNDEFINED;
}
break;
}
case '<':
{
int d = getcFromInputFile ();
Expand Down

0 comments on commit e5650e9

Please sign in to comment.