Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/little-corners-open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'typescript-svelte-plugin': patch
'svelte-language-server': patch
'svelte-check': patch
---

perf: various optimization with ast walk
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export class SemanticTokensProviderImpl implements SemanticTokensProvider {

const startOffset = document.offsetAt(startPosition);
const endOffset = document.offsetAt(endPosition);
const originalText = document.getText();

// Ensure components in the template get no semantic highlighting
if (
Expand All @@ -139,9 +140,9 @@ export class SemanticTokensProviderImpl implements SemanticTokensProvider {
classificationType === TokenType.parameter ||
classificationType === TokenType.variable ||
classificationType === TokenType.function) &&
snapshot.svelteNodeAt(startOffset)?.type === 'InlineComponent' &&
(document.getText().charCodeAt(startOffset - 1) === /* < */ 60 ||
document.getText().charCodeAt(startOffset - 1) === /* / */ 47)
(originalText.charCodeAt(startOffset - 1) === /* < */ 60 ||
originalText.charCodeAt(startOffset - 1) === /* / */ 47) &&
snapshot.svelteNodeAt(startOffset)?.type === 'InlineComponent'
) {
return;
}
Expand Down
40 changes: 19 additions & 21 deletions packages/language-server/src/plugins/typescript/features/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,23 +189,20 @@ export function findContainingNode<T extends ts.Node>(
textSpan: ts.TextSpan,
predicate: (node: ts.Node) => node is T
): T | undefined {
const children = node.getChildren();
const end = textSpan.start + textSpan.length;

for (const child of children) {
if (!(child.getStart() <= textSpan.start && child.getEnd() >= end)) {
continue;
}

if (predicate(child)) {
return child;
}

const foundInChildren = findContainingNode(child, textSpan, predicate);
if (foundInChildren) {
return foundInChildren;
// TypeScript will re-parse part of the file in getChildren() to include syntax tokens.
// But for the use cases of this function, we only need the actual nodes like Identifier.
// the forEachChild name is a bit misleading too because it function more like find than forEach
return node.forEachChild((child) => {
if (child.getStart() <= textSpan.start && child.getEnd() >= textSpan.start) {
if (predicate(child)) {
return child;
}
const foundInChildren = findContainingNode(child, textSpan, predicate);
if (foundInChildren) {
return foundInChildren;
}
}
}
});
}

export function findClosestContainingNode<T extends ts.Node>(
Expand Down Expand Up @@ -242,15 +239,15 @@ export function findNodeAtSpan<T extends ts.Node>(

const end = start + length;

for (const child of node.getChildren()) {
return node.forEachChild((child) => {
const childStart = child.getStart();
if (end <= childStart) {
return;
}

const childEnd = child.getEnd();
if (start >= childEnd) {
continue;
return;
}

if (start === childStart && end === childEnd) {
Expand All @@ -266,7 +263,7 @@ export function findNodeAtSpan<T extends ts.Node>(
if (foundInChildren) {
return foundInChildren;
}
}
});
}

function isSomeAncestor(node: ts.Node, predicate: NodePredicate) {
Expand Down Expand Up @@ -349,9 +346,9 @@ export function gatherDescendants<T extends ts.Node>(
if (predicate(node)) {
dest.push(node);
} else {
for (const child of node.getChildren()) {
node.forEachChild((child) => {
gatherDescendants(child, predicate, dest);
}
});
}
return dest;
}
Expand Down Expand Up @@ -416,6 +413,7 @@ export function getQuotePreference(
: double;
}
export function findChildOfKind(node: ts.Node, kind: ts.SyntaxKind): ts.Node | undefined {
// this one we do want to use getChildren() because we also want to find syntax tokens,
for (const child of node.getChildren()) {
if (child.kind === kind) {
return child;
Expand Down
16 changes: 8 additions & 8 deletions packages/typescript-plugin/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ export function findNodeAtSpan<T extends ts.Node>(

const end = start + length;

for (const child of node.getChildren()) {
return node.forEachChild((child) => {
const childStart = child.getStart();
if (end <= childStart) {
return;
}

const childEnd = child.getEnd();
if (start >= childEnd) {
continue;
return;
}

if (start === childStart && end === childEnd) {
Expand All @@ -133,7 +133,7 @@ export function findNodeAtSpan<T extends ts.Node>(
if (foundInChildren) {
return foundInChildren;
}
}
});
}

/**
Expand All @@ -144,15 +144,15 @@ export function findNodeAtPosition<T extends ts.Node>(
pos: number,
predicate?: NodeTypePredicate<T>
): T | void {
for (const child of node.getChildren()) {
return node.forEachChild((child) => {
const childStart = child.getStart();
if (pos < childStart) {
return;
}

const childEnd = child.getEnd();
if (pos > childEnd) {
continue;
return;
}

const foundInChildren = findNodeAtPosition(child, pos, predicate);
Expand All @@ -166,7 +166,7 @@ export function findNodeAtPosition<T extends ts.Node>(
if (predicate(child)) {
return child;
}
}
});
}

/**
Expand Down Expand Up @@ -204,9 +204,9 @@ export function gatherDescendants<T extends ts.Node>(
if (predicate(node)) {
dest.push(node);
} else {
for (const child of node.getChildren()) {
node.forEachChild((child) => {
gatherDescendants(child, predicate, dest);
}
});
}
return dest;
}
Expand Down