diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 053255fbaa7..92781227758 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2393,7 +2393,8 @@ namespace ts { function bindSpecialPropertyAssignment(node: BinaryExpression) { const lhs = node.left as PropertyAccessEntityNameExpression; // Fix up parent pointers since we're going to use these nodes before we bind into them - lhs.parent = node; + node.left.parent = node; + node.right.parent = node; if (isIdentifier(lhs.expression) && container === file && isNameOfExportsOrModuleExportsAliasDeclaration(file, lhs.expression)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; @@ -2444,7 +2445,9 @@ namespace ts { (symbol.exports || (symbol.exports = createSymbolTable())); // Declare the method/property - declareSymbol(symbolTable, symbol, propertyAccess, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + const symbolFlags = SymbolFlags.Property | (isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0); + const symbolExcludes = SymbolFlags.PropertyExcludes & ~(isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0); + declareSymbol(symbolTable, symbol, propertyAccess, symbolFlags, symbolExcludes); } function lookupSymbolForPropertyAccess(node: EntityNameExpression): Symbol | undefined { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4919a373d66..cbbd377fdaa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2002,21 +2002,7 @@ 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; const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name; let namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location); if (!namespace || nodeIsMissing(right)) { @@ -2025,8 +2011,11 @@ namespace ts { else if (namespace === unknownSymbol) { return namespace; } - if (isInJavaScriptFile(name) && isDeclarationOfFunctionOrClassExpression(namespace)) { - namespace = getSymbolOfNode((namespace.valueDeclaration as VariableDeclaration).initializer); + if (isInJavaScriptFile(name)) { + const initializer = getDeclaredJavascriptInitializer(namespace.valueDeclaration); + if (initializer) { + namespace = getSymbolOfNode(initializer); + } } symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning); if (!symbol) { @@ -7246,12 +7235,11 @@ namespace ts { // A jsdoc TypeReference may have resolved to a value (as opposed to a type). If // the symbol is a constructor function, return the inferred class type; otherwise, // the type of this reference is just the type of the value we resolved to. + const assignedType = getAssignedClassType(symbol); const valueType = getTypeOfSymbol(symbol); - if (valueType.symbol && !isInferredClassType(valueType)) { - const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments); - if (referenceType) { - return referenceType; - } + const referenceType = valueType.symbol && !isInferredClassType(valueType) && getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments); + if (referenceType || assignedType) { + return referenceType && assignedType ? getIntersectionType([assignedType, referenceType]) : referenceType || assignedType; } // Resolve the type reference as a Type for the purpose of reporting errors. @@ -17894,23 +17882,22 @@ namespace ts { } function getJavaScriptClassType(symbol: Symbol): Type | undefined { - if (isDeclarationOfFunctionOrClassExpression(symbol)) { - symbol = getSymbolOfNode((symbol.valueDeclaration as VariableDeclaration).initializer); + const initializer = getDeclaredJavascriptInitializer(symbol.valueDeclaration); + if (initializer) { + symbol = getSymbolOfNode(initializer); } - let assigned = getAssignedClassType(symbol); let inferred: Type | undefined; if (isJavaScriptConstructor(symbol.valueDeclaration)) { inferred = getInferredClassType(symbol); } - if (symbol.flags & SymbolFlags.Variable) { - const valueType = getTypeOfSymbol(symbol); - if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { - inferred = getInferredClassType(valueType.symbol); - } + const assigned = getAssignedClassType(symbol); + const valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { + inferred = getInferredClassType(valueType.symbol); } - return !inferred ? assigned : - !assigned ? inferred : - getIntersectionType([inferred, assigned]); + return assigned && inferred ? + getIntersectionType([inferred, assigned]) : + assigned || inferred; } function getAssignedClassType(symbol: Symbol) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index cbccc071399..aabfd762ffb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3243,8 +3243,8 @@ namespace ts { Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, - Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor, - Type = Class | Interface | Enum | EnumMember | TypeLiteral | ObjectLiteral | TypeParameter | TypeAlias, + Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | JSContainer, + Type = Class | Interface | Enum | EnumMember | TypeLiteral | ObjectLiteral | TypeParameter | TypeAlias | JSContainer, Namespace = ValueModule | NamespaceModule | Enum, Module = ValueModule | NamespaceModule, Accessor = GetAccessor | SetAccessor, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 420ce4bdf09..e7bbaf966d6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1471,18 +1471,6 @@ namespace ts { return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === CharacterCodes.doubleQuote; } - /** - * Returns true if the node is a variable declaration whose initializer is a function or class expression. - * This function does not test if the node is in a JavaScript file or not. - */ - export function isDeclarationOfFunctionOrClassExpression(s: Symbol) { - if (s.valueDeclaration && isVariableDeclaration(s.valueDeclaration)) { - return s.valueDeclaration.initializer && - (s.valueDeclaration.initializer.kind === SyntaxKind.FunctionExpression || s.valueDeclaration.initializer.kind === SyntaxKind.ClassExpression); - } - return false; - } - export function getJSInitializerSymbol(symbol: Symbol) { if (!symbol || !symbol.valueDeclaration) { return symbol; diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index ddb13c3e04c..7f5ea7c68d9 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -16,8 +16,9 @@ namespace ts.refactor.convertFunctionToES6Class { return undefined; } - if (isDeclarationOfFunctionOrClassExpression(symbol)) { - symbol = (symbol.valueDeclaration as VariableDeclaration).initializer.symbol; + const initializer = getDeclaredJavascriptInitializer(symbol.valueDeclaration); + if (initializer) { + symbol = initializer.symbol; } if ((symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) { @@ -264,4 +265,4 @@ namespace ts.refactor.convertFunctionToES6Class { const token = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); return checker.getSymbolAtLocation(token); } -} \ No newline at end of file +} diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 86a33c179a3..e136d0ac86f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1956,28 +1956,28 @@ declare namespace ts { JSContainer = 67108864, Enum = 384, Variable = 3, - Value = 107455, - Type = 793064, + Value = 67216319, + Type = 67901928, Namespace = 1920, Module = 1536, Accessor = 98304, - FunctionScopedVariableExcludes = 107454, - BlockScopedVariableExcludes = 107455, - ParameterExcludes = 107455, + FunctionScopedVariableExcludes = 67216318, + BlockScopedVariableExcludes = 67216319, + ParameterExcludes = 67216319, PropertyExcludes = 0, - EnumMemberExcludes = 900095, - FunctionExcludes = 106927, - ClassExcludes = 899519, - InterfaceExcludes = 792968, - RegularEnumExcludes = 899327, - ConstEnumExcludes = 899967, - ValueModuleExcludes = 106639, + EnumMemberExcludes = 68008959, + FunctionExcludes = 67215791, + ClassExcludes = 68008383, + InterfaceExcludes = 67901832, + RegularEnumExcludes = 68008191, + ConstEnumExcludes = 68008831, + ValueModuleExcludes = 67215503, NamespaceModuleExcludes = 0, - MethodExcludes = 99263, - GetAccessorExcludes = 41919, - SetAccessorExcludes = 74687, - TypeParameterExcludes = 530920, - TypeAliasExcludes = 793064, + MethodExcludes = 67208127, + GetAccessorExcludes = 67150783, + SetAccessorExcludes = 67183551, + TypeParameterExcludes = 67639784, + TypeAliasExcludes = 67901928, AliasExcludes = 2097152, ModuleMember = 2623475, ExportHasLocal = 944, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 1c3c13f48b0..577b4680f36 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1956,28 +1956,28 @@ declare namespace ts { JSContainer = 67108864, Enum = 384, Variable = 3, - Value = 107455, - Type = 793064, + Value = 67216319, + Type = 67901928, Namespace = 1920, Module = 1536, Accessor = 98304, - FunctionScopedVariableExcludes = 107454, - BlockScopedVariableExcludes = 107455, - ParameterExcludes = 107455, + FunctionScopedVariableExcludes = 67216318, + BlockScopedVariableExcludes = 67216319, + ParameterExcludes = 67216319, PropertyExcludes = 0, - EnumMemberExcludes = 900095, - FunctionExcludes = 106927, - ClassExcludes = 899519, - InterfaceExcludes = 792968, - RegularEnumExcludes = 899327, - ConstEnumExcludes = 899967, - ValueModuleExcludes = 106639, + EnumMemberExcludes = 68008959, + FunctionExcludes = 67215791, + ClassExcludes = 68008383, + InterfaceExcludes = 67901832, + RegularEnumExcludes = 68008191, + ConstEnumExcludes = 68008831, + ValueModuleExcludes = 67215503, NamespaceModuleExcludes = 0, - MethodExcludes = 99263, - GetAccessorExcludes = 41919, - SetAccessorExcludes = 74687, - TypeParameterExcludes = 530920, - TypeAliasExcludes = 793064, + MethodExcludes = 67208127, + GetAccessorExcludes = 67150783, + SetAccessorExcludes = 67183551, + TypeParameterExcludes = 67639784, + TypeAliasExcludes = 67901928, AliasExcludes = 2097152, ModuleMember = 2623475, ExportHasLocal = 944, diff --git a/tests/baselines/reference/typeFromPropertyAssignment14.symbols b/tests/baselines/reference/typeFromPropertyAssignment14.symbols new file mode 100644 index 00000000000..3f5035e24ad --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment14.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/salsa/def.js === +var Outer = {}; +>Outer : Symbol(Outer, Decl(def.js, 0, 3), Decl(work.js, 0, 0), Decl(work.js, 0, 28)) + +=== tests/cases/conformance/salsa/work.js === +Outer.Inner = function () {} +>Outer.Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) +>Outer : Symbol(Outer, Decl(def.js, 0, 3), Decl(work.js, 0, 0), Decl(work.js, 0, 28)) +>Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) + +Outer.Inner.prototype = { +>Outer.Inner.prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) +>Outer.Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) +>Outer : Symbol(Outer, Decl(def.js, 0, 3), Decl(work.js, 0, 0), Decl(work.js, 0, 28)) +>Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) +>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) + + x: 1, +>x : Symbol(x, Decl(work.js, 1, 25)) + + m() { } +>m : Symbol(m, Decl(work.js, 2, 9)) +} + +=== tests/cases/conformance/salsa/use.js === +/** @type {Outer.Inner} */ +var inner +>inner : Symbol(inner, Decl(use.js, 1, 3)) + +inner.x +>inner.x : Symbol(x, Decl(work.js, 1, 25)) +>inner : Symbol(inner, Decl(use.js, 1, 3)) +>x : Symbol(x, Decl(work.js, 1, 25)) + +inner.m() +>inner.m : Symbol(m, Decl(work.js, 2, 9)) +>inner : Symbol(inner, Decl(use.js, 1, 3)) +>m : Symbol(m, Decl(work.js, 2, 9)) + +var inno = new Outer.Inner() +>inno : Symbol(inno, Decl(use.js, 4, 3)) +>Outer.Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) +>Outer : Symbol(Outer, Decl(def.js, 0, 3), Decl(work.js, 0, 0), Decl(work.js, 0, 28)) +>Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) + +inno.x +>inno.x : Symbol(x, Decl(work.js, 1, 25)) +>inno : Symbol(inno, Decl(use.js, 4, 3)) +>x : Symbol(x, Decl(work.js, 1, 25)) + +inno.m() +>inno.m : Symbol(m, Decl(work.js, 2, 9)) +>inno : Symbol(inno, Decl(use.js, 4, 3)) +>m : Symbol(m, Decl(work.js, 2, 9)) + + + diff --git a/tests/baselines/reference/typeFromPropertyAssignment14.types b/tests/baselines/reference/typeFromPropertyAssignment14.types new file mode 100644 index 00000000000..10a3fa00e35 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment14.types @@ -0,0 +1,66 @@ +=== tests/cases/conformance/salsa/def.js === +var Outer = {}; +>Outer : typeof Outer +>{} : typeof Outer + +=== tests/cases/conformance/salsa/work.js === +Outer.Inner = function () {} +>Outer.Inner = function () {} : () => void +>Outer.Inner : () => void +>Outer : typeof Outer +>Inner : () => void +>function () {} : () => void + +Outer.Inner.prototype = { +>Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } +>Outer.Inner.prototype : any +>Outer.Inner : () => void +>Outer : typeof Outer +>Inner : () => void +>prototype : any +>{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } + + x: 1, +>x : number +>1 : 1 + + m() { } +>m : () => void +} + +=== tests/cases/conformance/salsa/use.js === +/** @type {Outer.Inner} */ +var inner +>inner : { [x: string]: any; x: number; m(): void; } + +inner.x +>inner.x : number +>inner : { [x: string]: any; x: number; m(): void; } +>x : number + +inner.m() +>inner.m() : void +>inner.m : () => void +>inner : { [x: string]: any; x: number; m(): void; } +>m : () => void + +var inno = new Outer.Inner() +>inno : { [x: string]: any; x: number; m(): void; } +>new Outer.Inner() : { [x: string]: any; x: number; m(): void; } +>Outer.Inner : () => void +>Outer : typeof Outer +>Inner : () => void + +inno.x +>inno.x : number +>inno : { [x: string]: any; x: number; m(): void; } +>x : number + +inno.m() +>inno.m() : void +>inno.m : () => void +>inno : { [x: string]: any; x: number; m(): void; } +>m : () => void + + + diff --git a/tests/baselines/reference/typeFromPropertyAssignment15.symbols b/tests/baselines/reference/typeFromPropertyAssignment15.symbols new file mode 100644 index 00000000000..21db92c0b9e --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment15.symbols @@ -0,0 +1,49 @@ +=== tests/cases/conformance/salsa/a.js === +var Outer = {}; +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15)) + +Outer.Inner = class { +>Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15)) +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15)) +>Inner : Symbol(Inner, Decl(a.js, 0, 15)) + + constructor() { + this.x = 1 +>this.x : Symbol((Anonymous class).x, Decl(a.js, 3, 19)) +>this : Symbol((Anonymous class), Decl(a.js, 2, 13)) +>x : Symbol((Anonymous class).x, Decl(a.js, 3, 19)) + } + m() { } +>m : Symbol((Anonymous class).m, Decl(a.js, 5, 5)) +} + +/** @type {Outer.Inner} */ +var inner +>inner : Symbol(inner, Decl(a.js, 10, 3)) + +inner.x +>inner.x : Symbol((Anonymous class).x, Decl(a.js, 3, 19)) +>inner : Symbol(inner, Decl(a.js, 10, 3)) +>x : Symbol((Anonymous class).x, Decl(a.js, 3, 19)) + +inner.m() +>inner.m : Symbol((Anonymous class).m, Decl(a.js, 5, 5)) +>inner : Symbol(inner, Decl(a.js, 10, 3)) +>m : Symbol((Anonymous class).m, Decl(a.js, 5, 5)) + +var inno = new Outer.Inner() +>inno : Symbol(inno, Decl(a.js, 13, 3)) +>Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15)) +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15)) +>Inner : Symbol(Inner, Decl(a.js, 0, 15)) + +inno.x +>inno.x : Symbol((Anonymous class).x, Decl(a.js, 3, 19)) +>inno : Symbol(inno, Decl(a.js, 13, 3)) +>x : Symbol((Anonymous class).x, Decl(a.js, 3, 19)) + +inno.m() +>inno.m : Symbol((Anonymous class).m, Decl(a.js, 5, 5)) +>inno : Symbol(inno, Decl(a.js, 13, 3)) +>m : Symbol((Anonymous class).m, Decl(a.js, 5, 5)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment15.types b/tests/baselines/reference/typeFromPropertyAssignment15.types new file mode 100644 index 00000000000..e875dd9e970 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment15.types @@ -0,0 +1,57 @@ +=== tests/cases/conformance/salsa/a.js === +var Outer = {}; +>Outer : { [x: string]: any; Inner: typeof (Anonymous class); } +>{} : { [x: string]: any; Inner: typeof (Anonymous class); } + +Outer.Inner = class { +>Outer.Inner = class { constructor() { this.x = 1 } m() { }} : typeof (Anonymous class) +>Outer.Inner : typeof (Anonymous class) +>Outer : { [x: string]: any; Inner: typeof (Anonymous class); } +>Inner : typeof (Anonymous class) +>class { constructor() { this.x = 1 } m() { }} : typeof (Anonymous class) + + constructor() { + this.x = 1 +>this.x = 1 : 1 +>this.x : number +>this : this +>x : number +>1 : 1 + } + m() { } +>m : () => void +} + +/** @type {Outer.Inner} */ +var inner +>inner : (Anonymous class) + +inner.x +>inner.x : number +>inner : (Anonymous class) +>x : number + +inner.m() +>inner.m() : void +>inner.m : () => void +>inner : (Anonymous class) +>m : () => void + +var inno = new Outer.Inner() +>inno : (Anonymous class) +>new Outer.Inner() : (Anonymous class) +>Outer.Inner : typeof (Anonymous class) +>Outer : { [x: string]: any; Inner: typeof (Anonymous class); } +>Inner : typeof (Anonymous class) + +inno.x +>inno.x : number +>inno : (Anonymous class) +>x : number + +inno.m() +>inno.m() : void +>inno.m : () => void +>inno : (Anonymous class) +>m : () => void + diff --git a/tests/baselines/reference/typeFromPropertyAssignment16.symbols b/tests/baselines/reference/typeFromPropertyAssignment16.symbols new file mode 100644 index 00000000000..e7fbaed599c --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment16.symbols @@ -0,0 +1,53 @@ +=== tests/cases/conformance/salsa/a.js === +var Outer = {}; +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) + +Outer.Inner = function () {} +>Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) +>Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) + +Outer.Inner.prototype = { +>Outer.Inner.prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) +>Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) +>Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) + + x: 1, +>x : Symbol(x, Decl(a.js, 3, 25)) + + m() { } +>m : Symbol(m, Decl(a.js, 4, 9)) +} + +/** @type {Outer.Inner} */ +var inner +>inner : Symbol(inner, Decl(a.js, 9, 3)) + +inner.x +>inner.x : Symbol(x, Decl(a.js, 3, 25)) +>inner : Symbol(inner, Decl(a.js, 9, 3)) +>x : Symbol(x, Decl(a.js, 3, 25)) + +inner.m() +>inner.m : Symbol(m, Decl(a.js, 4, 9)) +>inner : Symbol(inner, Decl(a.js, 9, 3)) +>m : Symbol(m, Decl(a.js, 4, 9)) + +var inno = new Outer.Inner() +>inno : Symbol(inno, Decl(a.js, 12, 3)) +>Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) +>Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) + +inno.x +>inno.x : Symbol(x, Decl(a.js, 3, 25)) +>inno : Symbol(inno, Decl(a.js, 12, 3)) +>x : Symbol(x, Decl(a.js, 3, 25)) + +inno.m() +>inno.m : Symbol(m, Decl(a.js, 4, 9)) +>inno : Symbol(inno, Decl(a.js, 12, 3)) +>m : Symbol(m, Decl(a.js, 4, 9)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment16.types b/tests/baselines/reference/typeFromPropertyAssignment16.types new file mode 100644 index 00000000000..a1167f3da6e --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment16.types @@ -0,0 +1,62 @@ +=== tests/cases/conformance/salsa/a.js === +var Outer = {}; +>Outer : { [x: string]: any; Inner: () => void; } +>{} : { [x: string]: any; Inner: () => void; } + +Outer.Inner = function () {} +>Outer.Inner = function () {} : () => void +>Outer.Inner : () => void +>Outer : { [x: string]: any; Inner: () => void; } +>Inner : () => void +>function () {} : () => void + +Outer.Inner.prototype = { +>Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } +>Outer.Inner.prototype : any +>Outer.Inner : () => void +>Outer : { [x: string]: any; Inner: () => void; } +>Inner : () => void +>prototype : any +>{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } + + x: 1, +>x : number +>1 : 1 + + m() { } +>m : () => void +} + +/** @type {Outer.Inner} */ +var inner +>inner : { [x: string]: any; x: number; m(): void; } + +inner.x +>inner.x : number +>inner : { [x: string]: any; x: number; m(): void; } +>x : number + +inner.m() +>inner.m() : void +>inner.m : () => void +>inner : { [x: string]: any; x: number; m(): void; } +>m : () => void + +var inno = new Outer.Inner() +>inno : { [x: string]: any; x: number; m(): void; } +>new Outer.Inner() : { [x: string]: any; x: number; m(): void; } +>Outer.Inner : () => void +>Outer : { [x: string]: any; Inner: () => void; } +>Inner : () => void + +inno.x +>inno.x : number +>inno : { [x: string]: any; x: number; m(): void; } +>x : number + +inno.m() +>inno.m() : void +>inno.m : () => void +>inno : { [x: string]: any; x: number; m(): void; } +>m : () => void + diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment14.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment14.ts new file mode 100644 index 00000000000..b3aaaf1702b --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment14.ts @@ -0,0 +1,23 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: def.js +var Outer = {}; + +// @Filename: work.js +Outer.Inner = function () {} +Outer.Inner.prototype = { + x: 1, + m() { } +} + +// @Filename: use.js +/** @type {Outer.Inner} */ +var inner +inner.x +inner.m() +var inno = new Outer.Inner() +inno.x +inno.m() + + diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment15.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment15.ts new file mode 100644 index 00000000000..c8099a03395 --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment15.ts @@ -0,0 +1,20 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: a.js +var Outer = {}; + +Outer.Inner = class { + constructor() { + this.x = 1 + } + m() { } +} + +/** @type {Outer.Inner} */ +var inner +inner.x +inner.m() +var inno = new Outer.Inner() +inno.x +inno.m() diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment16.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment16.ts new file mode 100644 index 00000000000..534e3bcc4c3 --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment16.ts @@ -0,0 +1,19 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: a.js +var Outer = {}; + +Outer.Inner = function () {} +Outer.Inner.prototype = { + x: 1, + m() { } +} + +/** @type {Outer.Inner} */ +var inner +inner.x +inner.m() +var inno = new Outer.Inner() +inno.x +inno.m()