Commit graph

129 commits

Author SHA1 Message Date
Nathan Shively-Sanders eb105efdcd
Avoid circular reference in this-property assignments (#37827)
* Avoid circular reference in this-property assignments

To do this, don't check this-property assigments that have the
this-property of the lhs appearing somewhere on the rhs:

```js
class C {
  m() {
    this.x = 12
    this.x = this.x + this.y
  }
}
```

I tried suppressing the circularity error, but because we cache the
first type discovered for a property, this still results in an implicit
any for `x` in the previous example. It just doesn't have an error.

Fixes #35099

* Add test case + rename function

* Use isMatchingReference
2020-04-10 16:41:31 -07:00
Nathan Shively-Sanders 7cf4b12d88
Fix crash for private identifier in expando assignments (#37764)
* Fix crash for private identifier in expando assignments

It does this by disallowing private identifiers from expando assignments
entirely. I haven't thought of a scenario where they make sense, but I
haven't thought about it exhaustively either.

Fixes #37356

* Update baselines

I think the new error is probably better. It's certainly different!
2020-04-03 10:29:22 -07:00
Eli Barzilay d6c05a1358 Fix getEffectiveTypeAnnotationNode
Prevent it from using the (return) type of a function.  Could also check
the condition before calling the function, but there are two places that
need the check, and OTOH, all calls check the result so returning
`undefined` should work.

(This problem was introduced in PR#32553.)

Fixes #33741.
2020-01-03 22:47:17 -05:00
Nathan Shively-Sanders 2cc1340a7b
Ignore @private/@protected on constructor functions (#35782)
* Ignore @private on constructor functions

This was incorrect in the best of circumstances and caused a crash when
the parent of the function had no symbol, because the accessibility
check assumed it was operating on a constructor and that the parent was
always the containing class.

* Non-constructors are always accessible

Previously, all function-like kinds were accessible, which includes
constructors. This was wrong.
2019-12-20 08:41:52 -08:00
Nathan Shively-Sanders b98cb0645d
Fix binding of this-assignments w/computed properties (#35639)
Top-level this-assignments do not support computed properties. But the
binder forgets to check for computed properties and tries to bind them
normally. This hits a helpful assert.

This change stop binding this-properties with computed properties at the
top-level.  There's nothing sensible we could do with them; we're unable
to late-bind entries to the global scope or to modules.
2019-12-11 15:55:08 -08:00
Kārlis Gaņģis 17f5469a2c Fix crash with Object.defineProperty for imported alias (--allowJs) (#35198)
Fixes #35196
2019-11-20 10:50:47 -08:00
Nathan Shively-Sanders 080e41dc90
Fix type reference to merged prototype property assignment (#34764)
The constructor function code path in the return type checking of
signatures needs to pass the *merged* symbol of the declaration to
getDeclaredTypeOfClassOrInterface. Other callers of
getDeclaredTypeOfClassOrInterface do this, or used an already-merged
symbol.

Fixes #33993
2019-10-28 10:14:04 -07:00
Kārlis Gaņģis 479d30646f Fix crash in assigning function with this ref to alias (#34650) 2019-10-22 14:33:45 -07:00
Nathan Shively-Sanders 1cbbe288ac
Treat any mix of element/prop access as declaration in JS (#34649)
Fixes #34642 but, notably, doesn't actually make the assignment into a
working declaration. It just fixes the crash.
2019-10-22 11:28:28 -07:00
Nathan Shively-Sanders fa1884ed1b
Fix crash in expando assignment to alias (#34566)
* Fix crash in expando assignment to alias

This PR disallows expando assignments

Fixes #34493, but disallows the prototype assignment nonetheless.

* Revert mistaken changes
2019-10-18 13:31:44 -07:00
Nathan Shively-Sanders 82f927f8dd
Fix stack overflow in circular assignment declaration (#34543)
* Fix stack overflow in circular assignment declaration

It also needs to have multiple assignments so that it has a ValueModule
flag.

Fixes #33006

* remove errant comment

* Remove other possible circularity

* Restore fallback with additional condition
2019-10-18 09:01:21 -07:00
Wenlu Wang 7c50bccec2 nullish coalescing commit (#32883)
* migrate nullish coalescing commit

* add more test case

* add branch type check test

* add more tests

* fix nullish precedence

* update public api

* add rescan question question token to fix regression

* update public api baseline

* Added tests that emit for nullish coalescing operator conforming with grammar restrictions when assertions are used.

* Fixed emit to hoist temporary variables (they previously went undeclared).
Added tests to ensure calls and property accesses are only called once.

* use not equal to null

* rename factory

* add grammar check

* fix more cases

* Fix handling of nullish coalescing oprator in expando objects.

* Fixed classifier to support ?? operator.

* update baseline

* accept baseline

* fix review

* update emitter and more testcase

* update control flow

* make linter happy

* update libs

* avoid unnecessary assert

* fix typooo

* Fixes for control-flow analysis
2019-09-30 15:33:50 -07:00
Andrew Branch f89de95955
Allow special element access assignments to create declarations (#33537)
* Start enabling element access special assignment

* Treat element access assignment as special assignment in JS

* Make declarations for bindable element access expressions

* Fix navigationBar crash

* Add multi-level test for JS

* Propagate element access expressions to more code paths

* Fix property access on `this`

* Add quick info test

* Uhhh I guess this is fine

* Fix module["exports"] and property access chained off element access

* Add test for this property assignment

* Add test for and fix prototype property assignment

* Fix teeeest???

* Update APIs

* Fix element access declarations on `this`

* Fix go-to-definition

* Add declaration emit to tests

* Reconcile with late-bound symbol element access assignment

* Fix baselines

* Add JS declaration back to tests

* Fix JS declaration emit of non-late-bound string literal property names

* Revert accidental auto-format

* Use `isAccessExpression`

* Add underscore escaping member to test

* Fix and test navBar changes
2019-09-30 15:08:44 -05:00
Wesley Wigham 293816875c
Support some late-bound special property assignments (#33220)
* Support some late-bound special property assignments

* Integrate PR feedback

* PR feedback

* Enable declaration on core tests

* Specialize type of binary expression used for late binding, speculative fix to navigation bar, merge check and type for elem/property accesses

* Add test showing current nav bar behavior (specifically the lack thereof)
2019-09-27 13:54:50 -07:00
Nathan Shively-Sanders 4bddf55328
Fix prototype property type lookup (#33034)
* Fix constructor function type reference lookup

I knew I missed some code in the constructor-functions-as-classes PR.
This simplifies the type reference resolution code as well.

* Simplify and document js alias type resolution
2019-08-22 12:51:15 -07:00
Nathan Shively-Sanders 3c42760765
Cache JS inferred class type symbol (#33010)
* Cache JS inferred class type symbol

Note that many sources merge into a single target, so the *source*
[links] is the one that caches the merged target.

The reason this is a problem is not that many sources merge into a
single target, but that both getTypeOfSymbol and getDeclaredTypeOfSymbol
end up calling mergeJSSymbols with the same [source,target] pair. The
merge should not happen twice.

* Remove more verbose debug assertion message

* Fix isJSConstructor check + update baselines

* inferClassSymbol cache now track multiple targets
2019-08-21 15:36:35 -07:00
Nathan Shively-Sanders 6ca9d04b60
Constructor functions as classes (#32944)
* Initial implementation

The original test passes but I haven't run any other tests yet, so I
assume the world is now broken.

* Append constructor function construct sigs

Instead of overwriting them

* Grab bag of improvements.

1. Mark @class-tagged functions with Class too.
2. Only gather local type parameters of constructor functions.
3. Remove getJSClassType calls with getDeclaredTypeOfSymbol.
4. Add a couple more failing tests.

getDeclaredTypeOfClassOrInterface now needs to understand prototype
assignment. That's next, I think.

* Prototype assignments work now

1. Binder marks prototype assignments as Class now.
2. Checker merges prototype assignments using the same merge code as for
functions and their declarations. No more intersections.

Many fewer failing tests now.

* Mark prototype-property assignments as Class

Even if there are no this-property assignments in them. (Then why are
you using a class?).

* Simplify getJSClassType, remove calls to its guts

It's probably not needed because now it's just a conditional call to
getDeclaredTypeOfSymbol, and I think most callers already know whether
they have a JS constructor function beforehand.

* isJSDocConstructor doesn't need to check prototype anymore

Because all the properties are merged during getDeclaredTypeOfSymbol.

* outer type parameter lookup follow prototype assignment

* this-type and -expression support in ctor funcs

Pretty cool!

* Fix remaining tests

* Fix minor lint

* Delete now-unused code

* Add class flag to nested class declarations

Also remove old TODOs
2019-08-19 14:12:53 -07:00
Nathan Shively-Sanders 772bee5e84
Property assignment uses parent type annotation (#32553)
* Property assignment uses parent type annotation

First draft, will write full explanation later.

Also makes sure that jsdoc is ignored in TS. It was not before.

* Update baselines
2019-07-25 10:23:03 -07:00
Nathan Shively-Sanders eeba30afc8
Fix infinite loop: module.exports alias detection (#31436)
* Fix infinite loop: module.exports alias detection

Previously, module.exports alias detection in the binder could enter an
infinite recursion. Now it does not.

Notably, there are *two* safeguards: a counter limiter that I set at
100, and an already-seen set. I actually prefer the counter limiter code
because it's foolproof and uses less memory. But it takes 100
iterations to escape from loops.

* fix space lint

* Remove already-seen map
2019-05-17 12:50:39 -07:00
Nathan Shively-Sanders be2db9db12
Add globalThis (#29332)
* Restore original code from bind-toplevel-this

With one or two additional comments

* Working in JS, but the symbol is not right.

Still need to

1. Make it work in Typescript.
2. Add test (and make them work) for the other uses of GlobalThis:
window, globalThis, etc.

* Check in TS also; update some tests

Lots of tests still fail, but all but 1 change so far has been correct.

* Update baselines

A couple of tests still fail and need to be fixed.

* Handle type references to globalThis

The type reference must be `typeof globalThis`. Just `globalThis` will
be treated as a value reference in type position -- an error.

* Restore former behaviour of implicitThis errors

I left the noImplicitThis rule for captured use of global this in an
arrow function, even though technically it isn't `any` any more --
it's typeof globalThis.  However, you should still use some other method
to access globals inside an arrow, because captured-global-this is super
confusing there.

* Test values with type globalThis

I ran into a problem with intersecting `Window & typeof globalThis`:

1. This adds a new index signature to Window, which is probably not
desired. In fact, with noImplicitAny, it's not desired on globalThis
either I think.
2. Adding this type requires editing TSJS-lib-generator, not this repo.

So I added the test cases and will probably update them later, when
those two problems are fixed.

* Add esnext declaration for globalThis

* Switch to symbol-based approach

I decided I didn't like the import-type-based approach.

Update baselines to reflect the difference.

* Do not suggest globals for completions at toplevel

* Add tests of element and property access

* Look up globalThis using normal resolution

globalThis is no longer constructed lazily. Its synthetic Identifier
node is also now more realistic.

* Update fourslash tests

* Add missed fourslash test update

* Remove esnext.globalthis.d.ts too

* Add chained globalThis self-lookup test

* Attempt at making globalThis readonly

In progress, had to interrupt for other work.

* Add/update tests

* Addres PR comments:

1. Add parameter to tryGetThisTypeAt to exclude globalThis.
2. Use combined Module flag instead combining them in-place.
3. SymbolDisplay doesn't print 'module globalThis' for this expressions
anymore.
2019-02-27 14:14:34 -08:00
Pranav Senthilnathan d38c616e29
Fix resolution of properties from prototype assignment in JS (#29302)
* fix type derived from prototype assignment

* accept new baselines

* remove direct intersection with object literal assigned to prototype

* add tests

* change webpack submodule commit

* fix submodule commits

* comment and simplify getJSDocTypeReference

* remove circularity guards that aren't hit anymore
2019-01-18 16:00:18 -08:00
Nathan Shively-Sanders 0774bb81ce
Fix crash on property assignment of unresolved module (#28606)
Previously, the compiler would crash when binding a non-top-level
property assignment on the symbol of an unresolved module:

```js
import x from 'arglebaz'
{
    x.bar = 1
}
```

That's because `x` looks like an alias but doesn't have a
valueDeclaration (since there is no file named 'arglebaz'), and the new
code for binding Object.defineProperty calls forgot to check for an
undefined valueDeclaration.

This change adds the checks for an undefined valueDeclaration.
2018-11-19 13:29:46 -08:00
Nathan Shively-Sanders dc9a066f65
Do not merge commonJS exports into an alias (#28133)
* Do not merge commonsjs exports onto an alias

getCommonJSExportEquals merges export assignments and export property
assignments. Something like this, which has no equivalent structure in
TS:

```js
module.exports = function() { }
module.exports.expando = 1
```

However, it is sometimes called with an alias, when its
parent, resolveExternalModuleSymbol, is called with dontResolveAlias:
true, and when the initialiser of the export assignment is an alias:

```js
function alias() { }
module.exports = alias
module.exports.expando = 1
```

In this case, (1) the actual value `alias` will have already merged in a
previous call to getCommonJSExportEquals and
(2) getTypeOfSymbol will follow the alias symbol to get the right type.
So getCommonJSExportEquals should do nothing in this case.

This bug manifests in the code for dynamic imports, which calls
getTypeOfSymbol on the incorrectly merged alias, which now has enough
value flags--Function, for example--to take the wrong branch and
subsequently crash.

* Update baselines
2018-10-25 15:08:06 -07:00
Nathan Shively-Sanders e379aeb151
Fix alias of module.exports->exports->IIFE (#27992)
In JS, when you assign `module.exports = exports` and the entire module is
wrapped in an IIFE, the resulting `export=` symbol, after following
aliases, is the module itself. This results in trying to merge the
file's exports with itself inside `getCommonJsExportEquals`, since it
thinks that it has found new exports, possibly in an object literal,
that need to be merged with the file's exports.

For example:

```js
(function() {
exports.a = 1
module.exports = exports
})()
```
2018-10-19 13:50:38 -07:00
Nathan Shively-Sanders 8779d4ca88
Fix JS merge crashes from lovefield (#27989)
1. Merge enum with expando.
2. Merge enum member with property assignment.
3. Merge interface-declared method declaration with
prototype-property-assignment method declaration.

The reason that the enum merges crash is that getTypeOfSymbol assumes
that symbol flags are (basically) mutually exclusive. This assumption is
shredded, badly, for JS merges.

One fix is to drop the assumption of exclusivity and instead order cases
by least to most likely. This has the highest chance of working, but is
also slow, since you would prefer to order cases by most likely *first*,
not *last*.

The other fix, which is what I did here, is to add a last-chance
re-dispatch at the bottom of
`getTypeOfVariableOrParameterOrPropertyWorker`. This dispatch uses the
valueDeclaration instead of the symbol flags.
2018-10-19 09:23:05 -07:00
Nathan Shively-Sanders c184184713
Add getEffectiveConstructSignatures (#27561)
* Add helpers that understand constructor functions

* getEffectiveConstructSignatures gets construct signatures from type, and
  call signatures from constructor functions if there are no construct
  signatures.
* getEffectiveConstructSignatureReturnType gets the "JS Class type" for
  constructor functions, and the return type of signatures for all other
  declarations.

This is a first step toward making constructor functions have construct
signatures instead of call signatures, which will also contribute to
fixing instantiation of generic constructor functions, which is basically
broken right now.

Note that the baselines *improve* but, because of the previously
mentioned generic problem, are still not correct. Construct signatures
for constructor functions and generic constructor functions turns out to
be an intertwined problem.

* Correct correct originalBaseType

And, for now, return anyType for generic constructor functions used as
base types. Don't give an incorrect error based on the function's return
type, which is usually void.

* Add error examples to tests

* Add construct signatures instead of getEffective* functions

* Fix typo in baseline

* Remove pesky newline

I thought I got rid of it!

* Test of constructor tag on object literal method

It doesn't work, and shouldn't in the future, because it's a runtime
error.
2018-10-15 12:47:57 -07:00
Nathan Shively-Sanders 8a4b6e03ab Fix class/constructor-function merge (#27366)
The check for prototype assignment on constructor functions assumes
that the prototype property, if present, comes from an assignment
declaration, such as:

```js
SomeClass.prototype = { /* methods go here */ }
```

In this case, however, when class SomeClass and var SomeClass merge
(because this is allowed), prototype is the synthetic property from
class SomeClass, which has no valueDeclaration.

The fix is to check that prototype has a valueDeclaration before
checking whether the valueDeclaration is in fact a prototype-assignment
declaration.
2018-10-08 12:56:19 -07:00
Nathan Shively-Sanders 98ec1e8730
Fix commonjs export= merging (#27368) (#27371)
I'm surprised we haven't seen more of this; I suspect it's because the
mixed `module.exports=` + `export.foo=` pattern isn't that common.
However, it'll happen any time that the exported symbol is unknown;
getCommonJsExportEquals blithely clones unknownSymbol and proceeds to
stick the `exports.foo=` properties onto it.

This causes problems later, because the compiler checks for
unknownSymbol with `===`. The fix is to not stick properties onto a
clone of unknownSymbol. This makes the correct errors appear and removes
the crash.
2018-09-26 12:40:30 -07:00
Nathan Shively-Sanders 90d3f8b573
Only report expando use-before-def for identical control flow containers (#27199) 2018-09-18 15:28:16 -07:00
Nathan Shively-Sanders c9f190283e
Fix non-toplevel prototype assignment (#27096)
* Fix non-toplevel prototype assignment

binder was using the wrong node to lookup the containing class type for
prototype assignment, so it incorrectly put the prototype declaration on
the class' symbol.

This correction to the binder in turn required a change in
getJSClassType in the checker. It now has to look at the "prototype"
property for the prototype instead of looking on the class symbol's exports
(which makes no sense).

* Refactor per PR suggestion
2018-09-17 13:07:05 -07:00
Nathan Shively-Sanders 989a717b04
Definite assignment checking for expando properties (#27128) 2018-09-17 12:56:39 -07:00
Nathan Shively-Sanders 394ee31a56
Fix cross-file merge of assignment decl valueDeclaration (#26918)
* Fix cross-file merge of assignment decl valueDeclaration

Previously mergeSymbol in the checker always updated valueDeclaration if
target.valueDeclaration was an assignment declaration. The binder only
updates target.valueDeclaration if it is an assignment declaration and
source.valueDeclaration is *not* an assignment declaration. Now the
checker behaves the same way as the binder.

* Update baselines

* Add a fix for #27099

Makes commonjs merge with globals when appropriate.

* Add a separate jsGlobalAugmentations table

Instead of trying to filter these augmentations out of the normal symbol
table of commonjs modules.
2018-09-16 07:46:03 -07:00
Nathan Shively-Sanders 614423b287
Fix this-type in prototype-assigned object literals (#26925)
* Fix this-type in prototype-assigned object literals

Some cases were missing from tryGetThisTypeAt.
Fixes #26831

* Lookup this in JS only for  @constructor+prototype assignments
2018-09-12 16:21:17 -07:00
Nathan Shively-Sanders ff05082e45
Bind non-expando property assignments at top-level (#26908)
* Bind non-expando property assignments at toplevel

Previously, only property assignments with expando initialisers were
bound in top-level statements. Now, all property assignments are bound.

This requires a matching change in the checker to make sure that these
assignments remain context sensitive if their valueDeclaration is a
'real' declaration (ie a non assignment-declaration).

* Add baselines for new test
2018-09-05 10:53:43 -07:00
Nathan Shively-Sanders d3f96015f1
Fix namespace expando merge (#26690)
* Allow JSContainers to merge with namespaces

Expando functions marked with JSContainer previously failed to merge
with namespaces. This change adds JSContainer to ValueModuleExcludes,
allowing this kind of merge.

* Improve symbol flags to fix namespace/expando merging

Calls to bindPropertyAssignment now provide which special assignment
kind they originated from. This allows better symbol flags to be set:

1. Property assignments get the FunctionScopedVariable flag, since they are
equivalent to a `namespace` exporting a `var`.
2. Prototype property assignments get the Method flag if the initialiser
is functionlike, and Property otherwise.
3. Prototype assignments get the flag Property.

(3) is still not entirely correct (it's missing the Prototype flag),
but is what existed previously. I'll try adding the Prototype flag to
see whether it changes any baselines.

* Add cross-file merge test

* Update missed baselines

* Namespace declarations are primary for merging purposes

Also, property-assignments go back to being property declarations, not
function-scoped variable declarations

* Revert unneeded changes

* Revert unneeded changes (in a codefix this time)

* Put JSContainer on all assignment declarations

This allows most of the new special-case merge code to go away. It now
uses the JSContainer special-case code, which already exists.

* Missed comment

* Fix extra newline lint
2018-08-30 13:18:50 -07:00
Nathan Shively-Sanders 29dbabe2e1
In JS, fix contextual type of this assignments (#26743)
in object literal methods inside an object literal with a type
annotation.

Note that this does not change:

1. The type of `this` in object literal methods.
2. The fact that this-property assignments are still declarations. They
just don't block contextual typing like most declarations do.

This change is a bit expensive. It first calls getThisContainer, which
walks the tree upward. Then it calls checkThisExpression, which will
usually call getContextualType on the object literal method. If the new
code then returns true, it will proceed to redo much of that work.

Calling checkThisExpression should not cause incorrect circularity
failures; we only have to inspect the shape of the object literal and
not the types of its properties to determine its type.
2018-08-29 15:06:38 -07:00
Nathan Shively-Sanders 6419240ab2
Declaration emit includes function properties (#26499)
* Declaration emit includes function properties

It does this by printing the type as an object literal type:

```ts
function f() { }
f.p = 1
```

Appears in a d.ts as

```ts
declare var f: {
  (): void;
  p: number;
}
```

It would also be possible to represent it as a namespace merge. I'm not
sure which is better.

```ts
declare function f(): void;
declare namespace f {
  export var p: number;
}
```

In order to avoid a private-name-used error (though I think it was
actually *unused*), I also had to change the nodeBuilder code to match.
This is arguably harder to read. So it's possible that I should instead
keep the nodeBuilder version as `typeof f` and make an exception for
private name use.

* Emit namespace merge instead of object type

This makes the change smaller, overall.

* Fix isJSContainerFunctionDeclaration+namespace merges

Also improve emit style to match other namespace emit.

* Add isPrivate + test case from PR comments
2018-08-27 10:29:53 -07:00
Nathan Shively-Sanders 03653934c3
Don't create expando object literals in TS (#26525)
Previously, getWidenedTypedFromJSPropertyAssignment was not called for
Typescript code. Since property assignments on functions, it is. That
meant that property assignments would incorrectly create a JS container
for empty object literals in a property assignment, even in Typescript:

```ts
const one = () => 1
one.p = {}
one.p.q = {} // should not work in Typescript!
```

Now empty object literals never create expando objects in Typescript,
because getJSExpandoObjectType requires the declaration to be in a JS
file.
2018-08-23 08:21:28 -07:00
Nathan Shively-Sanders 75071a2509
Allow super references to constructor function methods (#26482)
Previously, they were mistakenly treated as private because of a check
that required all super property accesses (like `super.x()`) to be
references to a MethodDeclaration or MethodSignature. This change also
allows PrototypeProperty special assignment kinds.
2018-08-16 09:20:30 -07:00
Nathan Shively-Sanders cc67ce1141
Property assignments in Typescript (#26368)
* Allow special property assignments in TS

But only for functions and constant variable declarations initialised with
functions.

This specifically excludes class declarations and class expressions,
which differs from Javascript. That's because Typescript supports
`static` properties, which are equivalent to property assignments to a
class.

* Improve contextual typing predicate

Don't think it's right yet, but probably closer?

* More fixes.

The code is still fantastically ugly, but everything works the way it
should.

Also update baselines, even where it is ill-advised.

* Cleanup

* Remove extra whitespace

* Some kind of fix to isAnyDeclarationName

It's not done yet.

Specifically, in TS:
Special property assignments are supposed to be declaration sites (but not all
top-level assignments), and I think I
got them to be. (But not sure).

In JS:
Special property assignments are supposed to be declaration sites (but not all
top-level assignments), and I'm pretty sure ALL top-level assignments
have been declaration sites for some time. This is incorrect, and
probably means the predicate needs to be the same for both dialects.

* Add fourslash and improve isAnyDeclarationName

Now JS behaves the same as TS.

* Cleanup from PR comments
2018-08-15 15:25:25 -07:00
Nathan Shively-Sanders 08eb99d8ec
For a this-property assignment with an empty object initializer, use type annotation if present (#26428)
* This-property w/empty object init: use type annotation

* JS initializer type doesn't apply to this-property assignments

* Move getJSExpandoType into getWidenedType* functions

Plus some cleanup.

* Improved style from PR comments

* Parameters are not expando
2018-08-15 14:53:30 -07:00
Nathan Shively-Sanders 29ca93ba48
Classes can extend Javascript constructor functions (#26452)
* Classes can extend JS constructor functions

Now ES6 classes can extend ES5 constructor functions, although only
those written in a JS file.

Note that the static side assignability is checked. I need to write
tests to make sure that instance side assignability is checked too.
I haven't tested generic constructor functions yet either.

* Test static+instance assignability errors+generics

Note that generics do not work.

* Cleanup from PR comments

* Even more cleanup

* Update case of function name
2018-08-14 14:43:04 -07:00
James Keane 50f442f9ff Fixes #26122 - erroneous "TS2350" for js constructors called with incorrect parameters (#26124)
* Fixes #26122.

When `resolveCall` does not resolve in `resolveNewExpression`, the error should only be thrown if there is a *defined* signature that is not-void.

* Fix other baselines to remove erroneous TS2350.
2018-08-01 13:40:55 -07:00
James Keane dfedb24f75 Jsdoc @constructor - in constructor properly infer this as class instance (#25980)
* Properly infer `this` in tagged `@constructor`s.

`c.prototype.method = function() { this }` was already supported.

This commit add support to two more kinds relying on the JSDoc
`@constructor` tag. These are:
 1. `/** @constructor */ function Example() { this }`
 2. `/** @constructor */ var Example = function() { this }`

* Update the baseline for js constructorFunctions.

C3 and C4 `this` was set as `any`, now it is properly showing as
the class type.

* Fix lint errors

* Add circular initialisers to constructo fn tests.

* Error (`TS2348`) if calling tagged js constructors

When calling a JS function explicitly tagged with either `@class` or
`@constructor` the checker should throw a TS2348 not callable error.

* Don't resolve jsdoc classes with construct sigs.

This undoes the last commit that sought to change how js functions
tagged with `@class` were inferred. For some reason, currently
unknown, giving those functions construct signatures causes issues
in property assignment/member resolution (as seen in the
`typeFromPropertyAssignment12` test case).

Instead of changing the signature resolution, the error is explicitly
generated in `resolveCallExpression` for those functions.
2018-07-31 13:52:39 -07:00
Nathan Shively-Sanders 4d84bde9b3
Only bind module.exports if no local definition exists (#25869)
* Only bind module.exports if no local definition exists

Note that this uses `lookupSymbolForNameWorker`, which is really a
best-effort check since it only knows about symbols that it has already
encountered.

As a side-effect, even when `module` is bound as part of a
`module.exports` reference, it only declares it once instead of one
declaration per reference.

* Only type module.exports inside module files

It is an error inside script files, but the binder sometimes creates a
ModuleExports symbol because we doesn't know whether we have a commonjs
module until after binding is done.

* Only bind module.exports in a commonjs module

Note that this, too, is a best-effort check since evidence of
commonjs-ness may be found after a *reference* to module.exports. (A
reference to module.exports alone is not enough evidence that a file is
commonjs. It has to have an assignment to it.)
2018-07-30 12:27:59 -07:00
Nathan Shively-Sanders 31d599abaf
Check module.exports (#25732)
* Revert "Revert "Explicitly typed special assignments are context sensitive (#25619)""

This reverts commit 16676f2707.

* Revert "Revert "Explicitly typed prototype assignments are context sensitive (#25688)""

This reverts commit ff8c30d636.

* Initial, wasteful, solution

It burns a check flags. Probably necessary, but perhaps not.

I haven't accepted baselines, but they are a bit questionable. I'm not
sure the synthetic type is right, because I expected to see
{ "exports": typeof import("x") } but instead see { "x": typeof
import("x") }.

* Update some baselines

* module.exports= always uses lhs type

Conflicts between exports property assignments and exports assignments
should get a union type instead of an error.

* Fix lint and accept good user baselines

* Add tests based on user tests.

These currently fail.

* Fix all but 1 of user test bugs found by typing module.exports

Still quite messy and full of notes

* Follow merged symbols+allow any object type

This allows exports like `module.exports = new EE` to have properties
added to them.

Still messy, but I'm going to run user tests and look for regressions.

* Update improved user baselines

* Fix infinite recursion when checking module.exports

* Fix bogus use-before-def error

getExportSymbolOfValueSymbolIfExported should always merge its returned
symbol, whether it's symbol.exportSymbol or just symbol.

* Update user test baselines

* Cleanup

* More small cleanup

* Bind `module` of `module.exports` as a special symbol

Previously it was also special, but created during name resolution in
the checker. It made sense when there was only one special symbol for
all files, but now there is one `module` symbol per file.
2018-07-20 10:59:26 -07:00
Nathan Shively-Sanders 1edc975f15
Revert the revert of explicitly typed special assignments (#25727)
* Revert "Revert "Explicitly typed special assignments are context sensitive (#25619)""

This reverts commit 16676f2707.

* Revert "Revert "Explicitly typed prototype assignments are context sensitive (#25688)""

This reverts commit ff8c30d636.
2018-07-17 10:02:51 -07:00
Nathan Shively-Sanders 16676f2707 Revert "Explicitly typed special assignments are context sensitive (#25619)"
This reverts commit 32e60a9647.
2018-07-16 12:39:08 -07:00
Nathan Shively-Sanders ff8c30d636 Revert "Explicitly typed prototype assignments are context sensitive (#25688)"
This reverts commit 5b21cbc0c9.
2018-07-16 12:38:27 -07:00
Nathan Shively-Sanders 5b21cbc0c9
Explicitly typed prototype assignments are context sensitive (#25688)
* Explicitly typed prototype assignments:ctx sensitive

Follow up to #25619: Add the necessary code to type `prototype`
correctly in prototype assignments so that code like
`F.prototype = { ... }` properly makes the object literal context
sensitive.

* Fix lint
2018-07-16 10:03:39 -07:00