Java Code Examples for com.google.javascript.rhino.jstype.FunctionType#getParameters()

The following examples show how to use com.google.javascript.rhino.jstype.FunctionType#getParameters() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DeclarationGenerator.java    From clutz with MIT License 6 votes vote down vote up
/**
 * Special handling for simple typing returning polymorphic this type in TypeScript. Prefer
 * `func(): this` instead of `func<T>(this: T): T` when any params are not templatized.
 */
private boolean shouldEmitThisParam(FunctionType ftype) {
  final JSType typeOfThis = ftype.getTypeOfThis();
  if (typeOfThis == null
      || !typeOfThis.isTemplateType()
      || !typeOfThis.equals(ftype.getReturnType())) {
    return true;
  }

  for (Parameter parameter : ftype.getParameters()) {
    JSType paramType = parameter.getJSType();
    if (!paramType.isTemplatizedType()) {
      continue;
    }

    final TemplateTypeMap templateTypeMap = paramType.getTemplateTypeMap();
    for (TemplateType key : templateTypeMap.getTemplateKeys()) {
      if (templateTypeMap.getResolvedTemplateType(key).equals(typeOfThis)) {
        return true;
      }
    }
  }

  return false;
}
 
Example 2
Source File: DevirtualizePrototypeMethods.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Creates a new JSType based on the original function type by
 * adding the original this pointer type to the beginning of the
 * argument type list and replacing the this pointer type with
 * NO_TYPE.
 */
private void fixFunctionType(Node functionNode) {
  FunctionType type = JSType.toMaybeFunctionType(functionNode.getJSType());
  if (type != null) {
    JSTypeRegistry typeRegistry = compiler.getTypeRegistry();

    List<JSType> parameterTypes = Lists.newArrayList();
    parameterTypes.add(type.getTypeOfThis());

    for (Node param : type.getParameters()) {
      parameterTypes.add(param.getJSType());
    }

    ObjectType thisType =
        typeRegistry.getNativeObjectType(JSTypeNative.UNKNOWN_TYPE);
    JSType returnType = type.getReturnType();

    JSType newType = typeRegistry.createFunctionType(
        thisType, returnType, parameterTypes);
    functionNode.setJSType(newType);
  }
}
 
Example 3
Source File: DeclarationGenerator.java    From clutz with MIT License 5 votes vote down vote up
private boolean allParametersUnknown(FunctionType ftype) {
  for (Parameter param : ftype.getParameters()) {
    JSType type = param.getJSType();
    // Note: template types (e.g. the T in Array<T>) return true for isUnknownType,
    // so we check that first.
    if (type.isTemplateType() || !type.isUnknownType()) return false;
  }
  return true;
}
 
Example 4
Source File: TypeInference.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    // TODO(johnlenz): Filter out non-function types
    // (such as null and undefined) as
    // we only care about FUNCTION subtypes here.
    JSType restrictedParameter = iParameterType
        .restrictByNotNullOrUndefined()
        .toMaybeFunctionType();
    if (restrictedParameter != null) {
      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(restrictedParameter);
      }
    }
    i++;
  }
}
 
Example 5
Source File: TightenTypes.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private ExternFunctionCall createExternFunctionCall(
    Node receiver, JSType jsThisType, FunctionType fun) {
  List<ConcreteType> argTypes = Lists.newArrayList();
  ConcreteType thisType;
  if (fun != null) {
    thisType = createType(jsThisType);
    for (Node arg : fun.getParameters()) {
      argTypes.add(createType(arg, scope));
    }
  } else {
    thisType = ConcreteType.NONE;
  }
  return new ExternFunctionCall(receiver, thisType, argTypes);
}
 
Example 6
Source File: Closure_112_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    // TODO(johnlenz): Filter out non-function types
    // (such as null and undefined) as
    // we only care about FUNCTION subtypes here.
    JSType restrictedParameter = iParameterType
        .restrictByNotNullOrUndefined()
        .toMaybeFunctionType();
    if (restrictedParameter != null) {
      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(restrictedParameter);
      }
    }
    i++;
  }
}
 
Example 7
Source File: Closure_112_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    // TODO(johnlenz): Filter out non-function types
    // (such as null and undefined) as
    // we only care about FUNCTION subtypes here.
    JSType restrictedParameter = iParameterType
        .restrictByNotNullOrUndefined()
        .toMaybeFunctionType();
    if (restrictedParameter != null) {
      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(restrictedParameter);
      }
    }
    i++;
  }
}
 
Example 8
Source File: Closure_35_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    if (iParameterType.isFunctionType()) {
      FunctionType iParameterFnType = iParameterType.toMaybeFunctionType();

      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(iParameterFnType);
      }
    }
    i++;
  }
}
 
