Skip to content

Commit

Permalink
Forbid duplicate static class and/or namespace members
Browse files Browse the repository at this point in the history
This isn't fully TS compatible, but refactors targeting internal names,
scoping, merging, etc. are needed to become more compatible. For
instance, if namespace members had unique separators in internal names,
then a non-exported namespace member would override a static class
member, assuming the names are the same.

Note that this change doesn't prevent the compiler from attempting to
compile the duplicate global, and hence the previous commit is needed
for this to work fully.
  • Loading branch information
CountBleck committed Nov 21, 2023
1 parent 89b49f0 commit 8a76750
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5058,15 +5058,31 @@ function tryMerge(older: Element, newer: Element): DeclaredElement | null {

/** Copies the members of `src` to `dest`. */
function copyMembers(src: Element, dest: Element): void {
let program = src.program;
assert(program == dest.program);

let srcMembers = src.members;
if (srcMembers) {
let destMembers = dest.members;
if (!destMembers) dest.members = destMembers = new Map();
// TODO: for (let [memberName, member] of srcMembers) {
for (let _keys = Map_keys(srcMembers), i = 0, k = _keys.length; i < k; ++i) {
let memberName = unchecked(_keys[i]);
let member = assert(srcMembers.get(memberName));
destMembers.set(memberName, member);
let srcMember = assert(srcMembers.get(memberName));
// This isn't TS compatible in every case, but the logic involved in
// merging, scoping, and making internal names is not currently able to
// handle duplicates well.
if (destMembers.has(memberName)) {
let destMember = assert(destMembers.get(memberName));
program.errorRelated(
DiagnosticCode.Duplicate_identifier_0,
srcMember.declaration.name.range, destMember.declaration.name.range,
memberName
);
continue;
}

destMembers.set(memberName, srcMember);
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions tests/compiler/issues/2793.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"stderr": [
"Duplicate identifier 'bar'.",
"in issues/2793.ts(8,14)",
"in issues/2793.ts(2,10)",
"Duplicate identifier 'baz'.",
"in issues/2793.ts(9,7)",
"in issues/2793.ts(3,10)",
"Duplicate identifier 'qux'.",
"in issues/2793.ts(10,14)",
"in issues/2793.ts(4,18)"
]
}
12 changes: 12 additions & 0 deletions tests/compiler/issues/2793.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Foo {
static bar: i32 = 2; // errors in TS
static baz: i32 = 2; // does not error in TS
private static qux: i32 = 2; // errors in TS
}

namespace Foo {
export let bar: i32 = 1;
let baz: string = "baz";
export let qux: i32 = 1;
let hi: i32 = 1;
}

0 comments on commit 8a76750

Please sign in to comment.