Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/rollup/rollup into sync-0…
Browse files Browse the repository at this point in the history
…1d8c9d1
  • Loading branch information
docschina-bot committed Nov 14, 2023
2 parents 3807f78 + 01d8c9d commit 6ff8e02
Show file tree
Hide file tree
Showing 16 changed files with 155 additions and 17 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# rollup changelog

## 4.4.1

_2023-11-14_

### Bug Fixes

- Do not flag duplicate function declarations in function scopes as syntax errors (#5248)

### Pull Requests

- [#5248](https://github.com/rollup/rollup/pull/5248): Allow functions to redeclare vars and functions in function scopes (@lukastaegert)

## 4.4.0

_2023-11-12_
Expand Down
2 changes: 1 addition & 1 deletion browser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rollup/browser",
"version": "4.4.0",
"version": "4.4.1",
"description": "Next-generation ES module bundler browser build",
"main": "dist/rollup.browser.js",
"module": "dist/es/rollup.browser.js",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rollup",
"version": "4.4.0",
"version": "4.4.1",
"description": "Next-generation ES module bundler",
"main": "dist/rollup.js",
"module": "dist/es/rollup.js",
Expand Down
7 changes: 0 additions & 7 deletions src/ast/scopes/CatchBodyScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,6 @@ export default class CatchBodyScope extends ChildScope {
this.addHoistedVariable(name, declaredVariable);
return declaredVariable;
}
// Functions can never re-declare catch parameters
if (kind === VariableKind.function) {
const name = identifier.name;
if (this.hoistedVariables?.get(name)) {
context.error(logRedeclarationError(name), identifier.start);
}
}
return super.addDeclaration(identifier, context, init, kind);
}
}
46 changes: 46 additions & 0 deletions src/ast/scopes/FunctionBodyScope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { AstContext } from '../../Module';
import { logRedeclarationError } from '../../utils/logs';
import type Identifier from '../nodes/Identifier';
import type { ExpressionEntity } from '../nodes/shared/Expression';
import { VariableKind } from '../nodes/shared/VariableKinds';
import LocalVariable from '../variables/LocalVariable';
import ChildScope from './ChildScope';
import type ParameterScope from './ParameterScope';

export default class FunctionBodyScope extends ChildScope {
constructor(
readonly parent: ParameterScope,
readonly context: AstContext
) {
super(parent, context);
}

// There is stuff that is only allowed in function scopes, i.e. functions can
// be redeclared, functions and var can redeclare each other
addDeclaration(
identifier: Identifier,
context: AstContext,
init: ExpressionEntity,
kind: VariableKind
): LocalVariable {
const name = identifier.name;
const existingVariable =
this.hoistedVariables?.get(name) || (this.variables.get(name) as LocalVariable);
if (existingVariable) {
const existingKind = existingVariable.kind;
if (
(kind === VariableKind.var || kind === VariableKind.function) &&
(existingKind === VariableKind.var ||
existingKind === VariableKind.function ||
existingKind === VariableKind.parameter)
) {
existingVariable.addDeclaration(identifier, init);
return existingVariable;
}
context.error(logRedeclarationError(name), identifier.start);
}
const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
this.variables.set(name, newVariable);
return newVariable;
}
}
3 changes: 2 additions & 1 deletion src/ast/scopes/ParameterScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { ExpressionEntity } from '../nodes/shared/Expression';
import ParameterVariable from '../variables/ParameterVariable';
import CatchBodyScope from './CatchBodyScope';
import ChildScope from './ChildScope';
import FunctionBodyScope from './FunctionBodyScope';
import type Scope from './Scope';

export default class ParameterScope extends ChildScope {
Expand All @@ -19,7 +20,7 @@ export default class ParameterScope extends ChildScope {
super(parent, context);
this.bodyScope = isCatchScope
? new CatchBodyScope(this, context)
: new ChildScope(this, context);
: new FunctionBodyScope(this, context);
}

/**
Expand Down
7 changes: 2 additions & 5 deletions src/ast/scopes/Scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default class Scope {
/*
Redeclaration rules:
- var can redeclare var
- in function scopes, function and var can redeclare function and var
- var is hoisted across scopes, function remains in the scope it is declared
- var and function can redeclare function parameters, but parameters cannot redeclare parameters
- function cannot redeclare catch scope parameters
Expand All @@ -34,11 +35,7 @@ export default class Scope {
this.hoistedVariables?.get(name) || (this.variables.get(name) as LocalVariable);
if (existingVariable) {
const existingKind = existingVariable.kind;
if (
(kind === VariableKind.var &&
(existingKind === VariableKind.var || existingKind === VariableKind.parameter)) ||
(kind === VariableKind.function && existingKind === VariableKind.parameter)
) {
if (kind === VariableKind.var && existingKind === VariableKind.var) {
existingVariable.addDeclaration(identifier, init);
return existingVariable;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const path = require('node:path');
const ID_MAIN = path.join(__dirname, 'main.js');

module.exports = defineTest({
description: 'throws when redeclaring a function binding as a function in a block scope',
error: {
code: 'REDECLARATION_ERROR',
frame: `
1: {
2: function foo() {}
3: function foo() {}
^
4: }`,
id: ID_MAIN,
loc: {
column: 10,
file: ID_MAIN,
line: 3
},
message: 'Identifier "foo" has already been declared',
pos: 31,
watchFiles: [ID_MAIN]
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
function foo() {}
function foo() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const path = require('node:path');
const ID_MAIN = path.join(__dirname, 'main.js');

module.exports = defineTest({
description: 'throws when redeclaring a top-level function binding as a function',
error: {
code: 'REDECLARATION_ERROR',
frame: `
1: function foo() {}
2: function foo() {}
^`,
id: ID_MAIN,
loc: {
column: 9,
file: ID_MAIN,
line: 2
},
message: 'Identifier "foo" has already been declared',
pos: 27,
watchFiles: [ID_MAIN]
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
function foo() {}
function foo() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const path = require('node:path');
const ID_MAIN = path.join(__dirname, 'main.js');

module.exports = defineTest({
description: 'throws when redeclaring a top-level var binding as a function',
error: {
code: 'REDECLARATION_ERROR',
frame: `
1: var foo;
2: function foo() {}
^`,
id: ID_MAIN,
loc: {
column: 9,
file: ID_MAIN,
line: 2
},
message: 'Identifier "foo" has already been declared',
pos: 18,
watchFiles: [ID_MAIN]
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var foo;
function foo() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = defineTest({
description: 'allows to redeclare vars and functions as vars and functions in function scopes'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function foo() {
var fn = 1;
function fn() {}
function fn() {}
var fn = 2;

assert.equal(fn, 2);
}

foo();

1 comment on commit 6ff8e02

@vercel
Copy link

@vercel vercel bot commented on 6ff8e02 Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.