Skip to content

Commit

Permalink
Allow calling functions whose "this type" is top or undefined as fr…
Browse files Browse the repository at this point in the history
…ee functions.

Example:
```
class Foo {
  /** @this {*} */ method() { }
}
const x = Foo.method;
x(); // This is legal now.
```

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=244935076
  • Loading branch information
nreid260 authored and tjgq committed Apr 24, 2019
1 parent 7db0af3 commit a15f21f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
19 changes: 11 additions & 8 deletions src/com/google/javascript/jscomp/TypeCheck.java
Expand Up @@ -2554,14 +2554,17 @@ private void visitCall(NodeTraversal t, Node n) {
report(n, CONSTRUCTOR_NOT_CALLABLE, childType.toString());
}

// Functions with explicit 'this' types must be called in a GETPROP
// or GETELEM.
if (functionType.isOrdinaryFunction()
&& !functionType.getTypeOfThis().isUnknownType()
&& !(functionType.getTypeOfThis().toObjectType() != null
&& functionType.getTypeOfThis().toObjectType().isNativeObjectType())
&& !(child.isGetElem() || child.isGetProp())) {
report(n, EXPECTED_THIS_TYPE, functionType.toString());
// Functions with explicit 'this' types must be called in a GETPROP or GETELEM.
if (functionType.isOrdinaryFunction() && !NodeUtil.isGet(child)) {
JSType receiverType = functionType.getTypeOfThis();
if (receiverType.isUnknownType()
|| receiverType.isAllType()
|| receiverType.isVoidType()
|| (receiverType.isObjectType() && receiverType.toObjectType().isNativeObjectType())) {
// Allow these special cases.
} else {
report(n, EXPECTED_THIS_TYPE, functionType.toString());
}
}

visitArgumentList(n, functionType);
Expand Down
9 changes: 5 additions & 4 deletions test/com/google/javascript/jscomp/TypeCheckTest.java
Expand Up @@ -8525,10 +8525,11 @@ public void testThis14() {
}

@Test
public void testThisTypeOfFunction1() {
testTypes(
"/** @type {function(this:Object)} */ function f() {}" +
"f();");
public void testThisType_whichTypesSupport_freeCallsOfFunction() {
testTypes("/** @type {function(this:*)} */ function f() {}; f();");
testTypes("/** @type {function(this:?)} */ function f() {}; f();");
testTypes("/** @type {function(this:undefined)} */ function f() {}; f();");
testTypes("/** @type {function(this:Object)} */ function f() {}; f();");
}

@Test
Expand Down

0 comments on commit a15f21f

Please sign in to comment.