Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 23 additions & 21 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1578,8 +1578,9 @@ namespace ts {
}

function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
if (meaning === SymbolFlags.Namespace) {
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Namespace, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
const namespaceMeaning = SymbolFlags.Namespace | (isInJavaScriptFile(errorLocation) ? SymbolFlags.Value : 0);
if (meaning === namespaceMeaning) {
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~namespaceMeaning, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
const parent = errorLocation.parent;
if (symbol) {
if (isQualifiedName(parent)) {
Expand Down Expand Up @@ -1995,31 +1996,32 @@ namespace ts {
}
}
else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) {
let left: EntityNameOrEntityNameExpression;

if (name.kind === SyntaxKind.QualifiedName) {
left = name.left;
}
else if (name.kind === SyntaxKind.PropertyAccessExpression) {
left = name.expression;
}
else {
// If the expression in property-access expression is not entity-name or parenthsizedExpression (e.g. it is a call expression), it won't be able to successfully resolve the name.
// This is the case when we are trying to do any language service operation in heritage clauses. By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression
// will attempt to checkPropertyAccessExpression to resolve symbol.
// i.e class C extends foo()./*do language service operation here*/B {}
return undefined;
}
const left = name.kind === SyntaxKind.QualifiedName ? name.left : name.expression;
Copy link
Member Author

Choose a reason for hiding this comment

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

this is just a drive-by fix — you can see that the else clause will never happen based on the containing if.

const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name;
let namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location);
const namespaceMeaning = SymbolFlags.Namespace | (isInJavaScriptFile(name) ? meaning & SymbolFlags.Value : 0);
let namespace = resolveEntityName(left, namespaceMeaning, ignoreErrors, /*dontResolveAlias*/ false, location);
if (!namespace || nodeIsMissing(right)) {
return undefined;
}
else if (namespace === unknownSymbol) {
return namespace;
}
if (isInJavaScriptFile(name) && isDeclarationOfFunctionOrClassExpression(namespace)) {
namespace = getSymbolOfNode((namespace.valueDeclaration as VariableDeclaration).initializer);
if (isInJavaScriptFile(name)) {
if (isDeclarationOfFunctionOrClassExpression(namespace)) {
namespace = getSymbolOfNode((namespace.valueDeclaration as VariableDeclaration).initializer);
}
if (namespace.valueDeclaration &&
isVariableDeclaration(namespace.valueDeclaration) &&
isCommonJsRequire(namespace.valueDeclaration.initializer)) {
const moduleName = (namespace.valueDeclaration.initializer as CallExpression).arguments[0] as StringLiteral;
const moduleSym = resolveExternalModuleName(moduleName, moduleName);
if (moduleSym) {
const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
if (resolvedModuleSymbol) {
namespace = resolvedModuleSymbol;
}
}
}
}
symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning);
if (!symbol) {
Expand Down Expand Up @@ -17954,7 +17956,7 @@ namespace ts {

// In JavaScript files, calls to any identifier 'require' are treated as external module imports
if (isInJavaScriptFile(node) && isCommonJsRequire(node)) {
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
return resolveExternalModuleTypeByLiteral(node.arguments[0] as StringLiteral);
}

const returnType = getReturnTypeOfSignature(signature);
Expand Down
32 changes: 32 additions & 0 deletions tests/baselines/reference/varRequireFromJavascript.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
tests/cases/conformance/salsa/use.js(1,10): error TS2304: Cannot find name 'require'.


==== tests/cases/conformance/salsa/use.js (1 errors) ====
var ex = require('./ex')
~~~~~~~
!!! error TS2304: Cannot find name 'require'.

// values work
var crunch = new ex.Crunch(1);
crunch.n


// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
wrap.n
}

==== tests/cases/conformance/salsa/ex.js (0 errors) ====
export class Crunch {
/** @param {number} n */
constructor(n) {
this.n = n
}
m() {
return this.n
}
}

56 changes: 56 additions & 0 deletions tests/baselines/reference/varRequireFromJavascript.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : Symbol(ex, Decl(use.js, 0, 3))
>'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.js, 0, 0))

// values work
var crunch = new ex.Crunch(1);
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>ex.Crunch : Symbol(Crunch, Decl(ex.js, 0, 0))
>ex : Symbol(ex, Decl(use.js, 0, 3))
>Crunch : Symbol(Crunch, Decl(ex.js, 0, 0))

crunch.n
>crunch.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))


// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
>f : Symbol(f, Decl(use.js, 4, 8))
>wrap : Symbol(wrap, Decl(use.js, 11, 11))

wrap.n
>wrap.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>wrap : Symbol(wrap, Decl(use.js, 11, 11))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
}

