1 package org.chromium.devtools.jsdoc.checks;
3 import com.google.javascript.rhino.head.Token;
4 import com.google.javascript.rhino.head.ast.AstNode;
5 import com.google.javascript.rhino.head.ast.Comment;
6 import com.google.javascript.rhino.head.ast.FunctionNode;
8 import java.util.HashSet;
11 public final class RequiredThisAnnotationChecker extends ContextTrackingChecker {
13 private final Set<FunctionRecord> functionsRequiringThisAnnotation = new HashSet<>();
16 void enterNode(AstNode node) {
17 if (node.getType() == Token.THIS) {
18 FunctionRecord function = getState().getCurrentFunctionRecord();
19 if (function == null) {
22 if (!function.isTopLevelFunction() && !function.isConstructor) {
23 functionsRequiringThisAnnotation.add(function);
30 void leaveNode(AstNode node) {
31 if (node.getType() != Token.FUNCTION) {
35 ContextTrackingState state = getState();
36 FunctionRecord record = state.getCurrentFunctionRecord();
37 if (!functionsRequiringThisAnnotation.contains(record)) {
40 FunctionNode functionNode = (FunctionNode) node;
41 AstNode functionNameNode = AstUtil.getFunctionNameNode(functionNode);
42 if (functionNameNode != null && shouldAddThisAnnotation(functionNode)) {
43 state.getContext().reportErrorInNode(functionNameNode, 0,
44 "@this annotation is required for functions referencing 'this'");
48 private boolean shouldAddThisAnnotation(FunctionNode node) {
49 Comment comment = AstUtil.getJsDocNode(node);
50 return comment == null || !getContext().getNodeText(comment).contains("@this");