Example 9
Source File: Closure_35_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    if (iParameterType.isFunctionType()) {
      FunctionType iParameterFnType = iParameterType.toMaybeFunctionType();

      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(iParameterFnType);
      }
    }
    i++;
  }
}
 
Example 10
Source File: Closure_25_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    if (iParameterType.isFunctionType()) {
      FunctionType iParameterFnType = iParameterType.toMaybeFunctionType();

      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(iParameterFnType);
      }
    }
    i++;
  }
}
 
Example 11
Source File: Closure_25_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
  int i = 0;
  int childCount = n.getChildCount();
  for (Node iParameter : fnType.getParameters()) {
    if (i + 1 >= childCount) {
      // TypeCheck#visitParametersList will warn so we bail.
      return;
    }

    JSType iParameterType = getJSType(iParameter);
    Node iArgument = n.getChildAtIndex(i + 1);
    JSType iArgumentType = getJSType(iArgument);
    inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);

    if (iParameterType.isFunctionType()) {
      FunctionType iParameterFnType = iParameterType.toMaybeFunctionType();

      if (iArgument.isFunction() &&
          iArgumentType.isFunctionType() &&
          iArgument.getJSDocInfo() == null) {
        iArgument.setJSType(iParameterFnType);
      }
    }
    i++;
  }
}
 
Example 12
Source File: Closure_35_TypeInference_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * For functions with function(this: T, ...) and T as parameters, type
 * inference will set the type of this on a function literal argument to the
 * the actual type of T.
 */
private void updateTypeOfThisOnClosure(Node n, FunctionType fnType) {
  // TODO(user): Make the template logic more general.

  if (fnType.getTemplateTypeName() == null) {
    return;
  }

  int i = 0;
  int childCount = n.getChildCount();
  // Find the parameter whose type is the template type.
  for (Node iParameter : fnType.getParameters()) {
    JSType iParameterType =
        getJSType(iParameter).restrictByNotNullOrUndefined();
    if (iParameterType.isTemplateType()) {
      // Find the actual type of this argument.
      ObjectType iArgumentType = null;
      if (i + 1 < childCount) {
        Node iArgument = n.getChildAtIndex(i + 1);
        iArgumentType = getJSType(iArgument)
            .restrictByNotNullOrUndefined()
            .collapseUnion()
            .toObjectType();
        if (iArgumentType == null) {
          compiler.report(
              JSError.make(NodeUtil.getSourceName(iArgument), iArgument,
                  TEMPLATE_TYPE_NOT_OBJECT_TYPE,
                  getJSType(iArgument).toString()));
          return;
        }
      }

      // Find the parameter whose type is function(this: T, ...)
      boolean foundTemplateTypeOfThisParameter = false;
      int j = 0;
      for (Node jParameter : fnType.getParameters()) {
        JSType jParameterType =
            getJSType(jParameter).restrictByNotNullOrUndefined();
        if (jParameterType.isFunctionType()) {
          FunctionType jParameterFnType = jParameterType.toMaybeFunctionType();
          if (jParameterFnType.getTypeOfThis().equals(iParameterType)) {
            foundTemplateTypeOfThisParameter = true;
            // Find the actual type of the this argument.
            if (j + 1 >= childCount) {
              // TypeCheck#visitParameterList will warn so we bail.
              return;
            }
            Node jArgument = n.getChildAtIndex(j + 1);
            JSType jArgumentType = getJSType(jArgument);
            if (jArgument.isFunction() &&
                jArgumentType.isFunctionType()) {
              if (iArgumentType != null &&
                  // null and undefined get filtered out above.
                  !iArgumentType.isNoType()) {
                // If it's an function expression, update the type of this
                // using the actual type of T.
                FunctionType jArgumentFnType = jArgumentType.toMaybeFunctionType();
                if (jArgumentFnType.getTypeOfThis().isUnknownType()) {
                  // The new type will be picked up when we traverse the inner
                  // function.
                  jArgument.setJSType(
                      registry.createFunctionTypeWithNewThisType(
                          jArgumentFnType, iArgumentType));
                }
              } else {
                // Warn if the anonymous function literal references this.
                if (NodeUtil.referencesThis(
                        NodeUtil.getFunctionBody(jArgument))) {
                  compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
                      FUNCTION_LITERAL_UNDEFINED_THIS));
                }
              }
            }
            // TODO(user): Add code to TypeCheck to check that the
            // types of the arguments match.
          }
        }
        j++;
      }

      if (!foundTemplateTypeOfThisParameter) {
        compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
            TEMPLATE_TYPE_OF_THIS_EXPECTED));
        return;
      }
    }
    i++;
  }
}
 
Example 13
Source File: Closure_35_TypeInference_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * For functions with function(this: T, ...) and T as parameters, type
 * inference will set the type of this on a function literal argument to the
 * the actual type of T.
 */
private void updateTypeOfThisOnClosure(Node n, FunctionType fnType) {
  // TODO(user): Make the template logic more general.

  if (fnType.getTemplateTypeName() == null) {
    return;
  }

  int i = 0;
  int childCount = n.getChildCount();
  // Find the parameter whose type is the template type.
  for (Node iParameter : fnType.getParameters()) {
    JSType iParameterType =
        getJSType(iParameter).restrictByNotNullOrUndefined();
    if (iParameterType.isTemplateType()) {
      // Find the actual type of this argument.
      ObjectType iArgumentType = null;
      if (i + 1 < childCount) {
        Node iArgument = n.getChildAtIndex(i + 1);
        iArgumentType = getJSType(iArgument)
            .restrictByNotNullOrUndefined()
            .collapseUnion()
            .toObjectType();
        if (iArgumentType == null) {
          compiler.report(
              JSError.make(NodeUtil.getSourceName(iArgument), iArgument,
                  TEMPLATE_TYPE_NOT_OBJECT_TYPE,
                  getJSType(iArgument).toString()));
          return;
        }
      }

      // Find the parameter whose type is function(this: T, ...)
      boolean foundTemplateTypeOfThisParameter = false;
      int j = 0;
      for (Node jParameter : fnType.getParameters()) {
        JSType jParameterType =
            getJSType(jParameter).restrictByNotNullOrUndefined();
        if (jParameterType.isFunctionType()) {
          FunctionType jParameterFnType = jParameterType.toMaybeFunctionType();
          if (jParameterFnType.getTypeOfThis().equals(iParameterType)) {
            foundTemplateTypeOfThisParameter = true;
            // Find the actual type of the this argument.
            if (j + 1 >= childCount) {
              // TypeCheck#visitParameterList will warn so we bail.
              return;
            }
            Node jArgument = n.getChildAtIndex(j + 1);
            JSType jArgumentType = getJSType(jArgument);
            if (jArgument.isFunction() &&
                jArgumentType.isFunctionType()) {
              if (iArgumentType != null &&
                  // null and undefined get filtered out above.
                  !iArgumentType.isNoType()) {
                // If it's an function expression, update the type of this
                // using the actual type of T.
                FunctionType jArgumentFnType = jArgumentType.toMaybeFunctionType();
                if (jArgumentFnType.getTypeOfThis().isUnknownType()) {
                  // The new type will be picked up when we traverse the inner
                  // function.
                  jArgument.setJSType(
                      registry.createFunctionTypeWithNewThisType(
                          jArgumentFnType, iArgumentType));
                }
              } else {
                // Warn if the anonymous function literal references this.
                if (NodeUtil.referencesThis(
                        NodeUtil.getFunctionBody(jArgument))) {
                  compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
                      FUNCTION_LITERAL_UNDEFINED_THIS));
                }
              }
            }
            // TODO(user): Add code to TypeCheck to check that the
            // types of the arguments match.
          }
        }
        j++;
      }

      if (!foundTemplateTypeOfThisParameter) {
        compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
            TEMPLATE_TYPE_OF_THIS_EXPECTED));
        return;
      }
    }
    i++;
  }
}
 
Example 14
Source File: Closure_25_TypeInference_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * For functions with function(this: T, ...) and T as parameters, type
 * inference will set the type of this on a function literal argument to the
 * the actual type of T.
 */
