use of com.google.javascript.rhino.jstype.FunctionParamBuilder in project closure-compiler by google.
the class FunctionTypeBuilder method inferParameterTypes.
/**
* Infer the parameter types from the list of parameter names and the JSDoc info.
*/
FunctionTypeBuilder inferParameterTypes(@Nullable Node paramsParent, @Nullable JSDocInfo info) {
if (paramsParent == null) {
if (info == null) {
return this;
} else {
return inferParameterTypes(info);
}
}
// arguments
final Iterator<Parameter> oldParameters;
Parameter oldParameterType = null;
if (parameters != null) {
oldParameters = parameters.iterator();
oldParameterType = oldParameters.hasNext() ? oldParameters.next() : null;
} else {
oldParameters = Collections.emptyIterator();
}
FunctionParamBuilder builder = new FunctionParamBuilder(typeRegistry);
boolean warnedAboutArgList = false;
Set<String> allJsDocParams = (info == null) ? new HashSet<>() : new HashSet<>(info.getParameterNames());
boolean isVarArgs = false;
int paramIndex = 0;
for (Node param = paramsParent.getFirstChild(); param != null; param = param.getNext()) {
boolean isOptionalParam = false;
final Node paramLhs;
if (param.isRest()) {
isVarArgs = true;
paramLhs = param.getOnlyChild();
} else if (param.isDefaultValue()) {
// The first child is the actual positional parameter
paramLhs = checkNotNull(param.getFirstChild(), param);
isOptionalParam = true;
} else {
isVarArgs = isVarArgsParameterByConvention(param);
isOptionalParam = isOptionalParameterByConvention(param);
paramLhs = param;
}
String paramName = null;
if (paramLhs.isName()) {
paramName = paramLhs.getString();
} else {
checkState(paramLhs.isDestructuringPattern());
// third JSDoc parameter.
if (info != null) {
paramName = info.getParameterNameAt(paramIndex);
}
}
allJsDocParams.remove(paramName);
// type from JSDocInfo
JSType parameterType = null;
if (info != null && info.hasParameterType(paramName)) {
JSTypeExpression parameterTypeExpression = info.getParameterType(paramName);
parameterType = parameterTypeExpression.evaluate(templateScope, typeRegistry);
isOptionalParam = isOptionalParam || parameterTypeExpression.isOptionalArg();
isVarArgs = isVarArgs || parameterTypeExpression.isVarArgs();
} else if (paramLhs.getJSDocInfo() != null && paramLhs.getJSDocInfo().hasType()) {
JSTypeExpression parameterTypeExpression = paramLhs.getJSDocInfo().getType();
parameterType = parameterTypeExpression.evaluate(templateScope, typeRegistry);
isOptionalParam = parameterTypeExpression.isOptionalArg();
isVarArgs = parameterTypeExpression.isVarArgs();
} else if (oldParameterType != null && oldParameterType.getJSType() != null) {
parameterType = oldParameterType.getJSType();
isOptionalParam = oldParameterType.isOptional();
isVarArgs = oldParameterType.isVariadic();
} else {
parameterType = typeRegistry.getNativeType(UNKNOWN_TYPE);
}
warnedAboutArgList |= addParameter(builder, parameterType, warnedAboutArgList, isOptionalParam, isVarArgs);
oldParameterType = oldParameters.hasNext() ? oldParameters.next() : null;
paramIndex++;
}
// Copy over any old parameters that aren't in the param list.
if (!isVarArgs) {
while (oldParameterType != null && !isVarArgs) {
builder.newParameterFrom(oldParameterType);
oldParameterType = oldParameters.hasNext() ? oldParameters.next() : null;
}
}
for (String inexistentName : allJsDocParams) {
reportWarning(INEXISTENT_PARAM, inexistentName, formatFnName());
}
parameters = builder.build();
return this;
}
use of com.google.javascript.rhino.jstype.FunctionParamBuilder in project closure-compiler by google.
the class FunctionTypeBuilder method inferFromOverriddenFunction.
/**
* Infer the parameter and return types of a function from
* the parameter and return types of the function it is overriding.
*
* @param oldType The function being overridden. Does nothing if this is null.
* @param paramsParent The PARAM_LIST node of the function that we're assigning to.
* If null, that just means we're not initializing this to a function
* literal.
*/
FunctionTypeBuilder inferFromOverriddenFunction(@Nullable FunctionType oldType, @Nullable Node paramsParent) {
if (oldType == null) {
return this;
}
// Propagate the template types, if they exist.
this.templateTypeNames = oldType.getTemplateTypeMap().getTemplateKeys();
returnType = oldType.getReturnType();
returnTypeInferred = oldType.isReturnTypeInferred();
if (paramsParent == null) {
// Not a function literal.
parameters = oldType.getParameters();
if (parameters == null) {
parameters = new FunctionParamBuilder(typeRegistry).build();
}
} else {
// We're overriding with a function literal. Apply type information
// to each parameter of the literal.
FunctionParamBuilder paramBuilder = new FunctionParamBuilder(typeRegistry);
Iterator<Parameter> oldParams = oldType.getParameters().iterator();
boolean warnedAboutArgList = false;
boolean oldParamsListHitOptArgs = false;
for (Node currentParam = paramsParent.getFirstChild(); currentParam != null; currentParam = currentParam.getNext()) {
if (oldParams.hasNext()) {
Parameter oldParam = oldParams.next();
oldParamsListHitOptArgs = oldParamsListHitOptArgs || oldParam.isVariadic() || oldParam.isOptional();
// The subclass method might write its var_args as individual arguments.
boolean isOptionalArg = oldParam.isOptional();
boolean isVarArgs = oldParam.isVariadic();
if (currentParam.getNext() != null && isVarArgs) {
isVarArgs = false;
isOptionalArg = true;
}
// with a default value
if (currentParam.isDefaultValue()) {
isOptionalArg = true;
}
paramBuilder.newParameterFrom(Parameter.create(oldParam.getJSType(), isOptionalArg, isVarArgs));
} else {
warnedAboutArgList |= addParameter(paramBuilder, typeRegistry.getNativeType(UNKNOWN_TYPE), warnedAboutArgList, codingConvention.isOptionalParameter(currentParam) || oldParamsListHitOptArgs || currentParam.isDefaultValue(), codingConvention.isVarArgsParameter(currentParam));
}
}
// but make them optional.
while (oldParams.hasNext()) {
paramBuilder.newOptionalParameterFrom(oldParams.next());
}
parameters = paramBuilder.build();
}
return this;
}
Aggregations