diff --git a/src/com/google/javascript/jscomp/CodingConvention.java b/src/com/google/javascript/jscomp/CodingConvention.java index ab2dab06bcf..f556f9dc8d3 100644 --- a/src/com/google/javascript/jscomp/CodingConvention.java +++ b/src/com/google/javascript/jscomp/CodingConvention.java @@ -277,10 +277,11 @@ public void applyDelegateRelationship( public String getDelegateSuperclassName(); /** - * Checks for getprops that set the calling conventions on delegate methods. + * Checks for function calls that set the calling conventions on delegate + * methods. */ - public void checkForCallingConventionDefinitions( - Node getPropNode, Map delegateCallingConventions); + public void checkForCallingConventionDefiningCalls( + Node n, Map delegateCallingConventions); /** * Defines the delegate proxy prototype properties. Their types depend on diff --git a/src/com/google/javascript/jscomp/CodingConventions.java b/src/com/google/javascript/jscomp/CodingConventions.java index a54b10a79d7..82aa86e0d21 100644 --- a/src/com/google/javascript/jscomp/CodingConventions.java +++ b/src/com/google/javascript/jscomp/CodingConventions.java @@ -250,9 +250,9 @@ public String getDelegateSuperclassName() { } @Override - public void checkForCallingConventionDefinitions( + public void checkForCallingConventionDefiningCalls( Node n, Map delegateCallingConventions) { - nextConvention.checkForCallingConventionDefinitions( + nextConvention.checkForCallingConventionDefiningCalls( n, delegateCallingConventions); } @@ -510,7 +510,7 @@ public String getDelegateSuperclassName() { } @Override - public void checkForCallingConventionDefinitions(Node n, + public void checkForCallingConventionDefiningCalls(Node n, Map delegateCallingConventions) { // do nothing. } diff --git a/src/com/google/javascript/jscomp/TypedScopeCreator.java b/src/com/google/javascript/jscomp/TypedScopeCreator.java index ea44f899ecd..676720e1f29 100644 --- a/src/com/google/javascript/jscomp/TypedScopeCreator.java +++ b/src/com/google/javascript/jscomp/TypedScopeCreator.java @@ -533,6 +533,7 @@ public void visit(NodeTraversal t, Node n, Node parent) { switch (n.getToken()) { case CALL: checkForClassDefiningCalls(n); + checkForCallingConventionDefiningCalls(n, delegateCallingConventions); break; case FUNCTION: @@ -565,7 +566,6 @@ public void visit(NodeTraversal t, Node n, Node parent) { break; case GETPROP: - checkForCallingConventionDefinitions(n); // Handle stubbed properties. if (parent.isExprResult() && n.isQualifiedName()) { @@ -1473,10 +1473,12 @@ private JSType lookupQualifiedName(Node n) { } /** - * Look for expressions that set a delegate method's calling convention. + * Look for calls that set a delegate method's calling convention. */ - private void checkForCallingConventionDefinitions(Node n) { - codingConvention.checkForCallingConventionDefinitions(n, delegateCallingConventions); + private void checkForCallingConventionDefiningCalls( + Node n, Map delegateCallingConventions) { + codingConvention.checkForCallingConventionDefiningCalls(n, + delegateCallingConventions); } /** @@ -1576,12 +1578,12 @@ private void applyDelegateRelationship( FunctionType delegateProxy = typeRegistry.createConstructorType( - delegateBaseObject.getReferenceName() + DELEGATE_PROXY_SUFFIX /* name */, - null /* source */, - null /* parameters */, - null /* returnType */, - null /* templateKeys */, - false /* isAbstract */); + delegateBaseObject.getReferenceName() + DELEGATE_PROXY_SUFFIX, + null, + null, + null, + null, + false); delegateProxy.setPrototypeBasedOn(delegateBaseObject); codingConvention.applyDelegateRelationship( @@ -1693,6 +1695,20 @@ void maybeDeclareQualifiedName(NodeTraversal t, JSDocInfo info, // If the property is already declared, the error will be // caught when we try to declare it in the current scope. defineSlot(n, parent, valueType, inferred); + } else if (rhsValue != null && rhsValue.isTrue()) { + // We declare these for delegate proxy method properties. + ObjectType ownerType = getObjectSlot(ownerName); + FunctionType ownerFnType = JSType.toMaybeFunctionType(ownerType); + if (ownerFnType != null) { + JSType ownerTypeOfThis = ownerFnType.getTypeOfThis(); + String delegateName = codingConvention.getDelegateSuperclassName(); + JSType delegateType = delegateName == null ? + null : typeRegistry.getType(delegateName); + if (delegateType != null && + ownerTypeOfThis.isSubtype(delegateType)) { + defineSlot(n, parent, getNativeType(BOOLEAN_TYPE), true); + } + } } }