private void updateTypeOfThisOnClosure(Node n, FunctionType fnType) {
  // TODO(user): Make the template logic more general.

  if (fnType.getTemplateTypeName() == null) {
    return;
  }

  int i = 0;
  int childCount = n.getChildCount();
  // Find the parameter whose type is the template type.
  for (Node iParameter : fnType.getParameters()) {
    JSType iParameterType =
        getJSType(iParameter).restrictByNotNullOrUndefined();
    if (iParameterType.isTemplateType()) {
      // Find the actual type of this argument.
      ObjectType iArgumentType = null;
      if (i + 1 < childCount) {
        Node iArgument = n.getChildAtIndex(i + 1);
        iArgumentType = getJSType(iArgument)
            .restrictByNotNullOrUndefined()
            .collapseUnion()
            .toObjectType();
        if (iArgumentType == null) {
          compiler.report(
              JSError.make(NodeUtil.getSourceName(iArgument), iArgument,
                  TEMPLATE_TYPE_NOT_OBJECT_TYPE,
                  getJSType(iArgument).toString()));
          return;
        }
      }

      // Find the parameter whose type is function(this: T, ...)
      boolean foundTemplateTypeOfThisParameter = false;
      int j = 0;
      for (Node jParameter : fnType.getParameters()) {
        JSType jParameterType =
            getJSType(jParameter).restrictByNotNullOrUndefined();
        if (jParameterType.isFunctionType()) {
          FunctionType jParameterFnType = jParameterType.toMaybeFunctionType();
          if (jParameterFnType.getTypeOfThis().equals(iParameterType)) {
            foundTemplateTypeOfThisParameter = true;
            // Find the actual type of the this argument.
            if (j + 1 >= childCount) {
              // TypeCheck#visitParameterList will warn so we bail.
              return;
            }
            Node jArgument = n.getChildAtIndex(j + 1);
            JSType jArgumentType = getJSType(jArgument);
            if (jArgument.isFunction() &&
                jArgumentType.isFunctionType()) {
              if (iArgumentType != null &&
                  // null and undefined get filtered out above.
                  !iArgumentType.isNoType()) {
                // If it's an function expression, update the type of this
                // using the actual type of T.
                FunctionType jArgumentFnType = jArgumentType.toMaybeFunctionType();
                if (jArgumentFnType.getTypeOfThis().isUnknownType()) {
                  // The new type will be picked up when we traverse the inner
                  // function.
                  jArgument.setJSType(
                      registry.createFunctionTypeWithNewThisType(
                          jArgumentFnType, iArgumentType));
                }
              } else {
                // Warn if the anonymous function literal references this.
                if (NodeUtil.referencesThis(
                        NodeUtil.getFunctionBody(jArgument))) {
                  compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
                      FUNCTION_LITERAL_UNDEFINED_THIS));
                }
              }
            }
            // TODO(user): Add code to TypeCheck to check that the
            // types of the arguments match.
          }
        }
        j++;
      }

      if (!foundTemplateTypeOfThisParameter) {
        compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
            TEMPLATE_TYPE_OF_THIS_EXPECTED));
        return;
      }
    }
    i++;
  }
}
 
Example 15
Source File: RuntimeTypeCheck.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Insert checks for the parameters of the function.
 */
private void visitFunction(NodeTraversal t, Node n) {
  FunctionType funType = JSType.toMaybeFunctionType(n.getJSType());
  Node block = n.getLastChild();
  Node paramName = NodeUtil.getFunctionParameters(n).getFirstChild();
  Node insertionPoint = null;

  // To satisfy normalization constraints, the type checking must be
  // added after any inner function declarations.
  for (Node next = block.getFirstChild();
       next != null && NodeUtil.isFunctionDeclaration(next);
       next = next.getNext()) {
    insertionPoint = next;
  }

  for (Node paramType : funType.getParameters()) {
    // Can this ever happen?
    if (paramName == null) {
      return;
    }

    Node checkNode = createCheckTypeCallNode(
        paramType.getJSType(), paramName.cloneTree());

    if (checkNode == null) {
      // We don't know how to check this parameter type.
      paramName = paramName.getNext();
      continue;
    }

    checkNode = IR.exprResult(checkNode);
    if (insertionPoint == null) {
      block.addChildToFront(checkNode);
    } else {
      block.addChildAfter(checkNode, insertionPoint);
    }

    compiler.reportCodeChange();
    paramName = paramName.getNext();
    insertionPoint = checkNode;
  }
}
 
Example 16
Source File: Closure_25_TypeInference_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * For functions with function(this: T, ...) and T as parameters, type
 * inference will set the type of this on a function literal argument to the
 * the actual type of T.
 */
