mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 10:34:38 +02:00
6877202: Elements.getDocComment() is not getting JavaDocComments
6861094: javac -Xprint <file> does not print comments 6985205: access to tree positions and doc comments may be lost across annotation processing rounds Reviewed-by: darcy
This commit is contained in:
parent
26f967ece4
commit
2730836d77
19 changed files with 785 additions and 122 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -99,9 +99,6 @@ public class JavaCompiler extends com.sun.tools.javac.main.JavaCompiler {
|
||||||
private static Context preRegister(Context context) {
|
private static Context preRegister(Context context) {
|
||||||
Bark.preRegister(context);
|
Bark.preRegister(context);
|
||||||
|
|
||||||
// force the use of the scanner that captures Javadoc comments
|
|
||||||
DocCommentScanner.Factory.preRegister(context);
|
|
||||||
|
|
||||||
if (context.get(JavaFileManager.class) == null)
|
if (context.get(JavaFileManager.class) == null)
|
||||||
JavacFileManager.preRegister(context);
|
JavacFileManager.preRegister(context);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -96,9 +96,6 @@ public class JavacTaskImpl extends JavacTask {
|
||||||
args.getClass();
|
args.getClass();
|
||||||
context.getClass();
|
context.getClass();
|
||||||
fileObjects.getClass();
|
fileObjects.getClass();
|
||||||
|
|
||||||
// force the use of the scanner that captures Javadoc comments
|
|
||||||
com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JavacTaskImpl(JavacTool tool,
|
JavacTaskImpl(JavacTool tool,
|
||||||
|
@ -337,9 +334,13 @@ public class JavacTaskImpl extends JavacTask {
|
||||||
|
|
||||||
ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>();
|
ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>();
|
||||||
for (JCCompilationUnit unit : units) {
|
for (JCCompilationUnit unit : units) {
|
||||||
for (JCTree node : unit.defs)
|
for (JCTree node : unit.defs) {
|
||||||
if (node.getTag() == JCTree.CLASSDEF)
|
if (node.getTag() == JCTree.CLASSDEF) {
|
||||||
elements.append(((JCTree.JCClassDecl) node).sym);
|
JCClassDecl cdef = (JCClassDecl) node;
|
||||||
|
if (cdef.sym != null) // maybe null if errors in anno processing
|
||||||
|
elements.append(cdef.sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return elements.toList();
|
return elements.toList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -62,9 +62,6 @@ import static javax.tools.StandardLocation.CLASS_OUTPUT;
|
||||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
|
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
|
||||||
import static com.sun.tools.javac.util.ListBuffer.lb;
|
import static com.sun.tools.javac.util.ListBuffer.lb;
|
||||||
|
|
||||||
// TEMP, until we have a more efficient way to save doc comment info
|
|
||||||
import com.sun.tools.javac.parser.DocCommentScanner;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import javax.lang.model.SourceVersion;
|
import javax.lang.model.SourceVersion;
|
||||||
|
@ -964,11 +961,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||||
processAnnotations = procEnvImpl.atLeastOneProcessor();
|
processAnnotations = procEnvImpl.atLeastOneProcessor();
|
||||||
|
|
||||||
if (processAnnotations) {
|
if (processAnnotations) {
|
||||||
if (context.get(Scanner.Factory.scannerFactoryKey) == null)
|
|
||||||
DocCommentScanner.Factory.preRegister(context);
|
|
||||||
options.put("save-parameter-names", "save-parameter-names");
|
options.put("save-parameter-names", "save-parameter-names");
|
||||||
reader.saveParameterNames = true;
|
reader.saveParameterNames = true;
|
||||||
keepComments = true;
|
keepComments = true;
|
||||||
|
genEndPos = true;
|
||||||
if (taskListener != null)
|
if (taskListener != null)
|
||||||
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
|
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
|
||||||
log.deferDiagnostics = true;
|
log.deferDiagnostics = true;
|
||||||
|
@ -1587,6 +1583,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initRound(JavaCompiler prev) {
|
public void initRound(JavaCompiler prev) {
|
||||||
|
genEndPos = prev.genEndPos;
|
||||||
keepComments = prev.keepComments;
|
keepComments = prev.keepComments;
|
||||||
start_msec = prev.start_msec;
|
start_msec = prev.start_msec;
|
||||||
hasBeenUsed = true;
|
hasBeenUsed = true;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -42,50 +42,17 @@ import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||||
*/
|
*/
|
||||||
public class DocCommentScanner extends Scanner {
|
public class DocCommentScanner extends Scanner {
|
||||||
|
|
||||||
/** A factory for creating scanners. */
|
|
||||||
public static class Factory extends Scanner.Factory {
|
|
||||||
|
|
||||||
public static void preRegister(final Context context) {
|
|
||||||
context.put(scannerFactoryKey, new Context.Factory<Scanner.Factory>() {
|
|
||||||
public Factory make() {
|
|
||||||
return new Factory(context);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a new scanner factory. */
|
|
||||||
protected Factory(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Scanner newScanner(CharSequence input) {
|
|
||||||
if (input instanceof CharBuffer) {
|
|
||||||
return new DocCommentScanner(this, (CharBuffer)input);
|
|
||||||
} else {
|
|
||||||
char[] array = input.toString().toCharArray();
|
|
||||||
return newScanner(array, array.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Scanner newScanner(char[] input, int inputLength) {
|
|
||||||
return new DocCommentScanner(this, input, inputLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Create a scanner from the input buffer. buffer must implement
|
/** Create a scanner from the input buffer. buffer must implement
|
||||||
* array() and compact(), and remaining() must be less than limit().
|
* array() and compact(), and remaining() must be less than limit().
|
||||||
*/
|
*/
|
||||||
protected DocCommentScanner(Factory fac, CharBuffer buffer) {
|
protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) {
|
||||||
super(fac, buffer);
|
super(fac, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a scanner from the input array. The array must have at
|
/** Create a scanner from the input array. The array must have at
|
||||||
* least a single character of extra space.
|
* least a single character of extra space.
|
||||||
*/
|
*/
|
||||||
protected DocCommentScanner(Factory fac, char[] input, int inputLength) {
|
protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) {
|
||||||
super(fac, input, inputLength);
|
super(fac, input, inputLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2473,6 +2473,11 @@ public class JavacParser implements Parser {
|
||||||
defs.append(importDeclaration());
|
defs.append(importDeclaration());
|
||||||
} else {
|
} else {
|
||||||
JCTree def = typeDeclaration(mods);
|
JCTree def = typeDeclaration(mods);
|
||||||
|
if (keepDocComments && dc != null && docComments.get(def) == dc) {
|
||||||
|
// If the first type declaration has consumed the first doc
|
||||||
|
// comment, then don't use it for the top level comment as well.
|
||||||
|
dc = null;
|
||||||
|
}
|
||||||
if (def instanceof JCExpressionStatement)
|
if (def instanceof JCExpressionStatement)
|
||||||
def = ((JCExpressionStatement)def).expr;
|
def = ((JCExpressionStatement)def).expr;
|
||||||
defs.append(def);
|
defs.append(def);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -59,7 +59,7 @@ public class ParserFactory {
|
||||||
final Source source;
|
final Source source;
|
||||||
final Names names;
|
final Names names;
|
||||||
final Options options;
|
final Options options;
|
||||||
final Scanner.Factory scannerFactory;
|
final ScannerFactory scannerFactory;
|
||||||
|
|
||||||
protected ParserFactory(Context context) {
|
protected ParserFactory(Context context) {
|
||||||
super();
|
super();
|
||||||
|
@ -70,11 +70,11 @@ public class ParserFactory {
|
||||||
this.keywords = Keywords.instance(context);
|
this.keywords = Keywords.instance(context);
|
||||||
this.source = Source.instance(context);
|
this.source = Source.instance(context);
|
||||||
this.options = Options.instance(context);
|
this.options = Options.instance(context);
|
||||||
this.scannerFactory = Scanner.Factory.instance(context);
|
this.scannerFactory = ScannerFactory.instance(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
|
public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
|
||||||
Lexer lexer = scannerFactory.newScanner(input);
|
Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
|
||||||
if (keepEndPos) {
|
if (keepEndPos) {
|
||||||
return new EndPosParser(this, lexer, keepDocComments, keepLineMap);
|
return new EndPosParser(this, lexer, keepDocComments, keepLineMap);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -47,48 +47,6 @@ public class Scanner implements Lexer {
|
||||||
|
|
||||||
private static boolean scannerDebug = false;
|
private static boolean scannerDebug = false;
|
||||||
|
|
||||||
/** A factory for creating scanners. */
|
|
||||||
public static class Factory {
|
|
||||||
/** The context key for the scanner factory. */
|
|
||||||
public static final Context.Key<Scanner.Factory> scannerFactoryKey =
|
|
||||||
new Context.Key<Scanner.Factory>();
|
|
||||||
|
|
||||||
/** Get the Factory instance for this context. */
|
|
||||||
public static Factory instance(Context context) {
|
|
||||||
Factory instance = context.get(scannerFactoryKey);
|
|
||||||
if (instance == null)
|
|
||||||
instance = new Factory(context);
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Log log;
|
|
||||||
final Names names;
|
|
||||||
final Source source;
|
|
||||||
final Keywords keywords;
|
|
||||||
|
|
||||||
/** Create a new scanner factory. */
|
|
||||||
protected Factory(Context context) {
|
|
||||||
context.put(scannerFactoryKey, this);
|
|
||||||
this.log = Log.instance(context);
|
|
||||||
this.names = Names.instance(context);
|
|
||||||
this.source = Source.instance(context);
|
|
||||||
this.keywords = Keywords.instance(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scanner newScanner(CharSequence input) {
|
|
||||||
if (input instanceof CharBuffer) {
|
|
||||||
return new Scanner(this, (CharBuffer)input);
|
|
||||||
} else {
|
|
||||||
char[] array = input.toString().toCharArray();
|
|
||||||
return newScanner(array, array.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scanner newScanner(char[] input, int inputLength) {
|
|
||||||
return new Scanner(this, input, inputLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output variables; set by nextToken():
|
/* Output variables; set by nextToken():
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -177,7 +135,7 @@ public class Scanner implements Lexer {
|
||||||
private final Keywords keywords;
|
private final Keywords keywords;
|
||||||
|
|
||||||
/** Common code for constructors. */
|
/** Common code for constructors. */
|
||||||
private Scanner(Factory fac) {
|
private Scanner(ScannerFactory fac) {
|
||||||
log = fac.log;
|
log = fac.log;
|
||||||
names = fac.names;
|
names = fac.names;
|
||||||
keywords = fac.keywords;
|
keywords = fac.keywords;
|
||||||
|
@ -201,7 +159,7 @@ public class Scanner implements Lexer {
|
||||||
/** Create a scanner from the input buffer. buffer must implement
|
/** Create a scanner from the input buffer. buffer must implement
|
||||||
* array() and compact(), and remaining() must be less than limit().
|
* array() and compact(), and remaining() must be less than limit().
|
||||||
*/
|
*/
|
||||||
protected Scanner(Factory fac, CharBuffer buffer) {
|
protected Scanner(ScannerFactory fac, CharBuffer buffer) {
|
||||||
this(fac, JavacFileManager.toArray(buffer), buffer.limit());
|
this(fac, JavacFileManager.toArray(buffer), buffer.limit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +174,7 @@ public class Scanner implements Lexer {
|
||||||
* @param inputLength the size of the input.
|
* @param inputLength the size of the input.
|
||||||
* Must be positive and less than or equal to input.length.
|
* Must be positive and less than or equal to input.length.
|
||||||
*/
|
*/
|
||||||
protected Scanner(Factory fac, char[] input, int inputLength) {
|
protected Scanner(ScannerFactory fac, char[] input, int inputLength) {
|
||||||
this(fac);
|
this(fac);
|
||||||
eofPos = inputLength;
|
eofPos = inputLength;
|
||||||
if (inputLength == input.length) {
|
if (inputLength == input.length) {
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999, 2010, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sun.tools.javac.parser;
|
||||||
|
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
|
||||||
|
import com.sun.tools.javac.code.Source;
|
||||||
|
import com.sun.tools.javac.util.Context;
|
||||||
|
import com.sun.tools.javac.util.Log;
|
||||||
|
import com.sun.tools.javac.util.Names;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for creating scanners.
|
||||||
|
*
|
||||||
|
* <p><b>This is NOT part of any supported API.
|
||||||
|
* If you write code that depends on this, you do so at your own
|
||||||
|
* risk. This code and its internal interfaces are subject to change
|
||||||
|
* or deletion without notice.</b>
|
||||||
|
*/
|
||||||
|
public class ScannerFactory {
|
||||||
|
/** The context key for the scanner factory. */
|
||||||
|
public static final Context.Key<ScannerFactory> scannerFactoryKey =
|
||||||
|
new Context.Key<ScannerFactory>();
|
||||||
|
|
||||||
|
/** Get the Factory instance for this context. */
|
||||||
|
public static ScannerFactory instance(Context context) {
|
||||||
|
ScannerFactory instance = context.get(scannerFactoryKey);
|
||||||
|
if (instance == null)
|
||||||
|
instance = new ScannerFactory(context);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Log log;
|
||||||
|
final Names names;
|
||||||
|
final Source source;
|
||||||
|
final Keywords keywords;
|
||||||
|
|
||||||
|
/** Create a new scanner factory. */
|
||||||
|
protected ScannerFactory(Context context) {
|
||||||
|
context.put(scannerFactoryKey, this);
|
||||||
|
this.log = Log.instance(context);
|
||||||
|
this.names = Names.instance(context);
|
||||||
|
this.source = Source.instance(context);
|
||||||
|
this.keywords = Keywords.instance(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scanner newScanner(CharSequence input, boolean keepDocComments) {
|
||||||
|
if (input instanceof CharBuffer) {
|
||||||
|
CharBuffer buf = (CharBuffer) input;
|
||||||
|
if (keepDocComments)
|
||||||
|
return new DocCommentScanner(this, buf);
|
||||||
|
else
|
||||||
|
return new Scanner(this, buf);
|
||||||
|
} else {
|
||||||
|
char[] array = input.toString().toCharArray();
|
||||||
|
return newScanner(array, array.length, keepDocComments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
|
||||||
|
if (keepDocComments)
|
||||||
|
return new DocCommentScanner(this, input, inputLength);
|
||||||
|
else
|
||||||
|
return new Scanner(this, input, inputLength);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -107,9 +107,6 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
||||||
// force the use of Messager as a Log
|
// force the use of Messager as a Log
|
||||||
messager = Messager.instance0(context);
|
messager = Messager.instance0(context);
|
||||||
|
|
||||||
// force the use of the scanner that captures Javadoc comments
|
|
||||||
DocCommentScanner.Factory.preRegister(context);
|
|
||||||
|
|
||||||
return new JavadocTool(context);
|
return new JavadocTool(context);
|
||||||
} catch (CompletionFailure ex) {
|
} catch (CompletionFailure ex) {
|
||||||
messager.error(Position.NOPOS, ex.getMessage());
|
messager.error(Position.NOPOS, ex.getMessage());
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a test that uses ISO 8859 encoding.
|
||||||
|
*/
|
||||||
class T6302184 {
|
class T6302184 {
|
||||||
|
|
||||||
T6302184() {
|
T6302184() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -35,7 +35,6 @@ import javax.tools.SimpleJavaFileObject;
|
||||||
import com.sun.tools.javac.file.JavacFileManager;
|
import com.sun.tools.javac.file.JavacFileManager;
|
||||||
import com.sun.tools.javac.parser.Parser;
|
import com.sun.tools.javac.parser.Parser;
|
||||||
import com.sun.tools.javac.parser.ParserFactory;
|
import com.sun.tools.javac.parser.ParserFactory;
|
||||||
import com.sun.tools.javac.parser.Scanner;
|
|
||||||
import com.sun.tools.javac.tree.JCTree;
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
import com.sun.tools.javac.tree.TreeScanner;
|
import com.sun.tools.javac.tree.TreeScanner;
|
||||||
import com.sun.tools.javac.util.Context;
|
import com.sun.tools.javac.util.Context;
|
||||||
|
@ -60,7 +59,6 @@ public class TestLog
|
||||||
log.multipleErrors = true;
|
log.multipleErrors = true;
|
||||||
|
|
||||||
JavacFileManager.preRegister(context);
|
JavacFileManager.preRegister(context);
|
||||||
Scanner.Factory sfac = Scanner.Factory.instance(context);
|
|
||||||
ParserFactory pfac = ParserFactory.instance(context);
|
ParserFactory pfac = ParserFactory.instance(context);
|
||||||
|
|
||||||
final String text =
|
final String text =
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,8 +31,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.tools.javac.api.JavacTaskImpl;
|
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||||
import com.sun.tools.javac.parser.*; // XXX
|
import com.sun.tools.javac.parser.*;
|
||||||
import com.sun.tools.javac.util.*; // XXX
|
import com.sun.tools.javac.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
|
@ -65,7 +65,7 @@ public class TestJavacTaskScanner extends ToolTester {
|
||||||
fm.getJavaFileObjects(new File[] {file});
|
fm.getJavaFileObjects(new File[] {file});
|
||||||
StandardJavaFileManager fm = getLocalFileManager(tool, null, null);
|
StandardJavaFileManager fm = getLocalFileManager(tool, null, null);
|
||||||
task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits);
|
task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits);
|
||||||
task.getContext().put(Scanner.Factory.scannerFactoryKey,
|
task.getContext().put(ScannerFactory.scannerFactoryKey,
|
||||||
new MyScanner.Factory(task.getContext(), this));
|
new MyScanner.Factory(task.getContext(), this));
|
||||||
elements = task.getElements();
|
elements = task.getElements();
|
||||||
types = task.getTypes();
|
types = task.getTypes();
|
||||||
|
@ -170,34 +170,36 @@ public class TestJavacTaskScanner extends ToolTester {
|
||||||
|
|
||||||
class MyScanner extends Scanner {
|
class MyScanner extends Scanner {
|
||||||
|
|
||||||
public static class Factory extends Scanner.Factory {
|
public static class Factory extends ScannerFactory {
|
||||||
public Factory(Context context, TestJavacTaskScanner test) {
|
public Factory(Context context, TestJavacTaskScanner test) {
|
||||||
super(context);
|
super(context);
|
||||||
this.test = test;
|
this.test = test;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Scanner newScanner(CharSequence input) {
|
public Scanner newScanner(CharSequence input, boolean keepDocComments) {
|
||||||
|
assert !keepDocComments;
|
||||||
if (input instanceof CharBuffer) {
|
if (input instanceof CharBuffer) {
|
||||||
return new MyScanner(this, (CharBuffer)input, test);
|
return new MyScanner(this, (CharBuffer)input, test);
|
||||||
} else {
|
} else {
|
||||||
char[] array = input.toString().toCharArray();
|
char[] array = input.toString().toCharArray();
|
||||||
return newScanner(array, array.length);
|
return newScanner(array, array.length, keepDocComments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Scanner newScanner(char[] input, int inputLength) {
|
public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
|
||||||
|
assert !keepDocComments;
|
||||||
return new MyScanner(this, input, inputLength, test);
|
return new MyScanner(this, input, inputLength, test);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestJavacTaskScanner test;
|
private TestJavacTaskScanner test;
|
||||||
}
|
}
|
||||||
protected MyScanner(Factory fac, CharBuffer buffer, TestJavacTaskScanner test) {
|
protected MyScanner(ScannerFactory fac, CharBuffer buffer, TestJavacTaskScanner test) {
|
||||||
super(fac, buffer);
|
super(fac, buffer);
|
||||||
this.test = test;
|
this.test = test;
|
||||||
}
|
}
|
||||||
protected MyScanner(Factory fac, char[] input, int inputLength, TestJavacTaskScanner test) {
|
protected MyScanner(ScannerFactory fac, char[] input, int inputLength, TestJavacTaskScanner test) {
|
||||||
super(fac, input, inputLength);
|
super(fac, input, inputLength);
|
||||||
this.test = test;
|
this.test = test;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6877202
|
||||||
|
* @summary Elements.getDocComment() is not getting JavaDocComments
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.source.tree.*;
|
||||||
|
import com.sun.source.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.*;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.lang.model.util.*;
|
||||||
|
import javax.tools.*;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For a mixture of pre-existing and generated source files, ensure that we can
|
||||||
|
* get the doc comments.
|
||||||
|
* The test uses both a standard ElementScanner to find all the elements being
|
||||||
|
* processed, and a TreeScanner to find all the local and anonymous inner classes
|
||||||
|
* as well.
|
||||||
|
* And, because the relevant code paths in the compiler are different for
|
||||||
|
* command line and JSR 199 invocation, the test covers both ways of invoking the
|
||||||
|
* compiler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@SupportedOptions("scan")
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
public class TestDocComments extends AbstractProcessor {
|
||||||
|
enum CompileKind { API, CMD };
|
||||||
|
enum ScanKind { TREE, ELEMENT };
|
||||||
|
|
||||||
|
// ----- Main test driver: invoke compiler for the various test cases ------
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
for (CompileKind ck: CompileKind.values()) {
|
||||||
|
for (ScanKind sk: ScanKind.values()) {
|
||||||
|
try {
|
||||||
|
test(ck, sk);
|
||||||
|
} catch (IOException e) {
|
||||||
|
error(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors > 0)
|
||||||
|
throw new Exception(errors + " errors occurred");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test(CompileKind ck, ScanKind sk) throws IOException {
|
||||||
|
String testClasses = System.getProperty("test.classes");
|
||||||
|
String testSrc = System.getProperty("test.src");
|
||||||
|
File testDir = new File("test." + ck + "." + sk);
|
||||||
|
testDir.mkdirs();
|
||||||
|
String[] opts = {
|
||||||
|
"-d", testDir.getPath(),
|
||||||
|
"-implicit:none",
|
||||||
|
"-processor", TestDocComments.class.getName(),
|
||||||
|
"-processorpath", testClasses,
|
||||||
|
//"-XprintRounds",
|
||||||
|
"-Ascan=" + sk
|
||||||
|
};
|
||||||
|
File[] files = {
|
||||||
|
new File(testSrc, "a/First.java")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ck == CompileKind.API)
|
||||||
|
test_javac_api(opts, files);
|
||||||
|
else
|
||||||
|
test_javac_cmd(opts, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_javac_api(String[] opts, File[] files) throws IOException {
|
||||||
|
System.err.println("test javac api: " + Arrays.asList(opts) + " " + Arrays.asList(files));
|
||||||
|
DiagnosticListener<JavaFileObject> dl = new DiagnosticListener<JavaFileObject>() {
|
||||||
|
public void report(Diagnostic diagnostic) {
|
||||||
|
error(diagnostic.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
|
||||||
|
StandardJavaFileManager fm = c.getStandardFileManager(null, null, null);
|
||||||
|
Iterable<? extends JavaFileObject> units = fm.getJavaFileObjects(files);
|
||||||
|
JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units);
|
||||||
|
t.parse();
|
||||||
|
t.analyze();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_javac_cmd(String[] opts, File[] files) {
|
||||||
|
System.err.println("test javac cmd: " + Arrays.asList(opts) + " " + Arrays.asList(files));
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
List<String> args = new ArrayList<String>(Arrays.asList(opts));
|
||||||
|
for (File f: files)
|
||||||
|
args.add(f.getPath());
|
||||||
|
int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
|
||||||
|
pw.close();
|
||||||
|
String out = sw.toString();
|
||||||
|
if (out.length() > 0)
|
||||||
|
System.err.println(out);
|
||||||
|
if (rc > 0)
|
||||||
|
error("Compilation failed: rc=" + rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error(String msg) {
|
||||||
|
System.err.println(msg);
|
||||||
|
errors++;
|
||||||
|
//throw new Error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int errors;
|
||||||
|
|
||||||
|
// ----- Annotation processor: scan for elements and check doc comments ----
|
||||||
|
|
||||||
|
Map<String,String> options;
|
||||||
|
Filer filer;
|
||||||
|
Messager messager;
|
||||||
|
Elements elements;
|
||||||
|
ScanKind skind;
|
||||||
|
|
||||||
|
int round = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(ProcessingEnvironment pEnv) {
|
||||||
|
super.init(pEnv);
|
||||||
|
options = pEnv.getOptions();
|
||||||
|
filer = pEnv.getFiler();
|
||||||
|
messager = pEnv.getMessager();
|
||||||
|
elements = pEnv.getElementUtils();
|
||||||
|
skind = ScanKind.valueOf(options.get("scan"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
|
round++;
|
||||||
|
|
||||||
|
// Scan elements using an appropriate scanner, and for each element found,
|
||||||
|
// call check(Element e) to verify the doc comment on that element
|
||||||
|
for (Element e: roundEnv.getRootElements()) {
|
||||||
|
System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName());
|
||||||
|
if (skind == ScanKind.TREE) {
|
||||||
|
Trees trees = Trees.instance(processingEnv); // cannot cache this across rounds
|
||||||
|
new TestTreeScanner().scan(trees.getPath(e), trees);
|
||||||
|
} else
|
||||||
|
new TestElementScanner().scan(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For a few rounds, generate new source files, so that we can check whether
|
||||||
|
// doc comments are correctly handled in subsequent processing rounds
|
||||||
|
final int MAX_ROUNDS = 3;
|
||||||
|
if (round <= MAX_ROUNDS) {
|
||||||
|
String pkg = "p";
|
||||||
|
String currClass = "Gen" + round;
|
||||||
|
String curr = pkg + "." + currClass;
|
||||||
|
String next = (round < MAX_ROUNDS) ? (pkg + ".Gen" + (round + 1)) : "z.Last";
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
text.append("package ").append(pkg).append(";\n");
|
||||||
|
text.append("/** CLASS ").append(currClass).append(" */\n");
|
||||||
|
text.append("public class ").append(currClass).append(" {\n");
|
||||||
|
text.append(" /** CONSTRUCTOR <init> **/\n");
|
||||||
|
text.append(" ").append(currClass).append("() { }\n");
|
||||||
|
text.append(" /** FIELD x */\n");
|
||||||
|
text.append(" ").append(next).append(" x;\n");
|
||||||
|
text.append(" /** METHOD m */\n");
|
||||||
|
text.append(" void m() { }\n");
|
||||||
|
text.append("}\n");
|
||||||
|
|
||||||
|
try {
|
||||||
|
JavaFileObject fo = filer.createSourceFile(curr);
|
||||||
|
Writer out = fo.openWriter();
|
||||||
|
try {
|
||||||
|
out.write(text.toString());
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the doc comment on an element is as expected.
|
||||||
|
* This method is invoked for each element found by the scanners run by process.
|
||||||
|
*/
|
||||||
|
void check(Element e) {
|
||||||
|
System.err.println("Checking " + e);
|
||||||
|
|
||||||
|
String dc = elements.getDocComment(e);
|
||||||
|
System.err.println(" found " + dc);
|
||||||
|
|
||||||
|
String expect = (e.getKind() + " " + e.getSimpleName()); // default
|
||||||
|
|
||||||
|
Name name = e.getSimpleName();
|
||||||
|
Element encl = e.getEnclosingElement();
|
||||||
|
Name enclName = encl.getSimpleName();
|
||||||
|
ElementKind enclKind = encl.getKind();
|
||||||
|
switch (e.getKind()) {
|
||||||
|
case PARAMETER:
|
||||||
|
case LOCAL_VARIABLE:
|
||||||
|
// doc comments not retained for these elements
|
||||||
|
expect = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONSTRUCTOR:
|
||||||
|
if (enclName.length() == 0 || enclKind == ElementKind.ENUM) {
|
||||||
|
// Enum constructor is synthetic
|
||||||
|
expect = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case METHOD:
|
||||||
|
if (enclKind == ElementKind.ENUM
|
||||||
|
&& (name.contentEquals("values") || name.contentEquals("valueOf"))) {
|
||||||
|
// synthetic enum methods
|
||||||
|
expect = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLASS:
|
||||||
|
if (e.getSimpleName().length() == 0) {
|
||||||
|
// anon inner class
|
||||||
|
expect = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(" expect " + expect);
|
||||||
|
|
||||||
|
if (dc == null ? expect == null : dc.trim().equals(expect))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dc == null)
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "doc comment is null", e);
|
||||||
|
else {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR,
|
||||||
|
"unexpected comment: \"" + dc + "\", expected \"" + expect + "\"", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- Scanners to find elements -----------------------------------------
|
||||||
|
|
||||||
|
class TestElementScanner extends ElementScanner7<Void, Void> {
|
||||||
|
@Override
|
||||||
|
public Void visitExecutable(ExecutableElement e, Void _) {
|
||||||
|
check(e);
|
||||||
|
return super.visitExecutable(e, _);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Void visitType(TypeElement e, Void _) {
|
||||||
|
check(e);
|
||||||
|
return super.visitType(e, _);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Void visitVariable(VariableElement e, Void _) {
|
||||||
|
check(e);
|
||||||
|
return super.visitVariable(e, _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestTreeScanner extends TreePathScanner<Void,Trees> {
|
||||||
|
@Override
|
||||||
|
public Void visitClass(ClassTree tree, Trees trees) {
|
||||||
|
check(trees.getElement(getCurrentPath()));
|
||||||
|
return super.visitClass(tree, trees);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Void visitMethod(MethodTree tree, Trees trees) {
|
||||||
|
check(trees.getElement(getCurrentPath()));
|
||||||
|
return super.visitMethod(tree, trees);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Void visitVariable(VariableTree tree, Trees trees) {
|
||||||
|
check(trees.getElement(getCurrentPath()));
|
||||||
|
return super.visitVariable(tree, trees);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package a;
|
||||||
|
|
||||||
|
/** CLASS First */
|
||||||
|
public class First {
|
||||||
|
/** CONSTRUCTOR <init> */
|
||||||
|
First() { }
|
||||||
|
|
||||||
|
/** FIELD x */
|
||||||
|
p.Gen1 x;
|
||||||
|
|
||||||
|
/** METHOD m **/
|
||||||
|
void m(int i) {
|
||||||
|
/** CLASS Local */
|
||||||
|
class Local {
|
||||||
|
/** CONSTRUCTOR <init> */
|
||||||
|
Local() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
/** METHOD run **/
|
||||||
|
public void run() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ENUM E */
|
||||||
|
enum E {
|
||||||
|
/** ENUM_CONSTANT e1 */
|
||||||
|
e1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package z;
|
||||||
|
|
||||||
|
// This class should be read last, implicitly. Therefore it should not
|
||||||
|
// be subject to anno processing. If it is, the lack of doc comments should
|
||||||
|
// be detected and will flag an error.
|
||||||
|
public class Last {
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6861094
|
||||||
|
* @summary javac -Xprint <file> does not print comments
|
||||||
|
* @compile/ref=XprintDocComments.out -Xprint XprintDocComments.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLASS XprintDocComments
|
||||||
|
*/
|
||||||
|
class XPrintDocComments {
|
||||||
|
/**
|
||||||
|
* FIELD i;
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CLASS XprintDocComments
|
||||||
|
*/
|
||||||
|
class XPrintDocComments {
|
||||||
|
|
||||||
|
XPrintDocComments();
|
||||||
|
/**
|
||||||
|
* FIELD i;
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
}
|
204
langtools/test/tools/javac/tree/TreePosRoundsTest.java
Normal file
204
langtools/test/tools/javac/tree/TreePosRoundsTest.java
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6985205
|
||||||
|
* @summary access to tree positions and doc comments may be lost across annotation processing rounds
|
||||||
|
* @build TreePosRoundsTest
|
||||||
|
* @compile -proc:only -processor TreePosRoundsTest TreePosRoundsTest.java
|
||||||
|
* @run main TreePosRoundsTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.*;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.tools.*;
|
||||||
|
|
||||||
|
import com.sun.source.tree.*;
|
||||||
|
import com.sun.source.util.*;
|
||||||
|
import javax.tools.JavaCompiler.CompilationTask;
|
||||||
|
|
||||||
|
// This test is an annotation processor that performs multiple rounds of
|
||||||
|
// processing, and on each round, it checks that source positions are
|
||||||
|
// available and correct.
|
||||||
|
//
|
||||||
|
// The test can be run directly as a processor from the javac command line
|
||||||
|
// or via JSR 199 by invoking the main program.
|
||||||
|
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
public class TreePosRoundsTest extends AbstractProcessor {
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
String testSrc = System.getProperty("test.src");
|
||||||
|
String testClasses = System.getProperty("test.classes");
|
||||||
|
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
|
||||||
|
StandardJavaFileManager fm = c.getStandardFileManager(null, null, null);
|
||||||
|
String thisName = TreePosRoundsTest.class.getName();
|
||||||
|
File thisFile = new File(testSrc, thisName + ".java");
|
||||||
|
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(thisFile);
|
||||||
|
List<String> options = Arrays.asList(
|
||||||
|
"-proc:only",
|
||||||
|
"-processor", thisName,
|
||||||
|
"-processorpath", testClasses);
|
||||||
|
CompilationTask t = c.getTask(null, fm, null, options, null, files);
|
||||||
|
boolean ok = t.call();
|
||||||
|
if (!ok)
|
||||||
|
throw new Exception("processing failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Filer filer;
|
||||||
|
Messager messager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(ProcessingEnvironment pEnv) {
|
||||||
|
super.init(pEnv);
|
||||||
|
filer = pEnv.getFiler();
|
||||||
|
messager = pEnv.getMessager();
|
||||||
|
}
|
||||||
|
|
||||||
|
int round = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
|
round++;
|
||||||
|
|
||||||
|
// Scan trees for elements, verifying source tree positions
|
||||||
|
for (Element e: roundEnv.getRootElements()) {
|
||||||
|
try {
|
||||||
|
Trees trees = Trees.instance(processingEnv); // cannot cache this across rounds
|
||||||
|
TreePath p = trees.getPath(e);
|
||||||
|
new TestTreeScanner(p.getCompilationUnit(), trees).scan(trees.getPath(e), null);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR,
|
||||||
|
"Cannot get source: " + ex, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int MAXROUNDS = 3;
|
||||||
|
if (round < MAXROUNDS)
|
||||||
|
generateSource("Gen" + round);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateSource(String name) {
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
text.append("class ").append(name).append("{\n");
|
||||||
|
text.append(" int one = 1;\n");
|
||||||
|
text.append(" int two = 2;\n");
|
||||||
|
text.append(" int three = one + two;\n");
|
||||||
|
text.append("}\n");
|
||||||
|
|
||||||
|
try {
|
||||||
|
JavaFileObject fo = filer.createSourceFile(name);
|
||||||
|
Writer out = fo.openWriter();
|
||||||
|
try {
|
||||||
|
out.write(text.toString());
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestTreeScanner extends TreePathScanner<Void,Void> {
|
||||||
|
TestTreeScanner(CompilationUnitTree unit, Trees trees) throws IOException {
|
||||||
|
this.unit = unit;
|
||||||
|
JavaFileObject sf = unit.getSourceFile();
|
||||||
|
source = sf.getCharContent(true).toString();
|
||||||
|
sourcePositions = trees.getSourcePositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitVariable(VariableTree tree, Void _) {
|
||||||
|
check(getCurrentPath());
|
||||||
|
return super.visitVariable(tree, _);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check(TreePath tp) {
|
||||||
|
Tree tree = tp.getLeaf();
|
||||||
|
|
||||||
|
String expect = tree.toString();
|
||||||
|
if (tree.getKind() == Tree.Kind.VARIABLE) {
|
||||||
|
// tree.toString() does not know enough context to add ";",
|
||||||
|
// so deal with that manually...
|
||||||
|
Tree.Kind enclKind = tp.getParentPath().getLeaf().getKind();
|
||||||
|
//System.err.println(" encl: " +enclKind);
|
||||||
|
if (enclKind == Tree.Kind.CLASS || enclKind == Tree.Kind.BLOCK)
|
||||||
|
expect += ";";
|
||||||
|
}
|
||||||
|
//System.err.println("expect: " + expect);
|
||||||
|
|
||||||
|
int start = (int)sourcePositions.getStartPosition(unit, tree);
|
||||||
|
if (start == Diagnostic.NOPOS) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "start pos not set for " + trim(tree));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int end = (int)sourcePositions.getEndPosition(unit, tree);
|
||||||
|
if (end == Diagnostic.NOPOS) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "end pos not set for " + trim(tree));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String found = source.substring(start, end);
|
||||||
|
//System.err.println(" found: " + found);
|
||||||
|
|
||||||
|
// allow for long lines, in which case just compare beginning and
|
||||||
|
// end of the strings
|
||||||
|
boolean equal;
|
||||||
|
if (found.contains("\n")) {
|
||||||
|
String head = found.substring(0, found.indexOf("\n"));
|
||||||
|
String tail = found.substring(found.lastIndexOf("\n")).trim();
|
||||||
|
equal = expect.startsWith(head) && expect.endsWith(tail);
|
||||||
|
} else {
|
||||||
|
equal = expect.equals(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!equal) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR,
|
||||||
|
"unexpected value found: '" + found + "'; expected: '" + expect + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String trim(Tree tree) {
|
||||||
|
final int MAXLEN = 32;
|
||||||
|
String s = tree.toString().replaceAll("\\s+", " ").trim();
|
||||||
|
return (s.length() < MAXLEN) ? s : s.substring(0, MAXLEN);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilationUnitTree unit;
|
||||||
|
SourcePositions sourcePositions;
|
||||||
|
String source;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue