javac 7 bug: incorrect parsing of @deprecated javadoc tag

cushon cushon at google.com
Wed Nov 6 19:33:38 PST 2013


I found a small bug in the way javac 7 parses the @deprecated javadoc tag.

Javac assumes that javadoc always occurs before modifiers when it parses
member
declarations. This breaks the dep-ann xlint warning when @Deprecated appears
before /** @deprecated */, because the javadoc tag gets incorrectly applied
to
the next member declaration in the class.

For example:

class C {
  @Deprecated
  /** @deprecated */
  void f() {}

  void g() {} // dep-ann warning reported here
}

The changes to doc comment parsing in javac 8 appear to have fixed this
issue, but I thought the regression test might still be useful. I've
attached a patch with the test cases and a fix for javac 7.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20131106/44d2e909/attachment.html 
-------------- next part --------------
# HG changeset patch
# User cushon <cushon at google.com>
# Date 1383791457 28800
# Node ID 1e212a803553fb59845c2e4f308ead921d204df6
# Parent  ce654f4ecfd8fd5f81618c7e0949f22db08de4d5
Fix javac parsing of the @deprecated javadoc tag

Javac assumes that javadoc always occurs before modifiers when it parses member
declarations. This breaks the dep-ann xlint warning when @Deprecated appears
before /** @deprecated */, because the javadoc tag gets incorrectly applied to
the next member declaration in the class.

diff -r ce654f4ecfd8 -r 1e212a803553 src/share/classes/com/sun/tools/javac/parser/JavacParser.java
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Jun 27 13:21:47 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Nov 06 18:30:57 2013 -0800
@@ -1972,10 +1972,6 @@
             annotations.appendList(partial.annotations);
             pos = partial.pos;
         }
-        if (S.deprecatedFlag()) {
-            flags |= Flags.DEPRECATED;
-            S.resetDeprecatedFlag();
-        }
         int lastPos = Position.NOPOS;
     loop:
         while (true) {
@@ -2018,6 +2014,13 @@
         default: break;
         }
 
+        // Wait until all the modifiers have been parsed before checking for the @deprecated
+        // javadoc tag, in case an annotation appeared before the javadoc.
+        if (S.deprecatedFlag()) {
+            flags |= Flags.DEPRECATED;
+            S.resetDeprecatedFlag();
+        }
+
         /* A modifiers tree with no modifier tokens or annotations
          * has no text position. */
         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
diff -r ce654f4ecfd8 -r 1e212a803553 test/tools/javac/warnings/AnnotationBeforeDocComment.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/warnings/AnnotationBeforeDocComment.java	Wed Nov 06 18:30:57 2013 -0800
@@ -0,0 +1,167 @@
+/*
+ * Make sure the compiler scans for the @deprecated javadoc tag in doccomments
+ * that appear after the @Deprecated annotation.
+ */
+
+/**
+ * @test
+ * @summary deprecated annotations that appear before javadoc should still work
+ * @compile/ref=AnnotationBeforeDocComment.out -Xlint:dep-ann -XDrawDiagnostics AnnotationBeforeDocComment.java
+ * @compile/fail -Xlint:dep-ann -Werror AnnotationBeforeDocComment.java
+ */
+
+class AnnotationBeforeDocComment {
+
+  @Deprecated
+  /**
+   * @deprecated
+   */
+  class C{}
+
+  class D{}
+
+  /**
+   * @deprecated
+   */
+  @Deprecated
+  /**
+   * foo
+   */
+  class E{}
+
+  class F{}
+
+  /**
+   * foo
+   */
+  /**
+   * @deprecated
+   */
+  class G{} // warning
+
+  class H{}
+
+  /**
+   * @deprecated
+   */
+  /**
+   * foo
+   */
+  class I{} // warning
+
+  class K{}
+
+  @Deprecated
+  /**
+   * @deprecated
+   */
+  /**
+   * foo
+   */
+  class L{}
+
+  class M{}
+
+  /**
+   * @deprecated
+   */
+  @Deprecated
+  /**
+   * foo
+   */
+  class N{}
+
+  class O{}
+
+  /**
+   * @deprecated
+   */
+  /**
+   * foo
+   */
+  @Deprecated
+  class P{}
+
+  class Q{}
+
+  @Deprecated
+  /**
+   * @deprecated
+   */
+  void a() {}
+
+  void b() {}
+
+  /**
+   * @deprecated
+   */
+  @Deprecated
+  /**
+   * foo
+   */
+  void c() {}
+
+  void d() {}
+
+  /**
+   * foo
+   */
+  /**
+   * @deprecated
+   */
+  void e() {} // warning
+
+  void f() {}
+
+  /**
+   * @deprecated
+   */
+  /**
+   * foo
+   */
+  void g() {} // warning
+
+  void h() {}
+
+  @Deprecated
+  /**
+   * foo
+   */
+  /**
+   * @deprecated
+   */
+  void i() {}
+
+  void j() {}
+
+  /**
+   * foo
+   */
+  @Deprecated
+  /**
+   * @deprecated
+   */
+  void k() {}
+
+  void l() {}
+
+  /**
+   * foo
+   */
+  /**
+   * @deprecated
+   */
+  @Deprecated
+  void m() {}
+
+  void n() {}
+
+
+  /**
+   * @deprecated
+   */
+  @Deprecated
+  void o() {}
+
+  void p() {}
+}
diff -r ce654f4ecfd8 -r 1e212a803553 test/tools/javac/warnings/AnnotationBeforeDocComment.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/warnings/AnnotationBeforeDocComment.out	Wed Nov 06 18:30:57 2013 -0800
@@ -0,0 +1,5 @@
+AnnotationBeforeDocComment.java:40:3: compiler.warn.missing.deprecated.annotation
+AnnotationBeforeDocComment.java:50:3: compiler.warn.missing.deprecated.annotation
+AnnotationBeforeDocComment.java:112:8: compiler.warn.missing.deprecated.annotation
+AnnotationBeforeDocComment.java:122:8: compiler.warn.missing.deprecated.annotation
+4 warnings


More information about the compiler-dev mailing list