Skip to content

Commit

Permalink
Merge branch 'master' into doc-search
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Feb 1, 2023
2 parents 8cf20fc + ef25721 commit 1265b01
Show file tree
Hide file tree
Showing 32 changed files with 485 additions and 19 deletions.
26 changes: 16 additions & 10 deletions src/Chunk.ts
Expand Up @@ -710,13 +710,15 @@ export default class Chunk {
alternativeReexportModule = importingModule.alternativeReexportModules.get(variable);
if (alternativeReexportModule) {
const exportingChunk = this.chunkByModule.get(alternativeReexportModule);
if (exportingChunk && exportingChunk !== exportChunk) {
if (exportingChunk !== exportChunk) {
this.inputOptions.onwarn(
errorCyclicCrossChunkReexport(
variableModule.getExportNamesByVariable().get(variable)![0],
// Namespaces do not have an export name
variableModule.getExportNamesByVariable().get(variable)?.[0] || '*',
variableModule.id,
alternativeReexportModule.id,
importingModule.id
importingModule.id,
this.outputOptions.preserveModules
)
);
}
Expand All @@ -732,8 +734,10 @@ export default class Chunk {
for (const exportedVariable of map.keys()) {
const isSynthetic = exportedVariable instanceof SyntheticNamedExportVariable;
const importedVariable = isSynthetic ? exportedVariable.getBaseVariable() : exportedVariable;
this.checkCircularDependencyImport(importedVariable, module);
// When preserving modules, we do not create namespace objects but directly
// use the actual namespaces, which would be broken by this logic.
if (!(importedVariable instanceof NamespaceVariable && this.outputOptions.preserveModules)) {
this.checkCircularDependencyImport(importedVariable, module);
const exportingModule = importedVariable.module;
if (exportingModule instanceof Module) {
const chunk = this.chunkByModule.get(exportingModule);
Expand Down Expand Up @@ -1164,7 +1168,8 @@ export default class Chunk {
indent,
namespaceToStringTag,
pluginDriver,
snippets
snippets,
useOriginalName: null
};

let usesTopLevelAwait = false;
Expand Down Expand Up @@ -1373,12 +1378,13 @@ export default class Chunk {
const chunk = this.chunkByModule.get(variable.module as Module);
if (chunk !== this) {
this.imports.add(variable);
if (
!(variable instanceof NamespaceVariable && this.outputOptions.preserveModules) &&
variable.module instanceof Module
) {
chunk!.exports.add(variable);
if (variable.module instanceof Module) {
this.checkCircularDependencyImport(variable, module);
// When preserving modules, we do not create namespace objects but directly
// use the actual namespaces, which would be broken by this logic.
if (!(variable instanceof NamespaceVariable && this.outputOptions.preserveModules)) {
chunk!.exports.add(variable);
}
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/ast/nodes/ClassDeclaration.ts
Expand Up @@ -2,6 +2,7 @@ import type MagicString from 'magic-string';
import type { RenderOptions } from '../../utils/renderHelpers';
import { getSystemExportStatement } from '../../utils/systemJsRendering';
import type ChildScope from '../scopes/ChildScope';
import type Variable from '../variables/Variable';
import Identifier, { type IdentifierWithVariable } from './Identifier';
import type * as NodeType from './NodeType';
import ClassNode from './shared/ClassNode';
Expand Down Expand Up @@ -43,7 +44,10 @@ export default class ClassDeclaration extends ClassNode {
const renderedVariable = variable.getName(getPropertyAccess);
if (renderedVariable !== name) {
this.superClass?.render(code, options);
this.body.render(code, options);
this.body.render(code, {
...options,
useOriginalName: (_variable: Variable) => _variable === variable
});
code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`);
code.prependLeft(this.end, ';');
return;
Expand Down
4 changes: 2 additions & 2 deletions src/ast/nodes/Identifier.ts
Expand Up @@ -244,11 +244,11 @@ export default class Identifier extends NodeBase implements PatternNode {

render(
code: MagicString,
{ snippets: { getPropertyAccess } }: RenderOptions,
{ snippets: { getPropertyAccess }, useOriginalName }: RenderOptions,
{ renderedParentType, isCalleeOfRenderedParent, isShorthandProperty }: NodeRenderOptions = BLANK
): void {
if (this.variable) {
const name = this.variable.getName(getPropertyAccess);
const name = this.variable.getName(getPropertyAccess, useOriginalName);

if (name !== this.name) {
code.overwrite(this.start, this.end, name, {
Expand Down
9 changes: 8 additions & 1 deletion src/ast/variables/Variable.ts
@@ -1,5 +1,6 @@
import type ExternalModule from '../../ExternalModule';
import type Module from '../../Module';
import type { RenderOptions } from '../../utils/renderHelpers';
import type { HasEffectsContext } from '../ExecutionContext';
import type { NodeInteraction } from '../NodeInteractions';
import { INTERACTION_ACCESSED } from '../NodeInteractions';
Expand Down Expand Up @@ -42,7 +43,13 @@ export default class Variable extends ExpressionEntity {
return this.renderBaseName || this.renderName || this.name;
}

getName(getPropertyAccess: (name: string) => string): string {
getName(
getPropertyAccess: (name: string) => string,
useOriginalName?: RenderOptions['useOriginalName']
): string {
if (useOriginalName?.(this)) {
return this.name;
}
const name = this.renderName || this.name;
return this.renderBaseName ? `${this.renderBaseName}${getPropertyAccess(name)}` : name;
}
Expand Down
7 changes: 5 additions & 2 deletions src/utils/error.ts
Expand Up @@ -259,7 +259,8 @@ export function errorCyclicCrossChunkReexport(
exportName: string,
exporter: string,
reexporter: string,
importer: string
importer: string,
preserveModules: boolean
): RollupLog {
return {
code: CYCLIC_CROSS_CHUNK_REEXPORT,
Expand All @@ -271,7 +272,9 @@ export function errorCyclicCrossChunkReexport(
reexporter
)}" while both modules are dependencies of each other and will end up in different chunks by current Rollup settings. This scenario is not well supported at the moment as it will produce a circular dependency between chunks and will likely lead to broken execution order.\nEither change the import in "${relativeId(
importer
)}" to point directly to the exporting module or do not use "preserveModules" to ensure these modules end up in the same chunk.`,
)}" to point directly to the exporting module or ${
preserveModules ? 'do not use "output.preserveModules"' : 'reconfigure "output.manualChunks"'
} to ensure these modules end up in the same chunk.`,
reexporter
};
}
Expand Down
1 change: 1 addition & 0 deletions src/utils/renderHelpers.ts
Expand Up @@ -15,6 +15,7 @@ export interface RenderOptions {
namespaceToStringTag: boolean;
pluginDriver: PluginDriver;
snippets: GenerateCodeSnippets;
useOriginalName: ((variable: Variable) => boolean) | null;
}

export interface NodeRenderOptions {
Expand Down
3 changes: 3 additions & 0 deletions test/form/samples/use-class-name-in-static-block/_config.js
@@ -0,0 +1,3 @@
module.exports = {
description: 'use the original class name instead of renderName in class body'
};
36 changes: 36 additions & 0 deletions test/form/samples/use-class-name-in-static-block/_expected/amd.js
@@ -0,0 +1,36 @@
define((function () { 'use strict';

let Test$1 = class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
};

class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test2';
static {
assert.ok(Test.test);
new Test();
}
}

assert.ok(Test$1.test);
assert.ok(Test.test);

}));
34 changes: 34 additions & 0 deletions test/form/samples/use-class-name-in-static-block/_expected/cjs.js
@@ -0,0 +1,34 @@
'use strict';

let Test$1 = class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
};

class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test2';
static {
assert.ok(Test.test);
new Test();
}
}

assert.ok(Test$1.test);
assert.ok(Test.test);
32 changes: 32 additions & 0 deletions test/form/samples/use-class-name-in-static-block/_expected/es.js
@@ -0,0 +1,32 @@
let Test$1 = class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
};

class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test2';
static {
assert.ok(Test.test);
new Test();
}
}

assert.ok(Test$1.test);
assert.ok(Test.test);
37 changes: 37 additions & 0 deletions test/form/samples/use-class-name-in-static-block/_expected/iife.js
@@ -0,0 +1,37 @@
(function () {
'use strict';

let Test$1 = class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
};

class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test2';
static {
assert.ok(Test.test);
new Test();
}
}

assert.ok(Test$1.test);
assert.ok(Test.test);

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

let Test$1 = class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
};

class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test2';
static {
assert.ok(Test.test);
new Test();
}
}

assert.ok(Test$1.test);
assert.ok(Test.test);

})
};
}));
39 changes: 39 additions & 0 deletions test/form/samples/use-class-name-in-static-block/_expected/umd.js
@@ -0,0 +1,39 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';

let Test$1 = class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
};

class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test2';
static {
assert.ok(Test.test);
new Test();
}
}

assert.ok(Test$1.test);
assert.ok(Test.test);

}));
5 changes: 5 additions & 0 deletions test/form/samples/use-class-name-in-static-block/main.js
@@ -0,0 +1,5 @@
import { Test } from './test1.js';
import { Test as Test2 } from './test2.js';

assert.ok(Test.test);
assert.ok(Test2.test);
14 changes: 14 additions & 0 deletions test/form/samples/use-class-name-in-static-block/test1.js
@@ -0,0 +1,14 @@
export class Test {
constructor() {
assert.ok(Test.test);
assert.ok(this.getText());
}
getText() {
return Test.test;
}
static test = 'Test1';
static {
assert.ok(Test.test);
new Test();
}
}

0 comments on commit 1265b01

Please sign in to comment.