=== tests/cases/conformance/salsa/ex.js ===
export class Crunch {
>Crunch : Symbol(Crunch, Decl(ex.js, 0, 0))

/** @param {number} n */
constructor(n) {
>n : Symbol(n, Decl(ex.js, 2, 16))

this.n = n
>this.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>this : Symbol(Crunch, Decl(ex.js, 0, 0))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>n : Symbol(n, Decl(ex.js, 2, 16))
}
m() {
>m : Symbol(Crunch.m, Decl(ex.js, 4, 5))

return this.n
>this.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>this : Symbol(Crunch, Decl(ex.js, 0, 0))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
}
}

61 changes: 61 additions & 0 deletions tests/baselines/reference/varRequireFromJavascript.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : typeof "tests/cases/conformance/salsa/ex"
>require('./ex') : typeof "tests/cases/conformance/salsa/ex"
>require : any
>'./ex' : "./ex"

// values work
var crunch = new ex.Crunch(1);
>crunch : Crunch
>new ex.Crunch(1) : Crunch
>ex.Crunch : typeof Crunch
>ex : typeof "tests/cases/conformance/salsa/ex"
>Crunch : typeof Crunch
>1 : 1

crunch.n
>crunch.n : number
>crunch : Crunch
>n : number


// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
>f : (wrap: Crunch) => void
>wrap : Crunch

wrap.n
>wrap.n : number
>wrap : Crunch
>n : number
}

=== tests/cases/conformance/salsa/ex.js ===
export class Crunch {
>Crunch : Crunch

/** @param {number} n */
constructor(n) {
>n : number

this.n = n
>this.n = n : number
>this.n : number
>this : this
>n : number
>n : number
}
m() {
>m : () => number

return this.n
>this.n : number
>this : this
>n : number
}
}

31 changes: 31 additions & 0 deletions tests/baselines/reference/varRequireFromTypescript.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
tests/cases/conformance/salsa/use.js(1,10): error TS2304: Cannot find name 'require'.


==== tests/cases/conformance/salsa/use.js (1 errors) ====
var ex = require('./ex')
~~~~~~~
!!! error TS2304: Cannot find name 'require'.

// values work
var crunch = new ex.Crunch(1);
crunch.n


// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
greatest.day
wrap.n
}

==== tests/cases/conformance/salsa/ex.d.ts (0 errors) ====
export type Greatest = { day: 1 }
export class Crunch {
n: number
m(): number
constructor(n: number)
}

57 changes: 57 additions & 0 deletions tests/baselines/reference/varRequireFromTypescript.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : Symbol(ex, Decl(use.js, 0, 3))
>'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.d.ts, 0, 0))

// values work
var crunch = new ex.Crunch(1);
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>ex.Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33))
>ex : Symbol(ex, Decl(use.js, 0, 3))
>Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33))

crunch.n
>crunch.n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))


// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
>f : Symbol(f, Decl(use.js, 4, 8))
>greatest : Symbol(greatest, Decl(use.js, 12, 11))
>wrap : Symbol(wrap, Decl(use.js, 12, 20))

greatest.day
>greatest.day : Symbol(day, Decl(ex.d.ts, 0, 24))
>greatest : Symbol(greatest, Decl(use.js, 12, 11))
>day : Symbol(day, Decl(ex.d.ts, 0, 24))

wrap.n
>wrap.n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
>wrap : Symbol(wrap, Decl(use.js, 12, 20))
>n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
}

=== tests/cases/conformance/salsa/ex.d.ts ===
export type Greatest = { day: 1 }
>Greatest : Symbol(Greatest, Decl(ex.d.ts, 0, 0))
>day : Symbol(day, Decl(ex.d.ts, 0, 24))

export class Crunch {
>Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33))

n: number
>n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))

m(): number
>m : Symbol(Crunch.m, Decl(ex.d.ts, 2, 13))

constructor(n: number)
>n : Symbol(n, Decl(ex.d.ts, 4, 16))
}

61 changes: 61 additions & 0 deletions tests/baselines/reference/varRequireFromTypescript.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : typeof "tests/cases/conformance/salsa/ex"
>require('./ex') : typeof "tests/cases/conformance/salsa/ex"
>require : any
>'./ex' : "./ex"

// values work
var crunch = new ex.Crunch(1);
>crunch : Crunch
>new ex.Crunch(1) : Crunch
>ex.Crunch : typeof Crunch
>ex : typeof "tests/cases/conformance/salsa/ex"
>Crunch : typeof Crunch
>1 : 1

crunch.n
>crunch.n : number
>crunch : Crunch
>n : number


// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
>f : (greatest: { day: 1; }, wrap: Crunch) => void
>greatest : { day: 1; }
>wrap : Crunch

greatest.day
>greatest.day : 1
>greatest : { day: 1; }
>day : 1

wrap.n
>wrap.n : number
>wrap : Crunch
>n : number
}

=== tests/cases/conformance/salsa/ex.d.ts ===
export type Greatest = { day: 1 }
>Greatest : Greatest
>day : 1

export class Crunch {
>Crunch : Crunch

n: number
>n : number

m(): number
>m : () => number

constructor(n: number)
>n : number
}

Loading