Skip to content

Commit

Permalink
Initial support for default imports/exports, see #98
Browse files Browse the repository at this point in the history
Does not implement combinations like 'import theDefault, *' yet
  • Loading branch information
dcodeIO committed Jun 4, 2019
1 parent 27e54ed commit fa66738
Show file tree
Hide file tree
Showing 20 changed files with 310 additions and 47 deletions.
3 changes: 0 additions & 3 deletions lib/lint/base.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@
"no-debugger": {
"severity": "error"
},
"no-default-export": {
"severity": "error"
},
"no-duplicate-super": {
"severity": "error"
},
Expand Down
19 changes: 19 additions & 0 deletions src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export enum NodeKind {
DO,
EMPTY,
EXPORT,
EXPORTDEFAULT,
EXPORTIMPORT,
EXPRESSION,
FOR,
Expand Down Expand Up @@ -701,6 +702,16 @@ export abstract class Node {
return stmt;
}

static createExportDefaultStatement(
declaration: DeclarationStatement,
range: Range
): ExportDefaultStatement {
var stmt = new ExportDefaultStatement();
stmt.declaration = declaration;
stmt.range = range;
return stmt;
}

static createExportImportStatement(
name: IdentifierExpression,
externalName: IdentifierExpression,
Expand Down Expand Up @@ -1775,6 +1786,14 @@ export class ExportStatement extends Statement {
isDeclare: bool;
}

/** Represents an `export default` statement. */
export class ExportDefaultStatement extends Statement {
kind = NodeKind.EXPORTDEFAULT;

/** Declaration being exported as default. */
declaration: DeclarationStatement;
}

/** Represents an expression that is used as a statement. */
export class ExpressionStatement extends Statement {
kind = NodeKind.EXPRESSION;
Expand Down
6 changes: 5 additions & 1 deletion src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ import {

nodeIsConstantValue,
findDecorator,
isTypeOmitted
isTypeOmitted,
ExportDefaultStatement
} from "./ast";

import {
Expand Down Expand Up @@ -1619,6 +1620,9 @@ export class Compiler extends DiagnosticEmitter {
// === Statements ===============================================================================

compileTopLevelStatement(statement: Statement, body: ExpressionRef[]): void {
if (statement.kind == NodeKind.EXPORTDEFAULT) {
statement = (<ExportDefaultStatement>statement).declaration;
}
switch (statement.kind) {
case NodeKind.CLASSDECLARATION: {
let memberStatements = (<ClassDeclaration>statement).members;
Expand Down
2 changes: 2 additions & 0 deletions src/diagnosticMessages.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export enum DiagnosticCode {
Type_expected = 1110,
A_default_clause_cannot_appear_more_than_once_in_a_switch_statement = 1113,
Duplicate_label_0 = 1114,
An_export_assignment_cannot_have_modifiers = 1120,
Octal_literals_are_not_allowed_in_strict_mode = 1121,
Digit_expected = 1124,
Hexadecimal_digit_expected = 1125,
Expand Down Expand Up @@ -204,6 +205,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
case 1110: return "Type expected.";
case 1113: return "A 'default' clause cannot appear more than once in a 'switch' statement.";
case 1114: return "Duplicate label '{0}'.";
case 1120: return "An export assignment cannot have modifiers.";
case 1121: return "Octal literals are not allowed in strict mode.";
case 1124: return "Digit expected.";
case 1125: return "Hexadecimal digit expected.";
Expand Down
1 change: 1 addition & 0 deletions src/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"Type expected.": 1110,
"A 'default' clause cannot appear more than once in a 'switch' statement.": 1113,
"Duplicate label '{0}'.": 1114,
"An export assignment cannot have modifiers.": 1120,
"Octal literals are not allowed in strict mode.": 1121,
"Digit expected.": 1124,
"Hexadecimal digit expected.": 1125,
Expand Down
74 changes: 63 additions & 11 deletions src/extra/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
EmptyStatement,
ExportImportStatement,
ExportStatement,
ExportDefaultStatement,
ExpressionStatement,
ForStatement,
IfStatement,
Expand Down Expand Up @@ -230,6 +231,10 @@ export class ASTBuilder {
this.visitExportStatement(<ExportStatement>node);
break;
}
case NodeKind.EXPORTDEFAULT: {
this.visitExportDefaultStatement(<ExportDefaultStatement>node);
break;
}
case NodeKind.EXPORTIMPORT: {
this.visitExportImportStatement(<ExportImportStatement>node);
break;
Expand Down Expand Up @@ -851,15 +856,19 @@ export class ASTBuilder {
}
}

visitClassDeclaration(node: ClassDeclaration): void {
visitClassDeclaration(node: ClassDeclaration, isDefault: bool = false): void {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
this.serializeExternalModifiers(node);
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
}
if (node.is(CommonFlags.ABSTRACT)) sb.push("abstract ");
if (node.name.text.length) {
sb.push("class ");
Expand Down Expand Up @@ -931,9 +940,13 @@ export class ASTBuilder {
visitEmptyStatement(node: EmptyStatement): void {
}

visitEnumDeclaration(node: EnumDeclaration): void {
visitEnumDeclaration(node: EnumDeclaration, isDefault: bool = false): void {
var sb = this.sb;
this.serializeExternalModifiers(node);
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
}
if (node.is(CommonFlags.CONST)) sb.push("const ");
sb.push("enum ");
this.visitIdentifierExpression(node.name);
Expand Down Expand Up @@ -1011,6 +1024,33 @@ export class ASTBuilder {
sb.push(";");
}

visitExportDefaultStatement(node: ExportDefaultStatement): void {
var declaration = node.declaration;
switch (declaration.kind) {
case NodeKind.ENUMDECLARATION: {
this.visitEnumDeclaration(<EnumDeclaration>declaration, true);
break;
}
case NodeKind.FUNCTIONDECLARATION: {
this.visitFunctionDeclaration(<FunctionDeclaration>declaration, true);
break;
}
case NodeKind.CLASSDECLARATION: {
this.visitClassDeclaration(<ClassDeclaration>declaration, true);
break;
}
case NodeKind.INTERFACEDECLARATION: {
this.visitInterfaceDeclaration(<InterfaceDeclaration>declaration, true);
break;
}
case NodeKind.NAMESPACEDECLARATION: {
this.visitNamespaceDeclaration(<NamespaceDeclaration>declaration, true);
break;
}
default: assert(false);
}
}

visitExpressionStatement(node: ExpressionStatement): void {
this.visitNode(node.expression);
}
Expand Down Expand Up @@ -1065,16 +1105,20 @@ export class ASTBuilder {
this.visitNode(node.statement);
}

visitFunctionDeclaration(node: FunctionDeclaration): void {
visitFunctionDeclaration(node: FunctionDeclaration, isDefault: bool = false): void {
var sb = this.sb;
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
this.serializeExternalModifiers(node);
this.serializeAccessModifiers(node);
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
this.serializeAccessModifiers(node);
}
if (node.name.text.length) {
sb.push("function ");
} else {
Expand Down Expand Up @@ -1230,15 +1274,19 @@ export class ASTBuilder {
this.visitTypeNode(node.valueType);
}

visitInterfaceDeclaration(node: InterfaceDeclaration): void {
visitInterfaceDeclaration(node: InterfaceDeclaration, isDefault: bool = false): void {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
this.serializeExternalModifiers(node);
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
}
sb.push("interface ");
this.visitIdentifierExpression(node.name);
var typeParameters = node.typeParameters;
Expand Down Expand Up @@ -1284,15 +1332,19 @@ export class ASTBuilder {
this.visitFunctionCommon(node);
}

visitNamespaceDeclaration(node: NamespaceDeclaration): void {
visitNamespaceDeclaration(node: NamespaceDeclaration, isDefault: bool = false): void {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
this.serializeExternalModifiers(node);
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
}
sb.push("namespace ");
this.visitIdentifierExpression(node.name);
var members = node.members;
Expand Down
Loading

0 comments on commit fa66738

Please sign in to comment.