Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1645)

Unified Diff: Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/RequiredThisAnnotationChecker.java

Issue 137553005: DevTools: [JsDocValidator] Refactor JsDoc annotation checkers (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Limit the thread count by the number of validated files Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/RequiredThisAnnotationChecker.java
diff --git a/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/RequiredThisAnnotationChecker.java b/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/RequiredThisAnnotationChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..830c253236d03c3785af0b84beed82d184437a81
--- /dev/null
+++ b/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/RequiredThisAnnotationChecker.java
@@ -0,0 +1,85 @@
+package org.chromium.devtools.jsdoc.checks;
+
+import com.google.javascript.rhino.head.Token;
+import com.google.javascript.rhino.head.ast.Assignment;
+import com.google.javascript.rhino.head.ast.AstNode;
+import com.google.javascript.rhino.head.ast.FunctionNode;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public final class RequiredThisAnnotationChecker extends ContextTrackingChecker {
+
+ private final Set<FunctionRecord> functionsRequiringThisAnnotation = new HashSet<>();
+
+ @Override
+ void enterNode(AstNode node) {
+ if (node.getType() == Token.THIS) {
+ FunctionRecord record = getState().getCurrentFunctionRecord();
+ if (record == null) {
+ return;
+ }
+ if (!record.isTopLevelFunction()
+ && !record.isConstructor
+ && (hasEnclosingConstructor(record)
+ || record.enclosingFunctionRecord.enclosingType != null)) {
+ functionsRequiringThisAnnotation.add(record);
+ }
+ return;
+ }
+ }
+
+ private boolean hasEnclosingConstructor(FunctionRecord record) {
+ FunctionRecord parent = record.enclosingFunctionRecord;
+ while (parent != null) {
+ if (parent.isConstructor) {
+ return true;
+ }
+ parent = parent.enclosingFunctionRecord;
+ }
+ return false;
+ }
+
+ @Override
+ void leaveNode(AstNode node) {
+ if (node.getType() != Token.FUNCTION) {
+ return;
+ }
+
+ ContextTrackingState state = getState();
+ FunctionRecord record = state.getCurrentFunctionRecord();
+ if (!functionsRequiringThisAnnotation.contains(record)) {
+ return;
+ }
+ FunctionNode functionNode = (FunctionNode) node;
+ AstNode functionNameNode = AstUtil.getFunctionNameNode(functionNode);
+ if (functionNameNode != null && shouldAddThisAnnotation(functionNode)) {
+ state.getContext().reportErrorInNode(functionNameNode, 0,
+ "@this annotation is required for functions referencing 'this'");
+ }
+ }
+
+ private boolean shouldAddThisAnnotation(FunctionNode node) {
+ String jsDoc = getJsDoc(node);
+ return jsDoc == null || !jsDoc.contains("@this");
+ }
+
+ private String getJsDoc(FunctionNode functionNode) {
+ String jsDoc = functionNode.getJsDoc();
+ if (jsDoc != null) {
+ return jsDoc;
+ }
+
+ // reader.onloadend = function() {...}
+ if (AstUtil.hasParentOfType(functionNode, Token.ASSIGN)) {
+ Assignment assignment = (Assignment) functionNode.getParent();
+ if (assignment.getRight() == functionNode) {
+ jsDoc = assignment.getJsDoc();
+ if (jsDoc != null) {
+ return jsDoc;
+ }
+ }
+ }
+ return null;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698