Skip to content

Commit 3739216

Browse files
committed
Merge branch 'master' into typeof-can-refer-class-before-declaration
2 parents aaf861a + 62f44fb commit 3739216

23 files changed

+291
-5
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,11 +760,17 @@ namespace ts {
760760

761761

762762
// declaration is after usage, but it can still be legal if usage is deferred:
763-
// 1. inside a function
764-
// 2. inside an instance property initializer, a reference to a non-instance property
765-
// 3. inside a static property initializer, a reference to a static method in the same class
763+
// 1. inside an export specifier
764+
// 2. inside a function
765+
// 3. inside an instance property initializer, a reference to a non-instance property
766+
// 4. inside a static property initializer, a reference to a static method in the same class
766767
// or if usage is in a type context:
767768
// 1. inside a type query (typeof in type position)
769+
if (usage.parent.kind === SyntaxKind.ExportSpecifier) {
770+
// export specifiers do not use the variable, they only make it available for use
771+
return true;
772+
}
773+
768774
const container = getEnclosingBlockScopeContainer(declaration);
769775
return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
770776

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,6 +3185,10 @@
31853185
"category": "Message",
31863186
"code": 6181
31873187
},
3188+
"Scoped package detected, looking in '{0}'": {
3189+
"category": "Message",
3190+
"code": "6182"
3191+
},
31883192

31893193
"Variable '{0}' implicitly has an '{1}' type.": {
31903194
"category": "Error",

src/compiler/moduleNameResolver.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,10 +954,25 @@ namespace ts {
954954
}
955955
nodeModulesAtTypesExists = false;
956956
}
957-
return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, moduleName, nodeModulesAtTypes, nodeModulesAtTypesExists, failedLookupLocations, state);
957+
return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackage(moduleName, state), nodeModulesAtTypes, nodeModulesAtTypesExists, failedLookupLocations, state);
958958
}
959959
}
960960

961+
/** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
962+
function mangleScopedPackage(moduleName: string, state: ModuleResolutionState): string {
963+
if (startsWith(moduleName, "@")) {
964+
const replaceSlash = moduleName.replace(ts.directorySeparator, "__");
965+
if (replaceSlash !== moduleName) {
966+
const mangled = replaceSlash.slice(1); // Take off the "@"
967+
if (state.traceEnabled) {
968+
trace(state.host, Diagnostics.Scoped_package_detected_looking_in_0, mangled);
969+
}
970+
return mangled;
971+
}
972+
}
973+
return moduleName;
974+
}
975+
961976
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult<Resolved> {
962977
const result = cache && cache.get(containingDirectory);
963978
if (result) {

src/server/server.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,9 @@ namespace ts.server {
401401
byteLength: Buffer.byteLength,
402402
hrtime: process.hrtime,
403403
logger,
404-
canUseEvents});
404+
canUseEvents,
405+
globalPlugins: options.globalPlugins,
406+
pluginProbeLocations: options.pluginProbeLocations});
405407

406408
if (telemetryEnabled && typingsInstaller) {
407409
typingsInstaller.setTelemetrySender(this);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [exportBinding.ts]
2+
export { x }
3+
const x = 'x'
4+
5+
export { Y as Z }
6+
class Y {}
7+
8+
9+
//// [exportBinding.js]
10+
"use strict";
11+
exports.__esModule = true;
12+
var x = 'x';
13+
exports.x = x;
14+
var Y = (function () {
15+
function Y() {
16+
}
17+
return Y;
18+
}());
19+
exports.Z = Y;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/es6/modules/exportBinding.ts ===
2+
export { x }
3+
>x : Symbol(x, Decl(exportBinding.ts, 0, 8))
4+
5+
const x = 'x'
6+
>x : Symbol(x, Decl(exportBinding.ts, 1, 5))
7+
8+
export { Y as Z }
9+
>Y : Symbol(Z, Decl(exportBinding.ts, 3, 8))
10+
>Z : Symbol(Z, Decl(exportBinding.ts, 3, 8))
11+
12+
class Y {}
13+
>Y : Symbol(Y, Decl(exportBinding.ts, 3, 17))
14+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/conformance/es6/modules/exportBinding.ts ===
2+
export { x }
3+
>x : "x"
4+
5+
const x = 'x'
6+
>x : "x"
7+
>'x' : "x"
8+
9+
export { Y as Z }
10+
>Y : typeof Y
11+
>Z : typeof Y
12+
13+
class Y {}
14+
>Y : Y
15+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [tests/cases/conformance/references/library-reference-scoped-packages.ts] ////
2+
3+
//// [index.d.ts]
4+
export const y = 0;
5+
6+
//// [a.ts]
7+
/// <reference types="@beep/boop" />
8+
9+
10+
//// [a.js]
11+
/// <reference types="@beep/boop" />
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
=== /a.ts ===
2+
/// <reference types="@beep/boop" />
3+
No type information for this code.
4+
No type information for this code.=== /node_modules/@types/beep__boop/index.d.ts ===
5+
export const y = 0;
6+
>y : Symbol(y, Decl(index.d.ts, 0, 12))
7+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
"======== Resolving type reference directive '@beep/boop', containing file '/a.ts', root directory 'types'. ========",
3+
"Resolving with primary search path 'types'.",
4+
"Directory 'types/@beep' does not exist, skipping all lookups in it.",
5+
"Looking up in 'node_modules' folder, initial location '/'.",
6+
"Scoped package detected, looking in 'beep__boop'",
7+
"File '/node_modules/@types/beep__boop.d.ts' does not exist.",
8+
"File '/node_modules/@types/beep__boop/package.json' does not exist.",
9+
"File '/node_modules/@types/beep__boop/index.d.ts' exist - use it as a name resolution result.",
10+
"Resolving real path for '/node_modules/@types/beep__boop/index.d.ts', result '/node_modules/@types/beep__boop/index.d.ts'.",
11+
"======== Type reference directive '@beep/boop' was successfully resolved to '/node_modules/@types/beep__boop/index.d.ts', primary: false. ========"
12+
]

0 commit comments

Comments
 (0)