private void updateTypeOfThisOnClosure(Node n, FunctionType fnType) {
  // TODO(user): Make the template logic more general.

  if (fnType.getTemplateTypeName() == null) {
    return;
  }

  int i = 0;
  int childCount = n.getChildCount();
  // Find the parameter whose type is the template type.
  for (Node iParameter : fnType.getParameters()) {
    JSType iParameterType =
        getJSType(iParameter).restrictByNotNullOrUndefined();
    if (iParameterType.isTemplateType()) {
      // Find the actual type of this argument.
      ObjectType iArgumentType = null;
      if (i + 1 < childCount) {
        Node iArgument = n.getChildAtIndex(i + 1);
        iArgumentType = getJSType(iArgument)
            .restrictByNotNullOrUndefined()
            .collapseUnion()
            .toObjectType();
        if (iArgumentType == null) {
          compiler.report(
              JSError.make(NodeUtil.getSourceName(iArgument), iArgument,
                  TEMPLATE_TYPE_NOT_OBJECT_TYPE,
                  getJSType(iArgument).toString()));
          return;
        }
      }

      // Find the parameter whose type is function(this: T, ...)
      boolean foundTemplateTypeOfThisParameter = false;
      int j = 0;
      for (Node jParameter : fnType.getParameters()) {
        JSType jParameterType =
            getJSType(jParameter).restrictByNotNullOrUndefined();
        if (jParameterType.isFunctionType()) {
          FunctionType jParameterFnType = jParameterType.toMaybeFunctionType();
          if (jParameterFnType.getTypeOfThis().equals(iParameterType)) {
            foundTemplateTypeOfThisParameter = true;
            // Find the actual type of the this argument.
            if (j + 1 >= childCount) {
              // TypeCheck#visitParameterList will warn so we bail.
              return;
            }
            Node jArgument = n.getChildAtIndex(j + 1);
            JSType jArgumentType = getJSType(jArgument);
            if (jArgument.isFunction() &&
                jArgumentType.isFunctionType()) {
              if (iArgumentType != null &&
                  // null and undefined get filtered out above.
                  !iArgumentType.isNoType()) {
                // If it's an function expression, update the type of this
                // using the actual type of T.
                FunctionType jArgumentFnType = jArgumentType.toMaybeFunctionType();
                if (jArgumentFnType.getTypeOfThis().isUnknownType()) {
                  // The new type will be picked up when we traverse the inner
                  // function.
                  jArgument.setJSType(
                      registry.createFunctionTypeWithNewThisType(
                          jArgumentFnType, iArgumentType));
                }
              } else {
                // Warn if the anonymous function literal references this.
                if (NodeUtil.referencesThis(
                        NodeUtil.getFunctionBody(jArgument))) {
                  compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
                      FUNCTION_LITERAL_UNDEFINED_THIS));
                }
              }
            }
            // TODO(user): Add code to TypeCheck to check that the
            // types of the arguments match.
          }
        }
        j++;
      }

      if (!foundTemplateTypeOfThisParameter) {
        compiler.report(JSError.make(NodeUtil.getSourceName(n), n,
            TEMPLATE_TYPE_OF_THIS_EXPECTED));
        return;
      }
    }
    i++;
  }
}
 
Example 17
Source File: AbstractClosureVisitor.java    From jsinterop-generator with Apache License 2.0 4 votes vote down vote up
private void acceptParameters(FunctionType owner) {
  int index = 0;
  for (Parameter parameter : owner.getParameters()) {
    acceptParameter(parameter, owner, index++);
  }
}
 
Example 18
Source File: TypeExpressionParser.java    From js-dossier with Apache License 2.0 4 votes vote down vote up
@Override
public Void caseFunctionType(FunctionType type) {
  if ("Function".equals(type.getReferenceName())) {
    currentExpression().getNamedTypeBuilder().setName("Function");
    return null;
  }

  com.github.jsdossier.proto.FunctionType.Builder functionType =
      currentExpression().getFunctionTypeBuilder();

  if (type.isConstructor()) {
    functionType.setIsConstructor(true);
    expressions.addLast(functionType.getInstanceTypeBuilder());
    type.getTypeOfThis().visit(this);
    expressions.removeLast();

  } else if (!type.getTypeOfThis().isUnknownType()
      || type.getTypeOfThis() instanceof NamedType) {
    expressions.addLast(functionType.getInstanceTypeBuilder());
    type.getTypeOfThis().visit(this);
    expressions.removeLast();
  }

  for (Node node : type.getParameters()) {
    TypeExpression.Builder parameterType = functionType.addParameterBuilder();
    expressions.addLast(parameterType);

    if (node.isVarArgs()) {
      parameterType.setIsVarargs(true);
    }

    if (node.getJSType() != null) {
      if (node.getJSType().isUnionType()) {
        caseUnionType((UnionType) node.getJSType(), node.isOptionalArg());
      } else {
        node.getJSType().visit(this);
      }
    }

    if (node.isOptionalArg()) {
      // Not sure if this is possible, but varargs implies optional and we only permit one
      // bit to be set.
      if (!parameterType.getIsVarargs()) {
        parameterType.setIsOptional(true);
      }
    }

    expressions.removeLast();
  }

  if (type.getReturnType() != null && !type.isConstructor()) {
    expressions.addLast(functionType.getReturnTypeBuilder());
    type.getReturnType().visit(this);
    expressions.removeLast();
  }
  return null;
}