mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-10-28 16:36:04 +08:00
[api] Add hasTrailingComma getter in the RemoteNodeList class (#63957)
Signed-off-by: mrazauskas <tom@mrazauskas.de>
This commit is contained in:
1 parent
5739027c9a
commit
3276240332
9 files changed
+67
-12
No files matched your search
@@ -267,7 +267,7 @@ export function encodeNode(node: Node): Uint8Array {
|
||||
0, // next
|
||||
parentIndex,
|
||||
list.length, // data for NodeList is its length
|
||||
0, // flags
|
||||
list.hasTrailingComma ? 1 : 0, // NodeLists have no AST flags; this slot is reused for hasTrailingComma
|
||||
);
|
||||
|
||||
const saveParentIndex = parentIndex;
|
||||
|
||||
@@ -43,7 +43,6 @@ export class RemoteNodeList extends Array<RemoteNode> implements NodeArray<Remot
|
||||
}
|
||||
|
||||
parent: RemoteNode;
|
||||
hasTrailingComma?: boolean;
|
||||
transformFlags: number = 0;
|
||||
protected view: DataView;
|
||||
protected index: number;
|
||||
@@ -71,6 +70,10 @@ export class RemoteNodeList extends Array<RemoteNode> implements NodeArray<Remot
|
||||
return this.view.getUint32(this._byteIndex + NODE_OFFSET_DATA, true);
|
||||
}
|
||||
|
||||
get hasTrailingComma(): boolean {
|
||||
return (this.view.getUint32(this._byteIndex + NODE_OFFSET_FLAGS, true) & 1) !== 0;
|
||||
}
|
||||
|
||||
private sourceFile: SourceFileInfo;
|
||||
|
||||
constructor(view: DataView, index: number, parent: RemoteNode, sourceFile: SourceFileInfo, offsetNodes: number) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const PROTOCOL_VERSION = 7;
|
||||
export const PROTOCOL_VERSION = 8;
|
||||
|
||||
export const HEADER_OFFSET_METADATA = 0;
|
||||
export const HEADER_OFFSET_HASH_LO0 = 4;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getSynthesizedDeepClone,
|
||||
InternalSymbolName,
|
||||
isCallExpression,
|
||||
isExpressionStatement,
|
||||
isFunctionDeclaration,
|
||||
isIdentifier,
|
||||
isImportDeclaration,
|
||||
@@ -1236,6 +1237,29 @@ describe("SourceFile", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("NodeArray", () => {
|
||||
test("hasTrailingComma", async () => {
|
||||
const api = spawnAPI({
|
||||
"/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true } }),
|
||||
"/src/main.ts": `declare function foo(...args: any): void;\nfoo("a", "b",);\nfoo("a", "b");`,
|
||||
});
|
||||
try {
|
||||
const snapshot = await api.updateSnapshot({ openProject: "/tsconfig.json" });
|
||||
const project = snapshot.getProject("/tsconfig.json")!;
|
||||
const sourceFile = await project.program.getSourceFile("/src/main.ts");
|
||||
assert.ok(sourceFile);
|
||||
const statements = sourceFile.statements.filter(isExpressionStatement);
|
||||
assert.ok(isCallExpression(statements[0].expression));
|
||||
assert.equal(statements[0].expression.arguments.hasTrailingComma, true);
|
||||
assert.ok(isCallExpression(statements[1].expression));
|
||||
assert.equal(statements[1].expression.arguments.hasTrailingComma, false);
|
||||
}
|
||||
finally {
|
||||
await api.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("unicode escapes", async () => {
|
||||
const api = spawnAPI({
|
||||
"/tsconfig.json": "{}",
|
||||
|
||||
@@ -67,7 +67,7 @@ describe("Encoder", () => {
|
||||
// Verify header
|
||||
const view = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength);
|
||||
const metadata = view.getUint32(0, true);
|
||||
assert.strictEqual(metadata >>> 24, 7, "protocol version should be 7");
|
||||
assert.strictEqual(metadata >>> 24, 8, "protocol version should be 8");
|
||||
|
||||
// Verify we can decode it
|
||||
const decoded = decode(encoded);
|
||||
@@ -179,11 +179,11 @@ describe("Encoder", () => {
|
||||
assert.strictEqual(rootKind, SyntaxKind.IfStatement);
|
||||
});
|
||||
|
||||
test("protocol version is 7", () => {
|
||||
test("protocol version is 8", () => {
|
||||
const sf = makeSF("", "/test.ts", []);
|
||||
const encoded = encodeSourceFile(sf);
|
||||
const view = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength);
|
||||
assert.strictEqual(view.getUint32(0, true) >>> 24, 7);
|
||||
assert.strictEqual(view.getUint32(0, true) >>> 24, 8);
|
||||
});
|
||||
|
||||
test("encodes source files without content mapping metadata", () => {
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
getSynthesizedDeepClone,
|
||||
InternalSymbolName,
|
||||
isCallExpression,
|
||||
isExpressionStatement,
|
||||
isFunctionDeclaration,
|
||||
isIdentifier,
|
||||
isImportDeclaration,
|
||||
@@ -1152,6 +1153,29 @@ describe("SourceFile", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("NodeArray", () => {
|
||||
test("hasTrailingComma", () => {
|
||||
const api = spawnAPI({
|
||||
"/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true } }),
|
||||
"/src/main.ts": `declare function foo(...args: any): void;\nfoo("a", "b",);\nfoo("a", "b");`,
|
||||
});
|
||||
try {
|
||||
const snapshot = api.updateSnapshot({ openProject: "/tsconfig.json" });
|
||||
const project = snapshot.getProject("/tsconfig.json")!;
|
||||
const sourceFile = project.program.getSourceFile("/src/main.ts");
|
||||
assert.ok(sourceFile);
|
||||
const statements = sourceFile.statements.filter(isExpressionStatement);
|
||||
assert.ok(isCallExpression(statements[0].expression));
|
||||
assert.equal(statements[0].expression.arguments.hasTrailingComma, true);
|
||||
assert.ok(isCallExpression(statements[1].expression));
|
||||
assert.equal(statements[1].expression.arguments.hasTrailingComma, false);
|
||||
}
|
||||
finally {
|
||||
api.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("unicode escapes", () => {
|
||||
const api = spawnAPI({
|
||||
"/tsconfig.json": "{}",
|
||||
|
||||
@@ -1518,7 +1518,6 @@ function emitRemoteNodeList(w: CodeWriter) {
|
||||
w.write(` }`);
|
||||
w.write(``);
|
||||
w.write(` parent: RemoteNode;`);
|
||||
w.write(` hasTrailingComma?: boolean;`);
|
||||
w.write(` transformFlags: number = 0;`);
|
||||
w.write(` protected view: DataView;`);
|
||||
w.write(` protected index: number;`);
|
||||
@@ -1546,6 +1545,10 @@ function emitRemoteNodeList(w: CodeWriter) {
|
||||
w.write(` return this.view.getUint32(this._byteIndex + NODE_OFFSET_DATA, true);`);
|
||||
w.write(` }`);
|
||||
w.write(``);
|
||||
w.write(` get hasTrailingComma(): boolean {`);
|
||||
w.write(` return (this.view.getUint32(this._byteIndex + NODE_OFFSET_FLAGS, true) & 1) !== 0;`);
|
||||
w.write(` }`);
|
||||
w.write(``);
|
||||
w.write(` private sourceFile: SourceFileInfo;`);
|
||||
w.write(``);
|
||||
w.write(` constructor(view: DataView, index: number, parent: RemoteNode, sourceFile: SourceFileInfo, offsetNodes: number) {`);
|
||||
|
||||
@@ -63,7 +63,7 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
ProtocolVersion uint8 = 7
|
||||
ProtocolVersion uint8 = 8
|
||||
)
|
||||
|
||||
// Source File Binary Format
|
||||
@@ -202,7 +202,8 @@ const (
|
||||
// NodeLists are represented as normal nodes with the special `kind` value `0xff_ff_ff_ff`. They are considered the parent
|
||||
// of their contents in the encoded format. A client reconstructing an AST similar to TypeScript's internal representation
|
||||
// should instead set the `parent` pointers of a NodeList's children to the NodeList's parent. A NodeList's `data` field
|
||||
// is the uint32 length of the list, and does not use one of the data types described below.
|
||||
// is the uint32 length of the list, and does not use one of the data types described below. A NodeList's `flags` field
|
||||
// is not used for AST node flags (NodeLists have none); bit 0 instead encodes `HasTrailingComma`.
|
||||
//
|
||||
// For node types other than NodeList, the node data field encodes one of the following, determined by the first 2 bits of
|
||||
// the field:
|
||||
@@ -502,7 +503,7 @@ func encodeTree(rootNode *ast.Node, sourceFile *ast.SourceFile) ([]byte, *NodeIn
|
||||
nodes[prevIndex*NodeSize+NodeOffsetNext+3] = b3
|
||||
}
|
||||
|
||||
nodes = appendUint32s(nodes, SyntaxKindNodeList, utf16(nodeList.Pos()), utf16(nodeList.End()), 0, parentIndex, uint32(len(nodeList.Nodes)), 0)
|
||||
nodes = appendUint32s(nodes, SyntaxKindNodeList, utf16(nodeList.Pos()), utf16(nodeList.End()), 0, parentIndex, uint32(len(nodeList.Nodes)), uint32(boolToByte(nodeList.HasTrailingComma())))
|
||||
|
||||
saveParentIndex := parentIndex
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ func TestEncodeSourceFile(t *testing.T) {
|
||||
|
||||
func TestEncodeContentMapperSourceFileMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
if encoder.ProtocolVersion != 7 {
|
||||
t.Fatalf("protocol version = %d, want 7", encoder.ProtocolVersion)
|
||||
if encoder.ProtocolVersion != 8 {
|
||||
t.Fatalf("protocol version = %d, want 8", encoder.ProtocolVersion)
|
||||
}
|
||||
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
|
||||
FileName: "/component.vue",
|
||||
|
||||
Reference in new issue
Block a user