Skip to content

Commit 84076a5

Browse files
authored
Add diagnostic context for expando property declarations (microsoft#29905)
1 parent 5ec35c1 commit 84076a5

10 files changed

+109
-7
lines changed

src/compiler/transformers/declarations.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,9 @@ namespace ts {
10061006
if (!isPropertyAccessExpression(p.valueDeclaration)) {
10071007
return undefined;
10081008
}
1009+
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
10091010
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
1011+
getSymbolAccessibilityDiagnostic = oldDiag;
10101012
const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
10111013
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl]));
10121014
});

src/compiler/transformers/declarations/diagnostics.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace ts {
2626
| ImportEqualsDeclaration
2727
| TypeAliasDeclaration
2828
| ConstructorDeclaration
29-
| IndexSignatureDeclaration;
29+
| IndexSignatureDeclaration
30+
| PropertyAccessExpression;
3031

3132
export function canProduceDiagnostics(node: Node): node is DeclarationDiagnosticProducing {
3233
return isVariableDeclaration(node) ||
@@ -46,7 +47,8 @@ namespace ts {
4647
isImportEqualsDeclaration(node) ||
4748
isTypeAliasDeclaration(node) ||
4849
isConstructorDeclaration(node) ||
49-
isIndexSignatureDeclaration(node);
50+
isIndexSignatureDeclaration(node) ||
51+
isPropertyAccessExpression(node);
5052
}
5153

5254
export function createGetSymbolAccessibilityDiagnosticForNodeName(node: DeclarationDiagnosticProducing) {
@@ -123,7 +125,7 @@ namespace ts {
123125
}
124126

125127
export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationDiagnosticProducing): (symbolAccessibilityResult: SymbolAccessibilityResult) => SymbolAccessibilityDiagnostic | undefined {
126-
if (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isBindingElement(node) || isConstructorDeclaration(node)) {
128+
if (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isPropertyAccessExpression(node) || isBindingElement(node) || isConstructorDeclaration(node)) {
127129
return getVariableDeclarationTypeVisibilityError;
128130
}
129131
else if (isSetAccessor(node) || isGetAccessor(node)) {
@@ -164,7 +166,7 @@ namespace ts {
164166
}
165167
// This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
166168
// The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all.
167-
else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
169+
else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.PropertySignature ||
168170
(node.kind === SyntaxKind.Parameter && hasModifier(node.parent, ModifierFlags.Private))) {
169171
// TODO(jfreeman): Deal with computed properties in error reporting.
170172
if (hasModifier(node, ModifierFlags.Static)) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tests/cases/compiler/b.ts(4,1): error TS4032: Property 'val' of exported interface has or is using name 'I' from private module '"tests/cases/compiler/a"'.
2+
3+
4+
==== tests/cases/compiler/a.ts (0 errors) ====
5+
interface I {}
6+
export function f(): I { return null as I; }
7+
==== tests/cases/compiler/b.ts (1 errors) ====
8+
import {f} from "./a";
9+
10+
export function q() {}
11+
q.val = f();
12+
~~~~~
13+
!!! error TS4032: Property 'val' of exported interface has or is using name 'I' from private module '"tests/cases/compiler/a"'.
14+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//// [tests/cases/compiler/declarationEmitExpandoPropertyPrivateName.ts] ////
2+
3+
//// [a.ts]
4+
interface I {}
5+
export function f(): I { return null as I; }
6+
//// [b.ts]
7+
import {f} from "./a";
8+
9+
export function q() {}
10+
q.val = f();
11+
12+
13+
//// [a.js]
14+
"use strict";
15+
exports.__esModule = true;
16+
function f() { return null; }
17+
exports.f = f;
18+
//// [b.js]
19+
"use strict";
20+
exports.__esModule = true;
21+
var a_1 = require("./a");
22+
function q() { }
23+
exports.q = q;
24+
q.val = a_1.f();
25+
26+
27+
//// [a.d.ts]
28+
interface I {
29+
}
30+
export declare function f(): I;
31+
export {};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/a.ts ===
2+
interface I {}
3+
>I : Symbol(I, Decl(a.ts, 0, 0))
4+
5+
export function f(): I { return null as I; }
6+
>f : Symbol(f, Decl(a.ts, 0, 14))
7+
>I : Symbol(I, Decl(a.ts, 0, 0))
8+
>I : Symbol(I, Decl(a.ts, 0, 0))
9+
10+
=== tests/cases/compiler/b.ts ===
11+
import {f} from "./a";
12+
>f : Symbol(f, Decl(b.ts, 0, 8))
13+
14+
export function q() {}
15+
>q : Symbol(q, Decl(b.ts, 0, 22), Decl(b.ts, 2, 22))
16+
17+
q.val = f();
18+
>q.val : Symbol(q.val, Decl(b.ts, 2, 22))
19+
>q : Symbol(q, Decl(b.ts, 0, 22), Decl(b.ts, 2, 22))
20+
>val : Symbol(q.val, Decl(b.ts, 2, 22))
21+
>f : Symbol(f, Decl(b.ts, 0, 8))
22+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/a.ts ===
2+
interface I {}
3+
export function f(): I { return null as I; }
4+
>f : () => I
5+
>null as I : I
6+
>null : null
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import {f} from "./a";
10+
>f : () => I
11+
12+
export function q() {}
13+
>q : typeof q
14+
15+
q.val = f();
16+
>q.val = f() : I
17+
>q.val : I
18+
>q : typeof q
19+
>val : I
20+
>f() : I
21+
>f : () => I
22+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @declaration: true
2+
// @filename: a.ts
3+
interface I {}
4+
export function f(): I { return null as I; }
5+
// @filename: b.ts
6+
import {f} from "./a";
7+
8+
export function q() {}
9+
q.val = f();

tests/cases/user/prettier/prettier

Submodule prettier updated 1906 files

tests/cases/user/webpack/webpack

Submodule webpack updated 1279 files

0 commit comments

Comments
 (0)