…lines 1–67 unchanged (67 lines)
68 private final JSTypeRegistry typeRegistry;
69 private final Node errorRoot;
70 private final String sourceName;
71 private final Scope scope;
72
73 private JSType returnType = null;
74 private boolean returnTypeInferred = false;
75 private List<ObjectType> implementedInterfaces = null;
76 private ObjectType baseType = null;
77 private ObjectType thisType = null;
78 private boolean isConstructor = false;
79 private boolean isInterface = false;
80 private Node parametersNode = null;
…lines 81–194 unchanged (114 lines)
195
196 /**
197 * Infer the return type from JSDocInfo.
198 */
199 FunctionTypeBuilder inferReturnType(@Nullable JSDocInfo info) {
200 returnType = info != null && info.hasReturnType() ?
201 info.getReturnType().evaluate(scope, typeRegistry) : null;
202 if (templateTypeName != null &&
203 returnType != null &&
204 returnType.restrictByNotNullOrUndefined().isTemplateType()) {
205 reportError(TEMPLATE_TYPE_EXPECTED, fnName);
206 }
207 return this;
208 }
209
210 /**
211 * If we haven't found a return value yet, try to look at the "return"
212 * statements in the function.
213 */
214 FunctionTypeBuilder inferReturnStatements(@Nullable Node functionBlock) {
215 if (functionBlock == null || compiler.getInput(sourceName).isExtern()) {
216 return this;
217 }
218 Preconditions.checkArgument(functionBlock.getType() == Token.BLOCK);
219 if (returnType == null) {
220 boolean hasNonEmptyReturns = false;
221 List<Node> worklist = Lists.newArrayList(functionBlock);
222 while (!worklist.isEmpty()) {
223 Node current = worklist.remove(worklist.size() - 1);
224 int cType = current.getType();
225 if (cType == Token.RETURN && current.getFirstChild() != null ||
226 cType == Token.THROW) {
227 hasNonEmptyReturns = true;
228 break;
229 } else if (NodeUtil.isStatementBlock(current) ||
230 NodeUtil.isControlStructure(current)) {
231 for (Node child = current.getFirstChild();
232 child != null; child = child.getNext()) {
233 worklist.add(child);
234 }
235 }
236 }
237
238 if (!hasNonEmptyReturns) {
239 returnType = typeRegistry.getNativeType(VOID_TYPE);
240 returnTypeInferred = true;
241 }
242 }
243 return this;
244 }
245
246 /**
247 * Infer the role of the function (whether it's a constructor or interface)
248 * and what it inherits from in JSDocInfo.
249 */
250 FunctionTypeBuilder inferInheritance(@Nullable JSDocInfo info) {
…lines 251–520 unchanged (270 lines)
521 maybeSetBaseType(fnType);
522 } else {
523 fnType = new FunctionBuilder(typeRegistry)
524 .withName(fnName)
525 .withSourceNode(sourceNode)
526 .withParamsNode(parametersNode)
527 .withReturnType(returnType, returnTypeInferred)
528 .withTypeOfThis(thisType)
529 .withTemplateName(templateTypeName)
530 .build();
531 maybeSetBaseType(fnType);
532 }
533
…lines 534–619 unchanged (86 lines)