8007096: DocLint parsing problems with some comments
authorjjg
Wed, 30 Jan 2013 09:40:54 -0800
changeset 15552 99e4c7eb352c
parent 15551 64c22739fdb8
child 15553 1636d13162e0
8007096: DocLint parsing problems with some comments Reviewed-by: mcimadamore
langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java
langtools/test/tools/doclint/EndWithIdentifierTest.java
langtools/test/tools/doclint/EndWithIdentifierTest.out
langtools/test/tools/doclint/UnfinishedInlineTagTest.java
langtools/test/tools/doclint/UnfinishedInlineTagTest.out
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Sun Jan 27 19:38:44 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Wed Jan 30 09:40:54 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -279,13 +279,7 @@
         try {
             nextChar();
             if (isIdentifierStart(ch)) {
-                int namePos = bp;
-                nextChar();
-                while (isIdentifierPart(ch))
-                    nextChar();
-                int nameLen = bp - namePos;
-
-                Name name = names.fromChars(buf, namePos, nameLen);
+                Name name = readIdentifier();
                 TagParser tp = tagParsers.get(name);
                 if (tp == null) {
                     List<DCTree> content = blockContent();
@@ -334,14 +328,9 @@
         try {
             nextChar();
             if (isIdentifierStart(ch)) {
-                int namePos = bp;
-                nextChar();
-                while (isIdentifierPart(ch))
-                    nextChar();
-                int nameLen = bp - namePos;
+                Name name = readIdentifier();
                 skipWhitespace();
 
-                Name name = names.fromChars(buf, namePos, nameLen);
                 TagParser tp = tagParsers.get(name);
                 if (tp == null) {
                     DCTree text = inlineText();
@@ -575,10 +564,8 @@
         int pos = bp;
 
         if (isJavaIdentifierStart(ch)) {
-            nextChar();
-            while (isJavaIdentifierPart(ch))
-                nextChar();
-            return m.at(pos).Identifier(names.fromChars(buf, pos, bp - pos));
+            Name name = readJavaIdentifier();
+            return m.at(pos).Identifier(name);
         }
 
         throw new ParseException("dc.identifier.expected");
@@ -703,39 +690,36 @@
     protected DCTree entity() {
         int p = bp;
         nextChar();
-        int namep = bp;
+        Name name = null;
         boolean checkSemi = false;
         if (ch == '#') {
+            int namep = bp;
             nextChar();
             if (isDecimalDigit(ch)) {
                 nextChar();
                 while (isDecimalDigit(ch))
                     nextChar();
-                checkSemi = true;
+                name = names.fromChars(buf, namep, bp - namep);
             } else if (ch == 'x' || ch == 'X') {
                 nextChar();
                 if (isHexDigit(ch)) {
                     nextChar();
                     while (isHexDigit(ch))
                         nextChar();
-                    checkSemi = true;
+                    name = names.fromChars(buf, namep, bp - namep);
                 }
             }
         } else if (isIdentifierStart(ch)) {
-            nextChar();
-            while (isIdentifierPart(ch))
-                nextChar();
-            checkSemi = true;
+            name = readIdentifier();
         }
 
-        if (checkSemi && ch == ';') {
+        if (name == null)
+            return erroneous("dc.bad.entity", p);
+        else {
+            if (ch != ';')
+                return erroneous("dc.missing.semicolon", p);
             nextChar();
-            return m.at(p).Entity(names.fromChars(buf, namep, bp - namep - 1));
-        } else {
-            String code = checkSemi
-                    ? "dc.missing.semicolon"
-                    : "dc.bad.entity";
-            return erroneous(code, p);
+            return m.at(p).Entity(name);
         }
     }
 
@@ -747,11 +731,7 @@
         int p = bp;
         nextChar();
         if (isIdentifierStart(ch)) {
-            int namePos = bp;
-            nextChar();
-            while (isIdentifierPart(ch))
-                nextChar();
-            int nameLen = bp - namePos;
+            Name name = readIdentifier();
             List<DCTree> attrs = htmlAttrs();
             if (attrs != null) {
                 boolean selfClosing = false;
@@ -761,22 +741,16 @@
                 }
                 if (ch == '>') {
                     nextChar();
-                    Name name = names.fromChars(buf, namePos, nameLen);
                     return m.at(p).StartElement(name, attrs, selfClosing);
                 }
             }
         } else if (ch == '/') {
             nextChar();
             if (isIdentifierStart(ch)) {
-                int namePos = bp;
-                nextChar();
-                while (isIdentifierPart(ch))
-                    nextChar();
-                int nameLen = bp - namePos;
+                Name name = readIdentifier();
                 skipWhitespace();
                 if (ch == '>') {
                     nextChar();
-                    Name name = names.fromChars(buf, namePos, nameLen);
                     return m.at(p).EndElement(name);
                 }
             }
@@ -822,10 +796,7 @@
         loop:
         while (isIdentifierStart(ch)) {
             int namePos = bp;
-            nextChar();
-            while (isIdentifierPart(ch))
-                nextChar();
-            int nameLen = bp - namePos;
+            Name name = readIdentifier();
             skipWhitespace();
             List<DCTree> value = null;
             ValueKind vkind = ValueKind.EMPTY;
@@ -862,7 +833,6 @@
                 skipWhitespace();
                 value = v.toList();
             }
-            Name name = names.fromChars(buf, namePos, nameLen);
             DCAttribute attr = m.at(namePos).Attribute(name, vkind, value);
             attrs.add(attr);
         }
@@ -897,7 +867,7 @@
     protected DCErroneous erroneous(String code, int pos) {
         int i = bp - 1;
         loop:
-        while (i > 0) {
+        while (i > pos) {
             switch (buf[i]) {
                 case '\f': case '\n': case '\r':
                     newline = true;
@@ -926,16 +896,24 @@
         return Character.isUnicodeIdentifierStart(ch);
     }
 
-    protected boolean isIdentifierPart(char ch) {
-        return Character.isUnicodeIdentifierPart(ch);
+    protected Name readIdentifier() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && Character.isUnicodeIdentifierPart(ch))
+            nextChar();
+        return names.fromChars(buf, start, bp - start);
     }
 
     protected boolean isJavaIdentifierStart(char ch) {
         return Character.isJavaIdentifierStart(ch);
     }
 
-    protected boolean isJavaIdentifierPart(char ch) {
-        return Character.isJavaIdentifierPart(ch);
+    protected Name readJavaIdentifier() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && Character.isJavaIdentifierPart(ch))
+            nextChar();
+        return names.fromChars(buf, start, bp - start);
     }
 
     protected boolean isDecimalDigit(char ch) {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java	Sun Jan 27 19:38:44 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java	Wed Jan 30 09:40:54 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -236,7 +236,7 @@
             // relative to the best match found in the array.
             if (pos == Position.NOPOS)
                 return Position.NOPOS;
-            if (pos < 0 || pos >= docComment.length())
+            if (pos < 0 || pos > docComment.length())
                 throw new StringIndexOutOfBoundsException(String.valueOf(pos));
             if (docPosns == null)
                 return Position.NOPOS;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndWithIdentifierTest.java	Wed Jan 30 09:40:54 2013 -0800
@@ -0,0 +1,32 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8007096
+ * @summary DocLint parsing problems with some comments
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html EndWithIdentifierTest.java
+ * @run main DocLintTester -Xmsgs -ref EndWithIdentifierTest.out EndWithIdentifierTest.java
+ * @author jlahoda
+ */
+
+/**@deprecated*/
+public class EndWithIdentifierTest {
+
+    /**{@link*/
+    private void unfinishedInlineTagName() {}
+
+    /**@see List*/
+    private void endsWithIdentifier() {}
+
+    /**&amp*/
+    private void entityName() {}
+
+    /**<a*/
+    private void tag() {}
+
+    /**</a*/
+    private void tagEnd() {}
+
+    /**<a name*/
+    private void attribute() {}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndWithIdentifierTest.out	Wed Jan 30 09:40:54 2013 -0800
@@ -0,0 +1,20 @@
+EndWithIdentifierTest.java:14: error: syntax error in reference
+    /**{@link*/
+       ^
+EndWithIdentifierTest.java:17: error: reference not found
+    /**@see List*/
+            ^
+EndWithIdentifierTest.java:20: error: semicolon missing
+    /**&amp*/
+       ^
+EndWithIdentifierTest.java:23: error: malformed HTML
+    /**<a*/
+       ^
+EndWithIdentifierTest.java:26: error: malformed HTML
+    /**</a*/
+       ^
+EndWithIdentifierTest.java:29: error: malformed HTML
+    /**<a name*/
+       ^
+6 errors
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/UnfinishedInlineTagTest.java	Wed Jan 30 09:40:54 2013 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8007096
+ * @summary DocLint parsing problems with some comments
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html UnfinishedInlineTagTest.java
+ * @run main DocLintTester -Xmsgs -ref UnfinishedInlineTagTest.out UnfinishedInlineTagTest.java
+ * @author jlahoda
+ */
+
+import java.util.List;
+
+/**{@link List
+ */
+public class UnfinishedInlineTagTest {
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/UnfinishedInlineTagTest.out	Wed Jan 30 09:40:54 2013 -0800
@@ -0,0 +1,5 @@
+UnfinishedInlineTagTest.java:14: error: unterminated inline tag
+ */
+^
+1 error
+