Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve rendered class names #4674

Merged
merged 3 commits into from Oct 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/ast/nodes/ClassDeclaration.ts
Expand Up @@ -33,10 +33,21 @@ export default class ClassDeclaration extends ClassNode {
const {
exportNamesByVariable,
format,
snippets: { _ }
snippets: { _, getPropertyAccess }
} = options;
if (format === 'system' && this.id && exportNamesByVariable.has(this.id.variable)) {
code.appendLeft(this.end, `${_}${getSystemExportStatement([this.id.variable], options)};`);
if (this.id) {
const { variable, name } = this.id;
if (format === 'system' && exportNamesByVariable.has(variable)) {
code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`);
}
const renderedVariable = variable.getName(getPropertyAccess);
if (renderedVariable !== name) {
this.superClass?.render(code, options);
this.body.render(code, options);
code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`);
code.prependLeft(this.end, ';');
return;
}
}
super.render(code, options);
}
Expand Down
28 changes: 18 additions & 10 deletions src/ast/nodes/VariableDeclarator.ts
Expand Up @@ -9,6 +9,7 @@ import {
import type { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import type { ObjectPath } from '../utils/PathTracker';
import { UNDEFINED_EXPRESSION } from '../values';
import ClassExpression from './ClassExpression';
import Identifier from './Identifier';
import * as NodeType from './NodeType';
import { type ExpressionNode, type IncludeChildren, NodeBase } from './shared/Node';
Expand Down Expand Up @@ -45,26 +46,33 @@ export default class VariableDeclarator extends NodeBase {
render(code: MagicString, options: RenderOptions): void {
const {
exportNamesByVariable,
snippets: { _ }
snippets: { _, getPropertyAccess }
} = options;
const renderId = this.id.included;
const { end, id, init, start } = this;
const renderId = id.included;
if (renderId) {
this.id.render(code, options);
id.render(code, options);
} else {
const operatorPos = findFirstOccurrenceOutsideComment(code.original, '=', this.id.end);
code.remove(this.start, findNonWhiteSpace(code.original, operatorPos + 1));
const operatorPos = findFirstOccurrenceOutsideComment(code.original, '=', id.end);
code.remove(start, findNonWhiteSpace(code.original, operatorPos + 1));
}
if (this.init) {
this.init.render(
if (init) {
if (id instanceof Identifier && init instanceof ClassExpression && !init.id) {
const renderedVariable = id.variable!.getName(getPropertyAccess);
if (renderedVariable !== id.name) {
code.appendLeft(init.start + 5, ` ${id.name}`);
}
}
init.render(
code,
options,
renderId ? BLANK : { renderedSurroundingElement: NodeType.ExpressionStatement }
);
} else if (
this.id instanceof Identifier &&
isReassignedExportsMember(this.id.variable!, exportNamesByVariable)
id instanceof Identifier &&
isReassignedExportsMember(id.variable!, exportNamesByVariable)
) {
code.appendLeft(this.end, `${_}=${_}void 0`);
code.appendLeft(end, `${_}=${_}void 0`);
}
}

Expand Down
@@ -1,10 +1,10 @@
define(['exports'], (function (exports) { 'use strict';

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
@@ -1,10 +1,10 @@
'use strict';

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
@@ -1,8 +1,8 @@
class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
Expand Up @@ -3,11 +3,11 @@ System.register([], (function (exports) {
return {
execute: (function () {

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = exports('p', 43);

Expand Down
@@ -1,10 +1,10 @@
define(['exports'], (function (exports) { 'use strict';

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
@@ -1,10 +1,10 @@
'use strict';

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
@@ -1,8 +1,8 @@
class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
Expand Up @@ -3,11 +3,11 @@ System.register([], (function (exports) {
return {
execute: (function () {

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = exports('p', 43);

Expand Down
@@ -1,10 +1,10 @@
define(['exports'], (function (exports) { 'use strict';

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
@@ -1,10 +1,10 @@
'use strict';

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
@@ -1,8 +1,8 @@
class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
}
};

var p$1 = 43;

Expand Down
Expand Up @@ -3,11 +3,11 @@ System.register([], (function (exports) {
return {
execute: (function () {

class C$1 {
let C$1 = class C {
fn (num) {
console.log(num - p);
}
} exports('C', C$1);
}; exports('C', C$1);

var p$1 = exports('p', 43);

Expand Down
@@ -0,0 +1,4 @@
module.exports = {
description: 'handles exporting class declarations with name conflicts in SystemJS',
options: { output: { name: 'bundle' } }
};
@@ -0,0 +1,10 @@
define(['exports'], (function (exports) { 'use strict';

let Foo$1 = class Foo {};

class Foo {}

exports.First = Foo$1;
exports.Second = Foo;

}));
@@ -0,0 +1,8 @@
'use strict';

let Foo$1 = class Foo {};

class Foo {}

exports.First = Foo$1;
exports.Second = Foo;
@@ -0,0 +1,5 @@
let Foo$1 = class Foo {};

class Foo {}

export { Foo$1 as First, Foo as Second };
@@ -0,0 +1,13 @@
var bundle = (function (exports) {
'use strict';

let Foo$1 = class Foo {};

class Foo {}

exports.First = Foo$1;
exports.Second = Foo;

return exports;

})({});
@@ -0,0 +1,12 @@
System.register('bundle', [], (function (exports) {
'use strict';
return {
execute: (function () {

let Foo$1 = class Foo {}; exports('First', Foo$1);

class Foo {} exports('Second', Foo);

})
};
}));
@@ -0,0 +1,14 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bundle = {}));
})(this, (function (exports) { 'use strict';

let Foo$1 = class Foo {};

class Foo {}

exports.First = Foo$1;
exports.Second = Foo;

}));
@@ -0,0 +1,2 @@
class Foo {}
export { Foo };
2 changes: 2 additions & 0 deletions test/form/samples/exported-class-declaration-conflict/main.js
@@ -0,0 +1,2 @@
export { Foo as First } from './first';
export { Foo as Second } from './second';
@@ -0,0 +1,2 @@
class Foo {}
export { Foo };
3 changes: 3 additions & 0 deletions test/function/samples/class-name-conflict/_config.js
@@ -0,0 +1,3 @@
module.exports = {
description: 'preserves class names even if the class is renamed'
};
3 changes: 3 additions & 0 deletions test/function/samples/class-name-conflict/declaration1.js
@@ -0,0 +1,3 @@
class foo {}

assert.strictEqual(foo.name, 'foo');
3 changes: 3 additions & 0 deletions test/function/samples/class-name-conflict/declaration2.js
@@ -0,0 +1,3 @@
class foo {}

assert.strictEqual(foo.name, 'foo');
3 changes: 3 additions & 0 deletions test/function/samples/class-name-conflict/expression1.js
@@ -0,0 +1,3 @@
let foo = class {};

assert.strictEqual(foo.name, 'foo');
3 changes: 3 additions & 0 deletions test/function/samples/class-name-conflict/expression2.js
@@ -0,0 +1,3 @@
let foo = class {};

assert.strictEqual(foo.name, 'foo');
4 changes: 4 additions & 0 deletions test/function/samples/class-name-conflict/main.js
@@ -0,0 +1,4 @@
import './expression1';
import './declaration1';
import './expression2';
import './declaration2';