Add expression range to BasicExpressionToken

This commit is contained in:
Christopher Schleiden
2023-02-02 08:52:23 -08:00
parent a1fea7e7fd
commit c287b80557
6 changed files with 76 additions and 13 deletions
@@ -55,7 +55,7 @@ jobs:
steps: steps:
- run: | - run: |
echo \${{ github.event_name }} echo \${{ github.event_name }}
echo 'hello' \${{ github.ref }}` echo 'hello' \${{github.ref }}`
} }
], ],
nullTrace nullTrace
@@ -81,19 +81,27 @@ jobs:
} }
expect(stepRun.originalExpressions).toHaveLength(2); expect(stepRun.originalExpressions).toHaveLength(2);
expect(stepRun.originalExpressions!.map(x => [x.toDisplayString(), x.range])).toEqual([ expect(stepRun.originalExpressions!.map(x => [x.toDisplayString(), x.range, x.expressionRange])).toEqual([
[ [
"${{ github.event_name }}", "${{ github.event_name }}",
{ {
start: {line: 7, column: 16}, start: {line: 7, column: 16},
end: {line: 7, column: 40} end: {line: 7, column: 40}
},
{
start: {line: 7, column: 20},
end: {line: 7, column: 37}
} }
], ],
[ [
"${{ github.ref }}", "${{ github.ref }}",
{ {
start: {line: 8, column: 24}, start: {line: 8, column: 24},
end: {line: 8, column: 41} end: {line: 8, column: 40}
},
{
start: {line: 8, column: 27},
end: {line: 8, column: 37}
} }
] ]
]); ]);
@@ -111,7 +111,7 @@ function convertJob(context: TemplateContext, jobKey: StringToken, token: Mappin
id: jobKey, id: jobKey,
name: undefined, name: undefined,
needs: undefined, needs: undefined,
if: new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined), if: new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined, undefined),
env: undefined, env: undefined,
concurrency: undefined, concurrency: undefined,
environment: undefined, environment: undefined,
@@ -52,7 +52,7 @@ function convertStep(context: TemplateContext, idBuilder: IdBuilder, step: Templ
let uses: StringToken | undefined; let uses: StringToken | undefined;
let continueOnError: boolean | undefined; let continueOnError: boolean | undefined;
let env: MappingToken | undefined; let env: MappingToken | undefined;
const ifCondition = new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined); const ifCondition = new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined, undefined);
for (const item of mapping) { for (const item of mapping) {
const key = item.key.assertString("steps item key"); const key = item.key.assertString("steps item key");
switch (key.value) { switch (key.value) {
@@ -607,7 +607,8 @@ class TemplateReader {
token.range, token.range,
`format('${format.join("")}'${args.join("")})`, `format('${format.join("")}'${args.join("")})`,
token.definitionInfo, token.definitionInfo,
expressionTokens expressionTokens,
undefined
); );
} }
@@ -615,10 +616,10 @@ class TemplateReader {
tr: TokenRange, tr: TokenRange,
rawExpression: string, rawExpression: string,
allowedContext: string[], allowedContext: string[],
token: TemplateToken, token: StringToken,
definitionInfo: DefinitionInfo | undefined definitionInfo: DefinitionInfo | undefined
): ExpressionToken | undefined { ): ExpressionToken | undefined {
const parseExpressionResult = this.parseExpression(tr, rawExpression, allowedContext, definitionInfo); const parseExpressionResult = this.parseExpression(tr, token, rawExpression, allowedContext, definitionInfo);
// Check for error // Check for error
if (parseExpressionResult.error) { if (parseExpressionResult.error) {
@@ -630,7 +631,8 @@ class TemplateReader {
} }
private parseExpression( private parseExpression(
range: TokenRange | undefined, range: TokenRange,
token: StringToken,
value: string, value: string,
allowedContext: string[], allowedContext: string[],
definitionInfo: DefinitionInfo | undefined definitionInfo: DefinitionInfo | undefined
@@ -665,9 +667,31 @@ class TemplateReader {
}; };
} }
const startTrim = value.length - value.trimStart().length;
const endTrim = value.length - value.trimEnd().length;
const expressionRange: TokenRange = {
start: {
...range.start,
column: range.start.column + OPEN_EXPRESSION.length + startTrim
},
end: {
...range.end,
column: range.end.column - CLOSE_EXPRESSION.length - endTrim
}
};
// Return the expression // Return the expression
return <ParseExpressionResult>{ return <ParseExpressionResult>{
expression: new BasicExpressionToken(this._fileId, range, trimmed, definitionInfo, undefined), expression: new BasicExpressionToken(
this._fileId,
range,
trimmed,
definitionInfo,
undefined,
token.source,
expressionRange
),
error: undefined error: undefined
}; };
} }
@@ -11,8 +11,18 @@ import {TokenType} from "./types";
export class BasicExpressionToken extends ExpressionToken { export class BasicExpressionToken extends ExpressionToken {
private readonly expr: string; private readonly expr: string;
public readonly source: string | undefined;
public readonly originalExpressions: BasicExpressionToken[] | undefined; public readonly originalExpressions: BasicExpressionToken[] | undefined;
/**
* The range of the expression within the source string.
*
* `range` is the range of the entire expression, including the `${{` and `}}`. `expression` is only the expression
* without any ${{ }} markers. `expressionRange` is the range of just the expression within the document.
*/
public readonly expressionRange: TokenRange | undefined;
/** /**
* @param originalExpressions If the basic expression was transformed from individual expressions, these will be the original ones * @param originalExpressions If the basic expression was transformed from individual expressions, these will be the original ones
*/ */
@@ -21,11 +31,15 @@ export class BasicExpressionToken extends ExpressionToken {
range: TokenRange | undefined, range: TokenRange | undefined,
expression: string, expression: string,
definitionInfo: DefinitionInfo | undefined, definitionInfo: DefinitionInfo | undefined,
originalExpressions: BasicExpressionToken[] | undefined originalExpressions: BasicExpressionToken[] | undefined,
source: string | undefined,
expressionRange?: TokenRange | undefined
) { ) {
super(TokenType.BasicExpression, file, range, undefined, definitionInfo); super(TokenType.BasicExpression, file, range, undefined, definitionInfo);
this.expr = expression; this.expr = expression;
this.source = source;
this.originalExpressions = originalExpressions; this.originalExpressions = originalExpressions;
this.expressionRange = expressionRange;
} }
public get expression(): string { public get expression(): string {
@@ -34,8 +48,24 @@ export class BasicExpressionToken extends ExpressionToken {
public override clone(omitSource?: boolean): TemplateToken { public override clone(omitSource?: boolean): TemplateToken {
return omitSource return omitSource
? new BasicExpressionToken(undefined, undefined, this.expr, this.definitionInfo, this.originalExpressions) ? new BasicExpressionToken(
: new BasicExpressionToken(this.file, this.range, this.expr, this.definitionInfo, this.originalExpressions); undefined,
undefined,
this.expr,
this.definitionInfo,
this.originalExpressions,
this.source,
this.expressionRange
)
: new BasicExpressionToken(
this.file,
this.range,
this.expr,
this.definitionInfo,
this.originalExpressions,
this.source,
this.expressionRange
);
} }
public override toString(): string { public override toString(): string {
@@ -2,6 +2,7 @@
export type Position = { export type Position = {
/** The one-based line value */ /** The one-based line value */
line: number; line: number;
/** The one-based column value */ /** The one-based column value */
column: number; column: number;
}; };