diff --git a/.changeset/cuddly-boats-slide.md b/.changeset/cuddly-boats-slide.md new file mode 100644 index 0000000000..6ef7582a1c --- /dev/null +++ b/.changeset/cuddly-boats-slide.md @@ -0,0 +1,5 @@ +--- +'@lit-labs/analyzer': patch +--- + +Adjust attribute source locations in template parser diff --git a/packages/labs/analyzer/src/lib/lit/template.ts b/packages/labs/analyzer/src/lib/lit/template.ts index 996f0ed8c1..d33bf14bfb 100644 --- a/packages/labs/analyzer/src/lib/lit/template.ts +++ b/packages/labs/analyzer/src/lib/lit/template.ts @@ -419,7 +419,14 @@ export const parseLitTemplate = ( if (node.attrs.length > 0) { for (const attr of node.attrs) { - // TODO (justinfagnani): adjust attribute locations + const attrSourceLocation = + node.sourceCodeLocation?.attrs?.[attr.name]; + + if (attrSourceLocation !== undefined) { + attrSourceLocation.startLine += lineAdjust; + attrSourceLocation.startCol += colAdjust; + attrSourceLocation.startOffset += offsetAdjust; + } if (attr.name.startsWith(marker)) { // An element binding, like
@@ -515,6 +522,12 @@ export const parseLitTemplate = ( ); spanIndex += strings.length - 1; } + + if (attrSourceLocation !== undefined) { + attrSourceLocation.endLine += lineAdjust; + attrSourceLocation.endCol += colAdjust; + attrSourceLocation.endOffset += offsetAdjust; + } } } diff --git a/packages/labs/analyzer/src/test/server/lit/template_test.ts b/packages/labs/analyzer/src/test/server/lit/template_test.ts index 478574c741..080d8d656f 100644 --- a/packages/labs/analyzer/src/test/server/lit/template_test.ts +++ b/packages/labs/analyzer/src/test/server/lit/template_test.ts @@ -193,6 +193,27 @@ const assertTemplateNodeText = ( assert.equal(elementTextFromLinesAndCols, expected); }; +const assertAttributeText = ( + node: Element, + attrName: string, + templateExpression: ts.TaggedTemplateExpression, + expected: string +) => { + // Trim off the leading and trailing backticks + const templateText = templateExpression.template.getFullText().slice(1, -1); + assert.ok(node.sourceCodeLocation?.attrs); + const sourceLocation = node.sourceCodeLocation?.attrs?.[attrName]; + assert.ok( + sourceLocation, + `source location for attribute not found: ${attrName}` + ); + const {startOffset, endOffset} = sourceLocation; + + // Check that the offsets are correct: + const textFromOffsets = templateText.substring(startOffset, endOffset); + assert.equal(textFromOffsets, expected); +}; + suite('parseLitTemplate', () => { const testFilePath = path.resolve(testFilesDir, 'hello.ts'); const {sourceFile, checker} = getTestSourceFile(testFilePath); @@ -325,6 +346,13 @@ suite('parseLitTemplate', () => { `
Hello, world!
` ); + assertAttributeText( + div as Element, + 'class$lit$', + templateExpression, + `class="\${'a'}"` + ); + const span = (div as Element).childNodes[0]; assert.equal(span.nodeName, 'span'); assertTemplateNodeText(