Skip to content

Commit

Permalink
Handle some cases of inlined exports and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Jeske committed May 20, 2020
1 parent 2835ee4 commit 8362b3a
Show file tree
Hide file tree
Showing 21 changed files with 184 additions and 65 deletions.
7 changes: 5 additions & 2 deletions src/Chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,9 @@ export default class Chunk {
renderedResolution,
resolution instanceof Module &&
!(resolution.facadeChunk && resolution.facadeChunk.strictFacade) &&
resolution.namespace.exportName!,
!!resolution.namespace.exportName &&
// We only need one of the export names to bind to
resolution.namespace.exportName[0],
options
);
}
Expand Down Expand Up @@ -1019,7 +1021,8 @@ export default class Chunk {
if (exportVariable instanceof ExportShimVariable) {
this.needsExportsShim = true;
}
exportVariable.exportName = exportName;
exportVariable.exportName = exportVariable.exportName || [];
exportVariable.exportName.push(exportName);
if (
options.format !== 'es' &&
options.format !== 'system' &&
Expand Down
36 changes: 20 additions & 16 deletions src/ast/nodes/AssignmentExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,32 @@ export default class AssignmentExpression extends NodeBase {
this.right.render(code, options);
if (options.format === 'system') {
if (this.left.variable && this.left.variable.exportName) {
const operatorPos = findFirstOccurrenceOutsideComment(
code.original,
this.operator,
this.left.end
);
const operation =
this.operator.length > 1
? ` ${this.left.variable.exportName} ${this.operator.slice(0, -1)}`
: '';
code.overwrite(
operatorPos,
operatorPos + this.operator.length,
`= exports('${this.left.variable.exportName}',${operation}`
);
code.appendLeft(this.right.end, `)`);
if (this.left.variable.exportName.length === 1) {
const operatorPos = findFirstOccurrenceOutsideComment(
code.original,
this.operator,
this.left.end
);
const operation =
this.operator.length > 1
? ` ${this.left.variable.exportName[0]} ${this.operator.slice(0, -1)}`
: '';
code.overwrite(
operatorPos,
operatorPos + this.operator.length,
`= exports('${this.left.variable.exportName[0]}',${operation}`
);
code.appendLeft(this.right.end, `)`);
} else {
code.appendLeft(this.right.end, `, ${getSystemExportStatement([this.left.variable])}`);
}
} else if ('addExportedVariables' in this.left) {
const systemPatternExports: Variable[] = [];
this.left.addExportedVariables(systemPatternExports);
if (systemPatternExports.length > 0) {
code.prependRight(
this.start,
`function (v) {${getSystemExportStatement(systemPatternExports)} return v;} (`
`function (v) {${getSystemExportStatement(systemPatternExports)}; return v;} (`
);
code.appendLeft(this.end, ')');
}
Expand Down
6 changes: 2 additions & 4 deletions src/ast/nodes/ClassDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IdentifierWithVariable } from './Identifier';
import * as NodeType from './NodeType';
import ClassNode from './shared/ClassNode';
import { GenericEsTreeNode } from './shared/Node';
import { getSystemExportStatement } from '../../utils/systemJsRendering';

export default class ClassDeclaration extends ClassNode {
id!: IdentifierWithVariable | null;
Expand All @@ -27,10 +28,7 @@ export default class ClassDeclaration extends ClassNode {

render(code: MagicString, options: RenderOptions) {
if (options.format === 'system' && this.id && this.id.variable.exportName) {
code.appendLeft(
this.end,
` exports('${this.id.variable.exportName}', ${this.id.variable.getName()});`
);
code.appendLeft(this.end, ` ${getSystemExportStatement([this.id.variable])};`);
}
super.render(code, options);
}
Expand Down
35 changes: 22 additions & 13 deletions src/ast/nodes/ExportDefaultDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import FunctionDeclaration from './FunctionDeclaration';
import Identifier from './Identifier';
import * as NodeType from './NodeType';
import { ExpressionNode, IncludeChildren, NodeBase } from './shared/Node';
import { getSystemExportStatement } from '../../utils/systemJsRendering';

const WHITESPACE = /\s/;

Expand Down Expand Up @@ -135,7 +136,7 @@ export default class ExportDefaultDeclaration extends NodeBase {
this.declaration instanceof ClassDeclaration &&
this.variable.exportName
) {
code.appendLeft(this.end, ` exports('${this.variable.exportName}', ${name});`);
code.appendLeft(this.end, ` ${getSystemExportStatement([this.variable])};`);
}
}

Expand All @@ -144,23 +145,31 @@ export default class ExportDefaultDeclaration extends NodeBase {
declarationStart: number,
options: RenderOptions
) {
const systemBinding =
options.format === 'system' && this.variable.exportName
? `exports('${this.variable.exportName}', `
: '';
code.overwrite(
this.start,
declarationStart,
`${options.varOrConst} ${this.variable.getName()} = ${systemBinding}`
);
const hasTrailingSemicolon = code.original.charCodeAt(this.end - 1) === 59; /*";"*/
if (systemBinding) {

if (options.format === 'system' && this.variable.exportName && this.variable.exportName.length === 1) {
code.overwrite(
this.start,
declarationStart,
`${options.varOrConst} ${this.variable.getName()} = exports('${this.variable.exportName[0]}', `
);
code.appendRight(
hasTrailingSemicolon ? this.end - 1 : this.end,
')' + (hasTrailingSemicolon ? '' : ';')
);
} else if (!hasTrailingSemicolon) {
code.appendLeft(this.end, ';');
} else {
code.overwrite(
this.start,
declarationStart,
`${options.varOrConst} ${this.variable.getName()} = `
);
if (!hasTrailingSemicolon) {
code.appendLeft(this.end, ';');
}
}

if (options.format === 'system' && this.variable.exportName && this.variable.exportName.length > 1) {
code.appendLeft(this.end, ` ${getSystemExportStatement([this.variable])};`);
}
}
}
Expand Down
48 changes: 27 additions & 21 deletions src/ast/nodes/UpdateExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EMPTY_PATH, ObjectPath } from '../utils/PathTracker';
import Identifier from './Identifier';
import * as NodeType from './NodeType';
import { ExpressionNode, NodeBase } from './shared/Node';
import { getSystemExportStatement } from '../../utils/systemJsRendering';

export default class UpdateExpression extends NodeBase {
argument!: ExpressionNode;
Expand Down Expand Up @@ -36,28 +37,33 @@ export default class UpdateExpression extends NodeBase {
this.argument.render(code, options);
const variable = this.argument.variable;
if (options.format === 'system' && variable && variable.exportName) {
const name = variable.getName();
if (this.prefix) {
code.overwrite(
this.start,
this.end,
`exports('${variable.exportName}', ${this.operator}${name})`
);
} else {
let op;
switch (this.operator) {
case '++':
op = `${name} + 1`;
break;
case '--':
op = `${name} - 1`;
break;
if (variable.exportName.length === 1) {
const name = variable.getName();
if (this.prefix) {
code.overwrite(
this.start,
this.end,
`exports('${variable.exportName[0]}', ${this.operator}${name})`
);
} else {
let op;
switch (this.operator) {
case '++':
op = `${name} + 1`;
break;
case '--':
op = `${name} - 1`;
break;
}
code.overwrite(
this.start,
this.end,
`(exports('${variable.exportName[0]}', ${op}), ${name}${this.operator})`
);
}
code.overwrite(
this.start,
this.end,
`(exports('${variable.exportName}', ${op}), ${name}${this.operator})`
);
} else {
// Regardless of prefix, we render the export as part of a sequence expression after the update
code.appendLeft(this.end, `, ${getSystemExportStatement([variable])}`);
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/ast/nodes/VariableDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export default class VariableDeclaration extends NodeBase {
code.appendLeft(renderedContentEnd, separatorString);
}
if (systemPatternExports.length > 0) {
code.appendLeft(renderedContentEnd, ' ' + getSystemExportStatement(systemPatternExports));
code.appendLeft(renderedContentEnd, ` ${getSystemExportStatement(systemPatternExports)};`);
}
}

Expand Down Expand Up @@ -177,9 +177,13 @@ export default class VariableDeclaration extends NodeBase {
if (node.id.type !== NodeType.Identifier) {
node.id.addExportedVariables(systemPatternExports);
} else if (node.id.variable!.exportName) {
// TODO: how to handle this case
// It might not be semantically correct to move the exports() after the declaration
// as other declarations may occur later but we don't have great a great for inlining the
//
code.prependLeft(
code.original.indexOf('=', node.id.end) + 1,
` exports('${node.id.variable!.safeExportName || node.id.variable!.exportName}',`
` exports('${node.id.variable!.safeExportName || node.id.variable!.exportName[0]}',`
);
nextSeparatorString += ')';
}
Expand Down
3 changes: 2 additions & 1 deletion src/ast/variables/NamespaceVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { RESERVED_NAMES } from '../../utils/reservedNames';
import Identifier from '../nodes/Identifier';
import { UNKNOWN_PATH } from '../utils/PathTracker';
import Variable from './Variable';
import { getSystemExportStatement } from '../../utils/systemJsRendering';

export default class NamespaceVariable extends Variable {
context: AstContext;
Expand Down Expand Up @@ -108,7 +109,7 @@ export default class NamespaceVariable extends Variable {
output = `${options.varOrConst} ${name}${_}=${_}${output};`;

if (options.format === 'system' && this.exportName) {
output += `${n}exports('${this.exportName}',${_}${name});`;
output += `${n}${getSystemExportStatement([this])};`;
}

return output;
Expand Down
2 changes: 1 addition & 1 deletion src/ast/variables/Variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { LiteralValueOrUnknown, UnknownValue, UNKNOWN_EXPRESSION } from '../valu

export default class Variable implements ExpressionEntity {
alwaysRendered = false;
exportName: string | null = null;
exportName: string[] | null = null;
included = false;
isId = false;
// both NamespaceVariable and ExternalVariable can be namespaces
Expand Down
14 changes: 9 additions & 5 deletions src/utils/systemJsRendering.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import Variable from '../ast/variables/Variable';

export function getSystemExportStatement(exportedVariables: Variable[]): string {
if (exportedVariables.length === 1) {
if (exportedVariables.length === 1 && exportedVariables[0].exportName && exportedVariables[0].exportName.length === 1) {
return `exports('${exportedVariables[0].safeExportName ||
exportedVariables[0].exportName}', ${exportedVariables[0].getName()});`;
exportedVariables[0].exportName[0]}', ${exportedVariables[0].getName()})`;
} else {
return `exports({${exportedVariables
.map(variable => `${variable.safeExportName || variable.exportName}: ${variable.getName()}`)
.join(', ')}});`;
return `exports({ ${exportedVariables
.map(variable =>
// TODO: do we always have export names at this point?
variable.exportName!.map(exportName => `${exportName}: ${variable.getName()}`)
.join(', ')
)
.join(', ')} })`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
description: 'supports binding a class declaration under multiple names in systemJS',
solo: true,
options: {
output: {
format: 'system'
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
System.register([], function (exports) {
'use strict';
return {
execute: function () {

class a {} exports({ a: a, b: a });

}
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class a {};

export { a as b };
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
description: 'supports binding a variable declaration under multiple names in systemJS',
solo: true,
options: {
output: {
format: 'system',
exports: 'named'
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
System.register([], function (exports) {
'use strict';
return {
execute: function () {

class A {} exports({ A: A, default: A });

}
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default class A {}
export { A }

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
description: 'supports binding a variable declaration under multiple names in systemJS',
solo: true,
options: {
output: {
format: 'system'
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
System.register([], function (exports) {
'use strict';
return {
execute: function () {

let a = 123, b = exports('b', 456);
exports({ a: a, c: a });

}
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export let a = 123, b = 456;
export { a as c };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
description: 'supports binding a variable declaration under multiple names in systemJS',
solo: true,
options: {
output: {
format: 'system'
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
System.register([], function (exports) {
'use strict';
return {
execute: function () {

let a = 123; exports({ a: a, b: a });
a++, exports({ a: a, b: a });

}
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export let a = 123;
a++;
export { a as b };

0 comments on commit 8362b3a

Please sign in to comment.