Skip to content

Commit 546d4e7

Browse files
authored
v0.9.14: variable resolution perf improvements, files provenance lineage
2 parents 36f060b + 80e6602 commit 546d4e7

16 files changed

Lines changed: 1613 additions & 993 deletions

File tree

‎apps/sim/executor/variables/resolver.ts‎

Lines changed: 134 additions & 82 deletions
Large diffs are not rendered by default.

‎apps/sim/lib/execution/code-placeholders/compiler.test.ts‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,3 +1611,17 @@ describe('compiler failure classification', () => {
16111611
).rejects.toBeInstanceOf(CodePlaceholderCompileError)
16121612
})
16131613
})
1614+
1615+
describe('python keyword lookback', () => {
1616+
it('terminates when the only keyword match on the line sits inside a string', async () => {
1617+
const compiled = await compileCodePlaceholders({
1618+
code: 'x = """\nlambda""" + {{A}}\n',
1619+
language: CodeLanguage.Python,
1620+
params: { A: 'v' },
1621+
})
1622+
1623+
expect(compiled.code).toBe(
1624+
`x = """\nlambda""" + (${compiled.bindings[0].name} if True else None)\n`
1625+
)
1626+
})
1627+
})

‎apps/sim/lib/execution/code-placeholders/javascript.ts‎

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
applySourceEdits,
44
CodePlaceholderCompileError,
55
createCodePlaceholderCompilationContext,
6-
isOffsetInRanges,
6+
createOffsetRangeLookup,
7+
partitionPoint,
78
type SourceEdit,
89
} from '@/lib/execution/code-placeholders/shared'
910
import type {
@@ -357,27 +358,32 @@ function collectAnnexBHtmlCommentRanges(
357358
source: string,
358359
sourceFile: ts.SourceFile
359360
): AnnexBHtmlCommentRange[] {
360-
const protectedRanges = [
361+
const isProtected = createOffsetRangeLookup([
361362
...collectStandardCommentRanges(source, sourceFile),
362363
...collectJavaScriptLiteralRanges(sourceFile),
363-
]
364+
])
364365
const ranges: AnnexBHtmlCommentRange[] = []
365366

367+
// Reused across lines: searching from every line start rescans to EOF when no marker exists.
368+
let nextOpenMarker = source.indexOf('<!--')
366369
let lineStart = 0
367370
while (lineStart < source.length) {
368371
const newline = source.indexOf('\n', lineStart)
369372
const lineEnd = newline === -1 ? source.length : newline
370373
const leadingWhitespace = /^\s*/.exec(source.slice(lineStart, lineEnd))?.[0].length ?? 0
371374
const closeMarker = lineStart + leadingWhitespace
372-
if (source.startsWith('-->', closeMarker) && !isOffsetInRanges(closeMarker, protectedRanges)) {
375+
if (source.startsWith('-->', closeMarker) && !isProtected(closeMarker)) {
373376
ranges.push({ start: closeMarker, end: lineEnd, markerLength: 3 })
374377
lineStart = newline === -1 ? source.length : newline + 1
375378
continue
376379
}
377380

378-
let openMarker = source.indexOf('<!--', lineStart)
381+
if (nextOpenMarker !== -1 && nextOpenMarker < lineStart) {
382+
nextOpenMarker = source.indexOf('<!--', lineStart)
383+
}
384+
let openMarker = nextOpenMarker
379385
while (openMarker >= 0 && openMarker < lineEnd) {
380-
if (!isOffsetInRanges(openMarker, protectedRanges)) {
386+
if (!isProtected(openMarker)) {
381387
ranges.push({ start: openMarker, end: lineEnd, markerLength: 4 })
382388
break
383389
}
@@ -714,10 +720,10 @@ export async function compileJavaScriptPlaceholders(
714720
ts.ScriptKind.JS
715721
)
716722
if (!input.analysisOnly) assertSyntacticallyValidJavaScript(source, input.code, sourceFile)
717-
const commentRanges: Array<[number, number]> = [
723+
const isInComment = createOffsetRangeLookup([
718724
...collectStandardCommentRanges(parserSource, sourceFile),
719725
...htmlCommentRanges.map(({ start, end }) => [start, end] as [number, number]),
720-
]
726+
])
721727
const itemByRange = new Map(
722728
sentinelOccurrences.map((item) => [`${item.occurrence.start}:${item.occurrence.end}`, item])
723729
)
@@ -757,12 +763,19 @@ export async function compileJavaScriptPlaceholders(
757763
if (ts.isTemplateExpression(node.template)) {
758764
for (const span of node.template.templateSpans) visit(span.expression)
759765
}
760-
const nestedEdits = edits.splice(nestedEditStart)
766+
// A stable sort: applySourceEdits keeps input order among edits with equal bounds.
767+
const nestedEdits = edits
768+
.splice(nestedEditStart)
769+
.sort((left, right) => left.start - right.start)
761770
const transformedNodeText = (child: ts.Node): string => {
762771
const childStart = child.getStart(sourceFile)
763772
const childEnd = child.getEnd()
764773
const childEdits = nestedEdits
765-
.filter((edit) => edit.start >= childStart && edit.end <= childEnd)
774+
.slice(
775+
partitionPoint(nestedEdits, (edit) => edit.start < childStart),
776+
partitionPoint(nestedEdits, (edit) => edit.start <= childEnd)
777+
)
778+
.filter((edit) => edit.end <= childEnd)
766779
.map((edit) => ({
767780
...edit,
768781
start: edit.start - childStart,
@@ -873,7 +886,7 @@ export async function compileJavaScriptPlaceholders(
873886

874887
if (ts.isIdentifier(node)) {
875888
const item = itemByRange.get(`${node.getStart(sourceFile)}:${node.getEnd()}`)
876-
if (!item || isOffsetInRanges(item.occurrence.start, commentRanges)) return
889+
if (!item || isInComment(item.occurrence.start)) return
877890
const resolved = context.resolve(item.occurrence)
878891
if (!resolved) return
879892
if (isDeclarationIdentifier(node) || isWriteIdentifier(node)) {
@@ -919,7 +932,7 @@ export async function compileJavaScriptPlaceholders(
919932
visit(sourceFile)
920933

921934
for (const item of sentinelOccurrences) {
922-
if (isOffsetInRanges(item.occurrence.start, commentRanges)) continue
935+
if (isInComment(item.occurrence.start)) continue
923936
if (!context.hasValue(item.occurrence.name) || consumed.has(item.occurrence)) continue
924937
rejectUnsupported(item, 'this JavaScript syntax position')
925938
}

0 commit comments

Comments
 (0)