[WIP] add TSNamespaceExportDeclaration (#1459)

* add TSNamespaceExportDeclaration

* extract ast-types/fork

* add TSEnumDeclaration and TSEnumMember

* add TSImportEqualsDeclaration and TSExternalModuleReference

* add TSInterfaceDeclaration and type annotation to TSMethodSignature

* add TSModuleDeclaration, TSDeclareKeyword, TSModuleBlock and fix TSNamespaceExportDeclaration

* remove workaround
master
Danny Arnold 2017-05-01 18:25:49 +02:00 committed by Christopher Chedeau
parent bff2d48aa8
commit 5ee0385d79
21 changed files with 406 additions and 9 deletions

20
src/ast-types.js Normal file
View File

@ -0,0 +1,20 @@
"use strict";
module.exports = require("ast-types/fork")([
// This core module of AST types captures ES5 as it is parsed today by
// git://github.com/ariya/esprima.git#master.
require("ast-types/def/core"),
// Feel free to add to or remove from this list of extension modules to
// configure the precise type hierarchy that you need.
require("ast-types/def/es6"),
require("ast-types/def/es7"),
require("ast-types/def/mozilla"),
require("ast-types/def/e4x"),
require("ast-types/def/jsx"),
require("ast-types/def/flow"),
require("ast-types/def/esprima"),
require("ast-types/def/babel"),
require("ast-types/def/babel6"),
require("./typescript-ast-nodes.js")
]);

View File

@ -1,7 +1,7 @@
"use strict";
var assert = require("assert");
var types = require("ast-types");
var types = require("./ast-types")
var n = types.namedTypes;
var isArray = types.builtInTypes.array;
var isObject = types.builtInTypes.object;

View File

@ -1,7 +1,7 @@
"use strict";
var assert = require("assert");
var types = require("ast-types");
var types = require("./ast-types")
var util = require("./util");
var n = types.namedTypes;
var isArray = types.builtInTypes.array;
@ -67,9 +67,8 @@ function getNodeHelper(path, count) {
for (var i = s.length - 1; i >= 0; i -= 2) {
var value = s[i];
// Temp: This can be removed when `ast-types` knows that TSNodes are Nodes.
var isTsNode = value && value.type && value.type.startsWith('TS');
if ((isTsNode || n.Node.check(value)) && --count < 0) {
if ((n.Node.check(value)) && --count < 0) {
return value;
}
}

View File

@ -26,7 +26,7 @@ var willBreak = docUtils.willBreak;
var isLineNext = docUtils.isLineNext;
var isEmpty = docUtils.isEmpty;
var types = require("ast-types");
var types = require("./ast-types");
var namedTypes = types.namedTypes;
var isString = types.builtInTypes.string;
@ -721,9 +721,12 @@ function genericPrintNoParens(path, options, print, args) {
case "ObjectExpression":
case "ObjectPattern":
case "ObjectTypeAnnotation":
case "TSInterfaceDeclaration":
case "TSTypeLiteral":
var isTypeAnnotation = n.type === "ObjectTypeAnnotation";
var isTypeScriptTypeAnnotaion = n.type === "TSTypeLiteral";
var isTypeScriptInterfaceDeclaration = n.type === "TSInterfaceDeclaration";
var isTypeScriptType = isTypeScriptTypeAnnotaion || isTypeScriptInterfaceDeclaration;
// Leave this here because we *might* want to make this
// configurable later -- flow accepts ";" for type separators,
// typescript accepts ";" and newlines
@ -733,13 +736,22 @@ function genericPrintNoParens(path, options, print, args) {
var rightBrace = n.exact ? "|}" : "}";
var parent = path.getParentNode(0);
var parentIsUnionTypeAnnotation = parent.type === "UnionTypeAnnotation";
var propertiesField = isTypeScriptTypeAnnotaion
var propertiesField = isTypeScriptType
? "members"
: "properties";
var prefix = ""
if (isTypeAnnotation) {
fields.push("indexers", "callProperties");
}
if (isTypeScriptInterfaceDeclaration) {
prefix = concat([
"interface ",
path.call(print, "name"),
" "
])
}
fields.push(propertiesField);
@ -778,6 +790,7 @@ function genericPrintNoParens(path, options, print, args) {
if (props.length === 0) {
return group(
concat([
prefix,
leftBrace,
comments.printDanglingComments(path, options),
softline,
@ -787,6 +800,7 @@ function genericPrintNoParens(path, options, print, args) {
} else {
return group(
concat([
prefix,
leftBrace,
indent(
align(
@ -2052,12 +2066,123 @@ function genericPrintNoParens(path, options, print, args) {
return concat(parts)
case "TSMethodSignature":
return concat([
parts.push(
path.call(print, 'name'),
"(",
join(", ", path.map(print, "parameters")),
")"
)
if (n.typeAnnotation) {
parts.push(
": ",
path.call(print, "typeAnnotation")
)
}
return concat(parts)
case "TSNamespaceExportDeclaration":
if (n.declaration) {
parts.push(
"export ",
path.call(print, "declaration")
)
} else {
parts.push(
"export as namespace ",
path.call(print, "name")
)
if (options.semi) {
parts.push(";")
}
}
return concat(parts)
case "TSEnumDeclaration":
parts.push(
"enum ",
path.call(print, "name"),
" "
)
if (n.members.length === 0) {
parts.push(
group(
concat([
"{",
comments.printDanglingComments(path, options),
softline,
"}"
])
)
);
} else {
parts.push(
group(
concat([
"{",
options.bracketSpacing ? line : softline,
indent(
concat([
softline,
printArrayItems(path, options, "members", print)
])
),
comments.printDanglingComments(
path,
options,
/* sameIndent */ true
),
softline,
options.bracketSpacing ? line : softline,
"}"
])
)
);
}
return concat(parts);
case "TSEnumMember":
return path.call(print, "name")
case "TSImportEqualsDeclaration":
parts.push(
"import ",
path.call(print, "name"),
" = ",
path.call(print, "moduleReference")
)
if (options.semi) {
parts.push(";")
}
return concat(parts)
case "TSExternalModuleReference":
return concat([
"require(",
path.call(print, "expression"),
")"
])
case "TSModuleDeclaration":
if (n.modifiers) {
parts.push(
join(" ", path.map(print, "modifiers")),
" "
)
}
parts.push(
"module ",
path.call(print, "name"),
" {",
path.call(print, "body"),
"}"
)
return concat(parts)
case "TSDeclareKeyword":
return "declare"
case "TSModuleBlock":
return concat(path.map(print, "body"))
// TODO
case "ClassHeritage":
// TODO

167
src/typescript-ast-nodes.js Normal file
View File

@ -0,0 +1,167 @@
module.exports = function(fork) {
fork.use(require("ast-types/def/es7"));
var types = fork.use(require("ast-types/lib/types"));
var def = types.Type.def;
var or = types.Type.or;
var defaults = fork.use(require("ast-types/lib/shared")).defaults;
// Ambient
def("TSAmbientVariableDefinition").bases("VariableDeclaration");
def("TSInterfaceDeclaration")
.bases("Declaration")
.build("name", "typeParameters", "members")
.field("name", def("Identifier"))
.field(
"typeParameters",
or(def("TypeParameterDeclaration"), null),
defaults["null"]
)
.field("members", [def("TSSignature")]);
// .field("body", def("ObjectTypeAnnotation"))
// .field("extends", [def("InterfaceExtends")]);
def("TSKeyword").bases("Node");
def("TSType").bases("Node");
def("TypeElement").bases("Node");
def("TSSignature")
.bases("TypeElement")
.build("typeParameters", "parameters", "typeAnnotation")
.field(
"typeParameters",
or(def("TypeParameterDeclaration"), null),
defaults["null"]
)
.field("parameters", [def("Identifier")])
.field("typeAnnotation", def("TSType"));
def("TSAnyKeyword").bases("TSKeyword");
def("TSBooleanKeyword").bases("TSKeyword");
def("TSNeverKeyword").bases("TSKeyword");
def("TSNumberKeyword").bases("TSKeyword");
def("TSObjectKeyword").bases("TSKeyword");
def("TSReadonlyKeyword").bases("TSKeyword");
def("TSStringKeyword").bases("TSKeyword");
def("TSSymbolKeyword").bases("TSKeyword");
def("TSUndefinedKeyword").bases("TSKeyword");
def("TSVoidKeyword").bases("TSKeyword");
// Types
def("TSConstructorType").bases("TSType");
def("TSFunctionType").bases("TSType");
def("TSIntersectionType")
.bases("TSType")
.build("types")
.field("types", [def("TSType")]);
def("TSParenthesizedType").bases("TSType");
def("TSThisType").bases("TSType");
def("TSUnionType")
.bases("TSType")
.build("types")
.field("types", [def("TSType")]);
def("TSTypeLiteral")
.bases("TSType")
.build("members")
.field("members", [def("TSSignature")]);
def("TSTypeOperator").bases("TSType");
def("TSTypeReference")
.bases("TSType")
.build("typeName", "typeParameters")
.field("typeName", def("Identifier"))
.field("typeParameters", def("TSType"));
def("TSFirstTypeNode")
.bases("Node")
.build("id", "typeAnnotation")
.field("id", def("Identifier"))
.field("typeAnnotation", def("TSType"));
// Signatures
def("TSCallSignature")
.bases("TSSignature")
.build("typeParameters", "parameters", "typeAnnotation");
def("TSConstructSignature")
.bases("TSSignature")
.build("typeParameters", "parameters", "typeAnnotation");
def("TSIndexSignature")
.bases("TSSignature")
.build("typeParameters", "parameters", "typeAnnotation");
def("TSMethodSignature")
.bases("TSSignature")
.build("name", "typeParameters", "parameters", "typeAnnotation")
.field("name", def("Identifier"));
def("TSPropertySignature")
.bases("TSSignature")
.build("name", "typeAnnotation", "initializer")
.field("name", def("Identifier"))
.field("typeAnnotation", def("TSType"))
.field("initializer", def("Expression"));
def("TSAsExpression").bases("Expression");
def("TSNamespaceExportDeclaration")
.bases("Declaration")
// needs more like `modefiers` and `decorators`
.build("name");
def("TSEnumDeclaration")
.bases("Declaration")
.build("name", "members")
.field("name", def("Identifier"));
def("TSEnumMember").build("name").field("name", def("Identifier"));
def("TSImportEqualsDeclaration")
.build("name", "moduleReference")
.field("name", def("Identifier"))
.field("moduleReference", def("TSExternalModuleReference"));
def("TSImportEqualsDeclaration")
.build("expression")
.field("expression", def("Literal"));
def("TSInterfaceDeclaration")
.build("name", "members")
.field("name", def("Identifier"))
.field("members", [def("TSMethodSignature")]);
def("TSModuleDeclaration")
.build("modifiers", "name", "body")
.bases("Node")
.field("name", or(def("Identifier"), def("Literal")));
def("TSDeclareKeyword").build();
def("TSModuleBlock").build("body");
def("TSAbstractMethodDefinition").build().bases("Node");
def("TSAbstractClassProperty").build("key", "value").bases("Node");
def("TSAbstractClassDeclaration").build().bases("Node");
};

View File

@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`enumDeclaration.ts 1`] = `
enum E { A, B, C }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enum E { A, B, C }
`;

View File

@ -0,0 +1 @@
enum E { A, B, C }

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`importEqualsDeclaration.ts 1`] = `
import glo_m4 = require("glo_m4");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import glo_m4 = require("glo_m4");
`;

View File

@ -0,0 +1 @@
import glo_m4 = require("glo_m4");

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`interfaceDeclaration.ts 1`] = `
interface abstract {
abstract(): void,
concrete(): number
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
interface abstract {
abstract(): void,
concrete(): number
}
`;

View File

@ -0,0 +1,4 @@
interface abstract {
abstract(): void,
concrete(): number
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`moduleDeclaration.ts 1`] = `
module A {
export class A {
}
}
declare module "B" {
export class B {
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
module A {export class A {}}
declare module "B" {export class B {}}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -0,0 +1,9 @@
module A {
export class A {
}
}
declare module "B" {
export class B {
}
}

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`exportAsNamespace.d.ts 1`] = `
// issue: https://github.com/Microsoft/TypeScript/issues/11545
export var X;
export as namespace N
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// issue: https://github.com/Microsoft/TypeScript/issues/11545
export var X;
export as namespace N;
`;

View File

@ -0,0 +1,4 @@
// issue: https://github.com/Microsoft/TypeScript/issues/11545
export var X;
export as namespace N

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -2,7 +2,7 @@
const fs = require("fs");
const prettier = require("../");
const types = require("ast-types");
const types = require("../src/ast-types");
const parser = require("../src/parser");
const RUN_AST_TESTS = process.env["AST_COMPARE"];