mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-18 03:43:28 -06:00
Fix js-prototype-assignment on declarations
This commit is contained in:
parent
d55aa22d15
commit
aa88f71c2e
@ -17915,15 +17915,34 @@ namespace ts {
|
||||
|
||||
function getAssignedClassType(symbol: Symbol) {
|
||||
const decl = symbol.valueDeclaration;
|
||||
const assignmentSymbol = decl && decl.parent && isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left);
|
||||
const assignmentSymbol = decl && decl.parent &&
|
||||
(isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
|
||||
isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
|
||||
if (assignmentSymbol) {
|
||||
const prototype = forEach(assignmentSymbol.declarations, d => getAssignedJavascriptPrototype(d.parent));
|
||||
const prototype = forEach(assignmentSymbol.declarations, getAssignedJavascriptPrototype);
|
||||
if (prototype) {
|
||||
return checkExpression(prototype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getAssignedJavascriptPrototype(node: Node) {
|
||||
if (!node.parent) {
|
||||
return false;
|
||||
}
|
||||
let parent: Node = node.parent;
|
||||
while (parent && parent.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
return parent && isBinaryExpression(parent) &&
|
||||
isPropertyAccessExpression(parent.left) &&
|
||||
parent.left.name.escapedText === "prototype" &&
|
||||
parent.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
isObjectLiteralExpression(parent.right) &&
|
||||
parent.right;
|
||||
}
|
||||
|
||||
|
||||
function getInferredClassType(symbol: Symbol) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.inferredClassType) {
|
||||
|
||||
@ -1488,18 +1488,10 @@ namespace ts {
|
||||
return symbol;
|
||||
}
|
||||
const declaration = symbol.valueDeclaration;
|
||||
const e = getDeclaredJavascriptInitializer(declaration) || getAssignedJavascriptInitializer(declaration) || getAssignedJavascriptPrototype(declaration);
|
||||
const e = getDeclaredJavascriptInitializer(declaration) || getAssignedJavascriptInitializer(declaration);
|
||||
return e ? e.symbol : symbol;
|
||||
}
|
||||
|
||||
export function getAssignedJavascriptPrototype(node: Node) {
|
||||
return isPropertyAccessExpression(node) &&
|
||||
node.parent && isPropertyAccessExpression(node.parent) && node.parent.name.escapedText === "prototype" &&
|
||||
node.parent.parent && isBinaryExpression(node.parent.parent) && node.parent.parent.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
node.parent.parent.right.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
node.parent.parent.right;
|
||||
}
|
||||
|
||||
export function getDeclaredJavascriptInitializer(node: Node) {
|
||||
if (node && isVariableDeclaration(node) && node.initializer) {
|
||||
return getJavascriptInitializer(node.initializer) ||
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
=== tests/cases/conformance/salsa/module.js ===
|
||||
var Inner = function() {}
|
||||
>Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25))
|
||||
|
||||
Inner.prototype = {
|
||||
>Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
>Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25))
|
||||
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
m() { },
|
||||
>m : Symbol(m, Decl(module.js, 1, 19))
|
||||
|
||||
i: 1
|
||||
>i : Symbol(i, Decl(module.js, 2, 12))
|
||||
}
|
||||
// incremental assignments still work
|
||||
Inner.prototype.j = 2
|
||||
>Inner.prototype : Symbol(Inner.j, Decl(module.js, 4, 1))
|
||||
>Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25))
|
||||
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
>j : Symbol(Inner.j, Decl(module.js, 4, 1))
|
||||
|
||||
/** @type {string} */
|
||||
Inner.prototype.k;
|
||||
>Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
>Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25))
|
||||
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
var inner = new Inner()
|
||||
>inner : Symbol(inner, Decl(module.js, 9, 3))
|
||||
>Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25))
|
||||
|
||||
inner.m()
|
||||
>inner.m : Symbol(m, Decl(module.js, 1, 19))
|
||||
>inner : Symbol(inner, Decl(module.js, 9, 3))
|
||||
>m : Symbol(m, Decl(module.js, 1, 19))
|
||||
|
||||
inner.i
|
||||
>inner.i : Symbol(i, Decl(module.js, 2, 12))
|
||||
>inner : Symbol(inner, Decl(module.js, 9, 3))
|
||||
>i : Symbol(i, Decl(module.js, 2, 12))
|
||||
|
||||
inner.j
|
||||
>inner.j : Symbol(Inner.j, Decl(module.js, 4, 1))
|
||||
>inner : Symbol(inner, Decl(module.js, 9, 3))
|
||||
>j : Symbol(Inner.j, Decl(module.js, 4, 1))
|
||||
|
||||
inner.k
|
||||
>inner.k : Symbol(Inner.k, Decl(module.js, 6, 21))
|
||||
>inner : Symbol(inner, Decl(module.js, 9, 3))
|
||||
>k : Symbol(Inner.k, Decl(module.js, 6, 21))
|
||||
|
||||
63
tests/baselines/reference/typeFromPropertyAssignment11.types
Normal file
63
tests/baselines/reference/typeFromPropertyAssignment11.types
Normal file
@ -0,0 +1,63 @@
|
||||
=== tests/cases/conformance/salsa/module.js ===
|
||||
var Inner = function() {}
|
||||
>Inner : () => void
|
||||
>function() {} : () => void
|
||||
|
||||
Inner.prototype = {
|
||||
>Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
|
||||
>Inner.prototype : any
|
||||
>Inner : () => void
|
||||
>prototype : any
|
||||
>{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
|
||||
|
||||
m() { },
|
||||
>m : () => void
|
||||
|
||||
i: 1
|
||||
>i : number
|
||||
>1 : 1
|
||||
}
|
||||
// incremental assignments still work
|
||||
Inner.prototype.j = 2
|
||||
>Inner.prototype.j = 2 : 2
|
||||
>Inner.prototype.j : any
|
||||
>Inner.prototype : any
|
||||
>Inner : () => void
|
||||
>prototype : any
|
||||
>j : any
|
||||
>2 : 2
|
||||
|
||||
/** @type {string} */
|
||||
Inner.prototype.k;
|
||||
>Inner.prototype.k : any
|
||||
>Inner.prototype : any
|
||||
>Inner : () => void
|
||||
>prototype : any
|
||||
>k : any
|
||||
|
||||
var inner = new Inner()
|
||||
>inner : { j: number; k: string; } & { [x: string]: any; m(): void; i: number; }
|
||||
>new Inner() : { j: number; k: string; } & { [x: string]: any; m(): void; i: number; }
|
||||
>Inner : () => void
|
||||
|
||||
inner.m()
|
||||
>inner.m() : void
|
||||
>inner.m : () => void
|
||||
>inner : { j: number; k: string; } & { [x: string]: any; m(): void; i: number; }
|
||||
>m : () => void
|
||||
|
||||
inner.i
|
||||
>inner.i : number
|
||||
>inner : { j: number; k: string; } & { [x: string]: any; m(): void; i: number; }
|
||||
>i : number
|
||||
|
||||
inner.j
|
||||
>inner.j : number
|
||||
>inner : { j: number; k: string; } & { [x: string]: any; m(): void; i: number; }
|
||||
>j : number
|
||||
|
||||
inner.k
|
||||
>inner.k : string
|
||||
>inner : { j: number; k: string; } & { [x: string]: any; m(): void; i: number; }
|
||||
>k : string
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: es6
|
||||
// @Filename: module.js
|
||||
var Inner = function() {}
|
||||
Inner.prototype = {
|
||||
m() { },
|
||||
i: 1
|
||||
}
|
||||
// incremental assignments still work
|
||||
Inner.prototype.j = 2
|
||||
/** @type {string} */
|
||||
Inner.prototype.k;
|
||||
var inner = new Inner()
|
||||
inner.m()
|
||||
inner.i
|
||||
inner.j
|
||||
inner.k
|
||||
Loading…
x
Reference in New Issue
Block a user