-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This includes handling for trailing commas.
- Loading branch information
1 parent
ffa7bfa
commit af9442a
Showing
5 changed files
with
259 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import * as ts from "typescript"; | ||
|
||
export function getNextSibling(node: ts.Node): ts.Node | null { | ||
const parent = node.parent; | ||
if (!parent) { | ||
return null; | ||
} | ||
|
||
const syntaxList = findContainingSyntaxList(node); | ||
|
||
if (syntaxList) { | ||
const children = syntaxList.getChildren(); | ||
const nodeIndex = children.indexOf(node); | ||
|
||
if (nodeIndex === -1) { | ||
throw new Error('Node not found among SyntaxList\'s children.'); | ||
} | ||
|
||
// If the node is the last child in the SyntaxList, recursively check the parent's next sibling | ||
if (nodeIndex === 0) { | ||
const parentNextSibling = getNextSibling(parent); | ||
if (!parentNextSibling) { | ||
return null; | ||
} | ||
|
||
// Return the first child of the parent's next sibling | ||
const parentSyntaxList = findContainingSyntaxList(parentNextSibling); | ||
if (parentSyntaxList) { | ||
const siblings = parentSyntaxList.getChildren(); | ||
return siblings[0] || null; | ||
} else { | ||
return parentNextSibling; | ||
} | ||
} | ||
|
||
// Otherwise, return the next sibling in the SyntaxList | ||
return children[nodeIndex + 1]; | ||
} | ||
|
||
const parentChildren = parent.getChildren(); | ||
const nodeIndex = parentChildren.indexOf(node); | ||
|
||
if (nodeIndex === -1) { | ||
throw new Error('Node not found among parent\'s children.'); | ||
} | ||
|
||
// If the node is the last child, recursively check the parent's next sibling | ||
if (nodeIndex === parentChildren.length - 1) { | ||
const parentNextSibling = getNextSibling(parent); | ||
if (!parentNextSibling) { | ||
return null; | ||
} | ||
|
||
// Return the last child of the parent's previous sibling | ||
const siblings = parentNextSibling.getChildren(); | ||
return siblings[0] || null; | ||
} | ||
|
||
// Otherwise, return the next sibling | ||
return parentChildren[nodeIndex + 1]; | ||
} | ||
|
||
export function getPreviousSibling(node: ts.Node): ts.Node | null { | ||
const parent = node.parent; | ||
if (!parent) { | ||
return null; | ||
} | ||
|
||
const syntaxList = findContainingSyntaxList(node); | ||
|
||
if (syntaxList) { | ||
const children = syntaxList.getChildren(); | ||
const nodeIndex = children.indexOf(node); | ||
|
||
if (nodeIndex === -1) { | ||
throw new Error('Node not found among SyntaxList\'s children.'); | ||
} | ||
|
||
// If the node is the first child in the SyntaxList, recursively check the parent's previous sibling | ||
if (nodeIndex === 0) { | ||
const parentPreviousSibling = getPreviousSibling(parent); | ||
if (!parentPreviousSibling) { | ||
return null; | ||
} | ||
|
||
// Return the last child of the parent's previous sibling | ||
const parentSyntaxList = findContainingSyntaxList(parentPreviousSibling); | ||
if (parentSyntaxList) { | ||
const siblings = parentSyntaxList.getChildren(); | ||
return siblings[siblings.length - 1] || null; | ||
} else { | ||
return parentPreviousSibling; | ||
} | ||
} | ||
|
||
// Otherwise, return the previous sibling in the SyntaxList | ||
return children[nodeIndex - 1]; | ||
} | ||
|
||
const parentChildren = parent.getChildren(); | ||
const nodeIndex = parentChildren.indexOf(node); | ||
|
||
if (nodeIndex === -1) { | ||
throw new Error('Node not found among parent\'s children.'); | ||
} | ||
|
||
// If the node is the first child, recursively check the parent's previous sibling | ||
if (nodeIndex === 0) { | ||
const parentPreviousSibling = getPreviousSibling(parent); | ||
if (!parentPreviousSibling) { | ||
return null; | ||
} | ||
|
||
// Return the last child of the parent's previous sibling | ||
const siblings = parentPreviousSibling.getChildren(); | ||
return siblings[siblings.length - 1] || null; | ||
} | ||
|
||
// Otherwise, return the previous sibling | ||
return parentChildren[nodeIndex - 1]; | ||
} | ||
|
||
function findContainingSyntaxList(node: ts.Node): ts.SyntaxList | null { | ||
const parent = node.parent; | ||
if (!parent) { | ||
return null; | ||
} | ||
|
||
const children = parent.getChildren(); | ||
for (const child of children) { | ||
if (child.kind == ts.SyntaxKind.SyntaxList && child.getChildren().includes(node)) { | ||
return child as ts.SyntaxList; | ||
} | ||
} | ||
|
||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import {connect, disconnect, javaScript, rewriteRun} from '../testHarness'; | ||
|
||
describe('new mapping', () => { | ||
beforeAll(() => connect()); | ||
afterAll(() => disconnect()); | ||
|
||
test('simple', () => { | ||
rewriteRun( | ||
//language=typescript | ||
javaScript('new Uint8Array(1)') | ||
); | ||
}); | ||
|
||
test('space', () => { | ||
rewriteRun( | ||
//language=typescript | ||
javaScript('new Uint8Array/*1*/(/*2*/1/*3*/)/*4*/') | ||
); | ||
}); | ||
|
||
test('multiple', () => { | ||
rewriteRun( | ||
//language=typescript | ||
javaScript('new Date(2023, 9, 25, 10, 30, 15, 500)') | ||
); | ||
}); | ||
|
||
test('trailing comma', () => { | ||
rewriteRun( | ||
//language=typescript | ||
javaScript('new Uint8Array(1 , )') | ||
); | ||
}); | ||
}); |