From 88c67fa7779ee97a3743bc203a08d39deb41dadf Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 13 Feb 2018 15:44:15 -0800 Subject: [PATCH] Refactor binder and update baselines. Also improve assert message in fourslash. --- src/compiler/binder.ts | 49 +++-- src/harness/fourslash.ts | 2 +- .../typeFromPropertyAssignment10.symbols | 141 ++++++++++++++ .../typeFromPropertyAssignment10.types | 174 ++++++++++++++++++ .../typeFromPropertyAssignment8.symbols | 54 +++--- .../typeFromPropertyAssignment9.symbols | 74 ++++---- .../salsa/typeFromPropertyAssignment10.ts | 48 +++++ .../codeFixUndeclaredAcrossFiles1.ts | 2 +- 8 files changed, 452 insertions(+), 92 deletions(-) create mode 100644 tests/baselines/reference/typeFromPropertyAssignment10.symbols create mode 100644 tests/baselines/reference/typeFromPropertyAssignment10.types create mode 100644 tests/cases/conformance/salsa/typeFromPropertyAssignment10.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6dbc89ab3ef..a26a2b0af24 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2408,65 +2408,62 @@ namespace ts { } } + function isValidInitializer(initializer: Node) { + return initializer.kind === SyntaxKind.ClassExpression || + initializer.kind === SyntaxKind.FunctionExpression || + initializer.kind === SyntaxKind.ObjectLiteralExpression && (initializer as ObjectLiteralExpression).properties.length === 0 || + initializer.kind === SyntaxKind.CallExpression && (skipParentheses((initializer as CallExpression).expression).kind === SyntaxKind.FunctionExpression || + skipParentheses((initializer as CallExpression).expression).kind === SyntaxKind.ArrowFunction); + } + function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) { // Look up the property in the local scope, since property assignments should follow the declaration - const symbol = lookupSymbolForPropertyAccess(name); + let symbol = follow(lookupSymbolForPropertyAccess(name)); // TODO: Should be able to structure this with less duplication - let targetSymbol = follow(symbol); Debug.assert(propertyAccess.parent.kind === SyntaxKind.BinaryExpression || propertyAccess.parent.kind === SyntaxKind.ExpressionStatement || propertyAccess.parent.kind === SyntaxKind.PropertyAccessExpression); - let isLegalPosition: boolean; - if (propertyAccess.parent.kind === SyntaxKind.BinaryExpression) { - const initializerKind = (propertyAccess.parent as BinaryExpression).right.kind; - isLegalPosition = (initializerKind === SyntaxKind.ClassExpression || initializerKind === SyntaxKind.FunctionExpression) && - propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile; - if (propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile && initializerKind === SyntaxKind.BinaryExpression && (((propertyAccess.parent as BinaryExpression).right as BinaryExpression).right.kind === SyntaxKind.ClassExpression || ((propertyAccess.parent as BinaryExpression).right as BinaryExpression).right.kind === SyntaxKind.FunctionExpression)) { - isLegalPosition = true; - } - } - else { - isLegalPosition = propertyAccess.parent.parent.kind === SyntaxKind.SourceFile; - } - if (!isPrototypeProperty && (!targetSymbol || !(targetSymbol.flags & SymbolFlags.Namespace)) && isLegalPosition) { + const isLegalPosition = propertyAccess.parent.kind === SyntaxKind.BinaryExpression ? + propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile && isValidInitializer((propertyAccess.parent as BinaryExpression).right) : + propertyAccess.parent.parent.kind === SyntaxKind.SourceFile; + if (!isPrototypeProperty && (!symbol || !(symbol.flags & SymbolFlags.Namespace)) && isLegalPosition) { const flags = SymbolFlags.Module | SymbolFlags.JSContainer; const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer; - // const startTargetSymbol = !!targetSymbol; // hm. This is only needed to make namespaced access of types workable. Namespaced access of *values* doesn't work now either, so something is wrong. // (Note: for the non-nested case, at least, addDeclarationToSymbol is only needed for things that could be further namespaces, because it // makes the intermediate namespace. However, I think something like it is needed for *all* nested assignments, in case their intermediate namespaces don't exist) iterateEntityNameExpression(propertyAccess.expression, (id, originalSymbol, available) => { - if (targetSymbol) { + if (symbol) { if (available) { // Note: add declaration to original symbol, not the special-syntax's symbol, so that namespaces work for type lookup addDeclarationToSymbol(originalSymbol, id, flags); - // TODO: Why can't I overwrite targetSymbol here? I'm having trouble tracking targetSymbol's state. + // TODO: Why can't I overwrite symbol here? I'm having trouble tracking symbol's state. return originalSymbol; } else { originalSymbol.exports = originalSymbol.exports || createSymbolTable(); - targetSymbol = declareSymbol(originalSymbol.exports, originalSymbol, id, flags, excludeFlags); - return targetSymbol; + symbol = declareSymbol(originalSymbol.exports, originalSymbol, id, flags, excludeFlags); + return symbol; } } else { Debug.assert(!available); - targetSymbol = declareSymbol(container.locals, /*parent*/ undefined, id, flags, excludeFlags); - return targetSymbol; + symbol = declareSymbol(container.locals, /*parent*/ undefined, id, flags, excludeFlags); + return symbol; } }); } - if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule | SymbolFlags.ObjectLiteral))) { + if (!symbol || !(symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule | SymbolFlags.ObjectLiteral))) { return; } // Set up the members collection if it doesn't exist already const symbolTable = isPrototypeProperty ? - (targetSymbol.members || (targetSymbol.members = createSymbolTable())) : - (targetSymbol.exports || (targetSymbol.exports = createSymbolTable())); + (symbol.members || (symbol.members = createSymbolTable())) : + (symbol.exports || (symbol.exports = createSymbolTable())); // Declare the method/property - declareSymbol(symbolTable, targetSymbol, propertyAccess, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + declareSymbol(symbolTable, symbol, propertyAccess, SymbolFlags.Property, SymbolFlags.PropertyExcludes); } function iterateEntityNameExpression(e: EntityNameExpression, action: (e: Identifier, originalSymbol: Symbol, available: boolean) => Symbol): Symbol { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 71df206c078..5758d30a08a 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -844,7 +844,7 @@ namespace FourSlash { const actual = actualCompletions.entries; if (actual.length !== expected.length) { - this.raiseError(`Expected ${expected.length} completions, got ${actual.map(a => a.name)}.`); + this.raiseError(`Expected ${expected.length} completions, got ${actual.length} (${actual.map(a => a.name)}).`); } ts.zipWith(actual, expected, (completion, expectedCompletion, index) => { diff --git a/tests/baselines/reference/typeFromPropertyAssignment10.symbols b/tests/baselines/reference/typeFromPropertyAssignment10.symbols new file mode 100644 index 00000000000..55c3f1dfcef --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment10.symbols @@ -0,0 +1,141 @@ +=== tests/cases/conformance/salsa/module.js === +var Outer = Outer || {}; +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) + +Outer.app = Outer.app || {}; +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) + +=== tests/cases/conformance/salsa/someview.js === +Outer.app.SomeView = (function () { +>Outer.app.SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) + + var SomeView = function() { +>SomeView : Symbol(SomeView, Decl(someview.js, 1, 7)) + + var me = this; +>me : Symbol(me, Decl(someview.js, 2, 11)) + } + return SomeView; +>SomeView : Symbol(SomeView, Decl(someview.js, 1, 7)) + +})(); +Outer.app.Inner = class { +>Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) + + constructor() { + /** @type {number} */ + this.y = 12; +>this.y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) +>this : Symbol((Anonymous class), Decl(someview.js, 6, 17)) +>y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) + } +} +var example = new Outer.app.Inner(); +>example : Symbol(example, Decl(someview.js, 12, 3)) +>Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) + +example.y; +>example.y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) +>example : Symbol(example, Decl(someview.js, 12, 3)) +>y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) + +/** @param {number} k */ +Outer.app.statische = function (k) { +>Outer.app.statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) +>k : Symbol(k, Decl(someview.js, 15, 32)) + + return k ** k; +>k : Symbol(k, Decl(someview.js, 15, 32)) +>k : Symbol(k, Decl(someview.js, 15, 32)) +} +=== tests/cases/conformance/salsa/application.js === +Outer.app.Application = (function () { +>Outer.app.Application : Symbol(app.Application, Decl(application.js, 0, 0)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Application : Symbol(app.Application, Decl(application.js, 0, 0)) + + /** + * Application main class. + * Will be instantiated & initialized by HTML page + */ + var Application = function () { +>Application : Symbol(Application, Decl(application.js, 6, 7)) + + var me = this; +>me : Symbol(me, Decl(application.js, 7, 11)) + + me.view = new Outer.app.SomeView(); +>me : Symbol(me, Decl(application.js, 7, 11)) +>Outer.app.SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) + + }; + return Application; +>Application : Symbol(Application, Decl(application.js, 6, 7)) + +})(); +=== tests/cases/conformance/salsa/main.js === +var app = new Outer.app.Application(); +>app : Symbol(app, Decl(main.js, 0, 3)) +>Outer.app.Application : Symbol(app.Application, Decl(application.js, 0, 0)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Application : Symbol(app.Application, Decl(application.js, 0, 0)) + +var inner = new Outer.app.Inner(); +>inner : Symbol(inner, Decl(main.js, 1, 3)) +>Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) + +inner.y; +>inner.y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) +>inner : Symbol(inner, Decl(main.js, 1, 3)) +>y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) + +/** @type {Outer.app.Inner} */ +var x; +>x : Symbol(x, Decl(main.js, 4, 3)) + +x.y; +>x.y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) +>x : Symbol(x, Decl(main.js, 4, 3)) +>y : Symbol((Anonymous class).y, Decl(someview.js, 7, 19)) + +Outer.app.statische(101); // Infinity, duh +>Outer.app.statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) +>Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) +>app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment10.types b/tests/baselines/reference/typeFromPropertyAssignment10.types new file mode 100644 index 00000000000..9dad053c099 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment10.types @@ -0,0 +1,174 @@ +=== tests/cases/conformance/salsa/module.js === +var Outer = Outer || {}; +>Outer : typeof __object +>Outer || {} : typeof __object +>Outer : typeof __object +>{} : typeof __object + +Outer.app = Outer.app || {}; +>Outer.app = Outer.app || {} : typeof __object +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>Outer.app || {} : typeof __object +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>{} : typeof __object + +=== tests/cases/conformance/salsa/someview.js === +Outer.app.SomeView = (function () { +>Outer.app.SomeView = (function () { var SomeView = function() { var me = this; } return SomeView;})() : () => void +>Outer.app.SomeView : () => void +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>SomeView : () => void +>(function () { var SomeView = function() { var me = this; } return SomeView;})() : () => void +>(function () { var SomeView = function() { var me = this; } return SomeView;}) : () => () => void +>function () { var SomeView = function() { var me = this; } return SomeView;} : () => () => void + + var SomeView = function() { +>SomeView : () => void +>function() { var me = this; } : () => void + + var me = this; +>me : any +>this : any + } + return SomeView; +>SomeView : () => void + +})(); +Outer.app.Inner = class { +>Outer.app.Inner = class { constructor() { /** @type {number} */ this.y = 12; }} : typeof (Anonymous class) +>Outer.app.Inner : typeof (Anonymous class) +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>Inner : typeof (Anonymous class) +>class { constructor() { /** @type {number} */ this.y = 12; }} : typeof (Anonymous class) + + constructor() { + /** @type {number} */ + this.y = 12; +>this.y = 12 : 12 +>this.y : number +>this : this +>y : number +>12 : 12 + } +} +var example = new Outer.app.Inner(); +>example : (Anonymous class) +>new Outer.app.Inner() : (Anonymous class) +>Outer.app.Inner : typeof (Anonymous class) +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>Inner : typeof (Anonymous class) + +example.y; +>example.y : number +>example : (Anonymous class) +>y : number + +/** @param {number} k */ +Outer.app.statische = function (k) { +>Outer.app.statische = function (k) { return k ** k;} : (k: number) => number +>Outer.app.statische : (k: number) => number +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>statische : (k: number) => number +>function (k) { return k ** k;} : (k: number) => number +>k : number + + return k ** k; +>k ** k : number +>k : number +>k : number +} +=== tests/cases/conformance/salsa/application.js === +Outer.app.Application = (function () { +>Outer.app.Application = (function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;})() : () => void +>Outer.app.Application : () => void +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>Application : () => void +>(function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;})() : () => void +>(function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;}) : () => () => void +>function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;} : () => () => void + + /** + * Application main class. + * Will be instantiated & initialized by HTML page + */ + var Application = function () { +>Application : () => void +>function () { var me = this; me.view = new Outer.app.SomeView(); } : () => void + + var me = this; +>me : any +>this : any + + me.view = new Outer.app.SomeView(); +>me.view = new Outer.app.SomeView() : any +>me.view : any +>me : any +>view : any +>new Outer.app.SomeView() : any +>Outer.app.SomeView : () => void +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>SomeView : () => void + + }; + return Application; +>Application : () => void + +})(); +=== tests/cases/conformance/salsa/main.js === +var app = new Outer.app.Application(); +>app : any +>new Outer.app.Application() : any +>Outer.app.Application : () => void +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>Application : () => void + +var inner = new Outer.app.Inner(); +>inner : (Anonymous class) +>new Outer.app.Inner() : (Anonymous class) +>Outer.app.Inner : typeof (Anonymous class) +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>Inner : typeof (Anonymous class) + +inner.y; +>inner.y : number +>inner : (Anonymous class) +>y : number + +/** @type {Outer.app.Inner} */ +var x; +>x : (Anonymous class) + +x.y; +>x.y : number +>x : (Anonymous class) +>y : number + +Outer.app.statische(101); // Infinity, duh +>Outer.app.statische(101) : number +>Outer.app.statische : (k: number) => number +>Outer.app : typeof __object +>Outer : typeof __object +>app : typeof __object +>statische : (k: number) => number +>101 : 101 + diff --git a/tests/baselines/reference/typeFromPropertyAssignment8.symbols b/tests/baselines/reference/typeFromPropertyAssignment8.symbols index 92dd284943a..99488e3d85a 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment8.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment8.symbols @@ -1,21 +1,21 @@ === tests/cases/conformance/salsa/a.js === var my = my || {}; ->my : Symbol(my, Decl(a.js, 0, 3)) ->my : Symbol(my, Decl(a.js, 0, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 1, 22)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 1, 22)) my.app = my.app || {}; ->my.app : Symbol(app, Decl(a.js, 0, 18)) ->my : Symbol(my, Decl(a.js, 0, 3)) ->app : Symbol(app, Decl(a.js, 0, 18)) ->my.app : Symbol(app, Decl(a.js, 0, 18)) ->my : Symbol(my, Decl(a.js, 0, 3)) ->app : Symbol(app, Decl(a.js, 0, 18)) +>my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 1, 22)) +>app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 1, 22)) +>app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) my.app.Application = (function () { >my.app.Application : Symbol(Application, Decl(a.js, 1, 22)) ->my.app : Symbol(app, Decl(a.js, 0, 18)) ->my : Symbol(my, Decl(a.js, 0, 3)) ->app : Symbol(app, Decl(a.js, 0, 18)) +>my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 1, 22)) +>app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) >Application : Symbol(Application, Decl(a.js, 1, 22)) var Application = function () { @@ -29,29 +29,29 @@ return Application; })(); my.app.Application() >my.app.Application : Symbol(Application, Decl(a.js, 1, 22)) ->my.app : Symbol(app, Decl(a.js, 0, 18)) ->my : Symbol(my, Decl(a.js, 0, 3)) ->app : Symbol(app, Decl(a.js, 0, 18)) +>my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 1, 22)) +>app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) >Application : Symbol(Application, Decl(a.js, 1, 22)) === tests/cases/conformance/salsa/b.js === var min = window.min || {}; ->min : Symbol(min, Decl(b.js, 0, 3)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 1, 24)) >window : Symbol(window, Decl(lib.dom.d.ts, --, --)) min.app = min.app || {}; ->min.app : Symbol(app, Decl(b.js, 0, 27)) ->min : Symbol(min, Decl(b.js, 0, 3)) ->app : Symbol(app, Decl(b.js, 0, 27)) ->min.app : Symbol(app, Decl(b.js, 0, 27)) ->min : Symbol(min, Decl(b.js, 0, 3)) ->app : Symbol(app, Decl(b.js, 0, 27)) +>min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 1, 24)) +>app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 1, 24)) +>app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) min.app.Application = (function () { >min.app.Application : Symbol(Application, Decl(b.js, 1, 24)) ->min.app : Symbol(app, Decl(b.js, 0, 27)) ->min : Symbol(min, Decl(b.js, 0, 3)) ->app : Symbol(app, Decl(b.js, 0, 27)) +>min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 1, 24)) +>app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) >Application : Symbol(Application, Decl(b.js, 1, 24)) var Application = function () { @@ -65,8 +65,8 @@ return Application; })(); min.app.Application() >min.app.Application : Symbol(Application, Decl(b.js, 1, 24)) ->min.app : Symbol(app, Decl(b.js, 0, 27)) ->min : Symbol(min, Decl(b.js, 0, 3)) ->app : Symbol(app, Decl(b.js, 0, 27)) +>min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 1, 24)) +>app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) >Application : Symbol(Application, Decl(b.js, 1, 24)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment9.symbols b/tests/baselines/reference/typeFromPropertyAssignment9.symbols index ccf78f89dd8..282275b556c 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment9.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment9.symbols @@ -1,12 +1,12 @@ === tests/cases/conformance/salsa/a.js === var my = my || {}; ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) /** @param {number} n */ my.method = function(n) { >my.method : Symbol(method, Decl(a.js, 0, 18)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) >method : Symbol(method, Decl(a.js, 0, 18)) >n : Symbol(n, Decl(a.js, 2, 21)) @@ -15,27 +15,27 @@ my.method = function(n) { } my.number = 1; >my.number : Symbol(number, Decl(a.js, 4, 1)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) >number : Symbol(number, Decl(a.js, 4, 1)) my.object = {}; >my.object : Symbol(object, Decl(a.js, 5, 14)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) >object : Symbol(object, Decl(a.js, 5, 14)) my.predicate = my.predicate || {}; ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) my.predicate.query = function () { >my.predicate.query : Symbol(query, Decl(a.js, 7, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) >query : Symbol(query, Decl(a.js, 7, 34)) var me = this; @@ -49,17 +49,17 @@ my.predicate.query = function () { var q = new my.predicate.query(); >q : Symbol(q, Decl(a.js, 12, 3)) >my.predicate.query : Symbol(query, Decl(a.js, 7, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) >query : Symbol(query, Decl(a.js, 7, 34)) my.predicate.query.result = 'none' >my.predicate.query.result : Symbol((Anonymous function).result, Decl(a.js, 12, 33)) >my.predicate.query : Symbol(query, Decl(a.js, 7, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) >query : Symbol(query, Decl(a.js, 7, 34)) >result : Symbol((Anonymous function).result, Decl(a.js, 12, 33)) @@ -68,14 +68,14 @@ my.predicate.query.result = 'none' */ my.predicate.sort = my.predicate.sort || function (first, second) { >my.predicate.sort : Symbol(sort, Decl(a.js, 13, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) >sort : Symbol(sort, Decl(a.js, 13, 34)) >my.predicate.sort : Symbol(sort, Decl(a.js, 13, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) >sort : Symbol(sort, Decl(a.js, 13, 34)) >first : Symbol(first, Decl(a.js, 17, 51)) >second : Symbol(second, Decl(a.js, 17, 57)) @@ -88,9 +88,9 @@ my.predicate.sort = my.predicate.sort || function (first, second) { } my.predicate.type = class { >my.predicate.type : Symbol(type, Decl(a.js, 19, 1)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 13, 34), Decl(a.js, 19, 1)) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 17, 3), Decl(a.js, 20, 3)) +>my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 7, 34), Decl(a.js, 19, 1)) +>predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 20, 3)) >type : Symbol(type, Decl(a.js, 19, 1)) m() { return 101; } @@ -100,22 +100,22 @@ my.predicate.type = class { // global-ish prefixes var min = window.min || {}; ->min : Symbol(min, Decl(a.js, 26, 3), Decl(a.js, 26, 27), Decl(a.js, 27, 44)) +>min : Symbol(min, Decl(a.js, 26, 3)) min.nest = this.min.nest || function () { }; ->min.nest : Symbol(nest, Decl(a.js, 26, 27), Decl(a.js, 28, 4)) ->min : Symbol(min, Decl(a.js, 26, 3), Decl(a.js, 26, 27), Decl(a.js, 27, 44)) ->nest : Symbol(nest, Decl(a.js, 26, 27), Decl(a.js, 28, 4)) +>min.nest : Symbol(nest, Decl(a.js, 26, 27)) +>min : Symbol(min, Decl(a.js, 26, 3)) +>nest : Symbol(nest, Decl(a.js, 26, 27)) min.nest.other = self.min.nest.other || class { }; >min.nest.other : Symbol((Anonymous function).other, Decl(a.js, 27, 44)) ->min.nest : Symbol(nest, Decl(a.js, 26, 27), Decl(a.js, 28, 4)) ->min : Symbol(min, Decl(a.js, 26, 3), Decl(a.js, 26, 27), Decl(a.js, 27, 44)) ->nest : Symbol(nest, Decl(a.js, 26, 27), Decl(a.js, 28, 4)) +>min.nest : Symbol(nest, Decl(a.js, 26, 27)) +>min : Symbol(min, Decl(a.js, 26, 3)) +>nest : Symbol(nest, Decl(a.js, 26, 27)) >other : Symbol((Anonymous function).other, Decl(a.js, 27, 44)) min.property = global.min.property || {}; >min.property : Symbol(property, Decl(a.js, 28, 50)) ->min : Symbol(min, Decl(a.js, 26, 3), Decl(a.js, 26, 27), Decl(a.js, 27, 44)) +>min : Symbol(min, Decl(a.js, 26, 3)) >property : Symbol(property, Decl(a.js, 28, 50)) diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment10.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment10.ts new file mode 100644 index 00000000000..aa700b28002 --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment10.ts @@ -0,0 +1,48 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @target: es6 +// @Filename: module.js +var Outer = Outer || {}; +Outer.app = Outer.app || {}; + +// @Filename: someview.js +Outer.app.SomeView = (function () { + var SomeView = function() { + var me = this; + } + return SomeView; +})(); +Outer.app.Inner = class { + constructor() { + /** @type {number} */ + this.y = 12; + } +} +var example = new Outer.app.Inner(); +example.y; +/** @param {number} k */ +Outer.app.statische = function (k) { + return k ** k; +} +// @Filename: application.js +Outer.app.Application = (function () { + + /** + * Application main class. + * Will be instantiated & initialized by HTML page + */ + var Application = function () { + var me = this; + me.view = new Outer.app.SomeView(); + }; + return Application; +})(); +// @Filename: main.js +var app = new Outer.app.Application(); +var inner = new Outer.app.Inner(); +inner.y; +/** @type {Outer.app.Inner} */ +var x; +x.y; +Outer.app.statische(101); // Infinity, duh diff --git a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts index b7bca4e0712..29dcc2a5048 100644 --- a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts +++ b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts @@ -23,7 +23,7 @@ verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); verify.rangeIs(` - y: {}; + y: { [x: string]: any; }; m1(): any { throw new Error("Method not implemented."); }