/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* Utility and test program to check validity of tree positions for tree nodes.
* The program can be run standalone, or as a jtreg test. In standalone mode,
* errors can be displayed in a gui viewer. For info on command line args,
* run program with no args.
*
* <p>
* jtreg: Note that by using the -r switch in the test description below, this test
* covering any new language features that may be tested in this test suite.
*/
/*
* @test
* @bug 6919889
* @summary assorted position errors in compiler syntax trees
* @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE .
*/
public class TreePosTest {
/**
* Main entry point.
* If test.src is set, program runs in jtreg mode, and will throw an Error
* if any errors arise, otherwise System.exit will be used, unless the gui
* viewer is being used. In jtreg mode, the default base directory for file
* args is the value of ${test.src}. In jtreg mode, the -r option can be
* given to change the default base directory to the root test directory.
*/
if (!ok) {
throw new Error("failed");
else
}
}
/**
* Run the program. A base directory can be provided for file arguments.
* In jtreg mode, the -r option can be given to change the default base
* directory to the test root directory. For other options, see usage().
* @param baseDir base directory for any file arguments.
* @param args command line args
* @return true if successful or in gui mode
*/
return true;
}
gui = true;
quiet = true;
verbose = true;
throw new Error("-r must be used before -ef");
d = d.getParentFile();
if (d == null)
throw new Error("cannot find TEST.ROOT");
}
baseDir = d;
}
else {
}
}
else
}
if (fileCount != 1)
if (errors > 0)
}
/**
* Print command line help.
* @param out output stream
*/
}
/**
* Test a file. If the file is a directory, it will be recursively scanned
* for java files.
* @param file the file or directory to test
*/
if (!quiet)
return;
}
if (file.isDirectory()) {
test(f);
}
return;
}
try {
if (verbose)
fileCount++;
} catch (ParseException e) {
if (!quiet) {
}
} catch (IOException e) {
}
return;
}
if (!quiet)
}
// See CR: 6982992 Tests CheckAttributedTree.java, JavacTreeScannerTest.java, and SourceTreeeScannerTest.java timeout
/**
* Read a file.
* @param file the file to be read
* @return the tree for the content of the file
* @throws IOException if any IO errors occur
* @throws TreePosTest.ParseException if any errors occur while parsing the file
*/
r.errors = 0;
if (r.errors > 0)
throw new Error("no trees found");
throw new Error("too many trees found");
return t;
}
/**
* Report an error. When the program is complete, the program will either
* exit or throw an Error if any errors have been reported.
* @param msg the error message
*/
errors++;
}
/** Number of files that have been analyzed. */
int fileCount;
/** Number of errors reported. */
int errors;
/** Flag: don't report irrelevant files. */
boolean quiet;
/** Flag: report files as they are processed. */
boolean verbose;
/** Flag: show errors in GUI viewer. */
boolean gui;
/** Option: encoding for test files. */
/** The GUI viewer for errors. */
/** The set of tags for tree nodes to be analyzed; if empty, all tree nodes
* are analyzed. */
/** Set of files and directories to be excluded from analysis. */
/** Set of tag names to be excluded from analysis. */
/** Table of printable names for tree tag values. */
/**
* Main class for testing assertions concerning tree positions for tree nodes.
*/
}
return;
// Modifiers nodes are present throughout the tree even where
// there is no corresponding source text.
// Redundant semicolons in a class definition can cause empty
// initializer blocks with no positions.
// If pos is NOPOS, so should be the start and end positions
} else {
// For this node, start , pos, and endpos should be all defined
// The following should normally be ordered
// encl.start <= start <= pos <= end <= encl.end
// In addition, the position of the enclosing node should be
// within this node.
// The primary exceptions are for array type nodes, because of the
// need to support legacy syntax:
// e.g. int a[]; int[] b[]; int f()[] { return null; }
// and because of inconsistent nesting of left and right of
// array declarations:
// e.g. int[][] a = new int[2][];
check("encl.pos <= start || end <= encl.pos",
}
}
}
}
}
// enum member declarations are desugared in the parser and have
// ill-defined semantics for tree positions, so for now, we
// skip the synthesized bits and just check parts which came from
// the original source text
}
}
}
}
} else
super.visitVarDef(tree);
}
return false;
}
}
if (!ok) {
if (gui) {
}
}
}
}
/**
* Utility class providing easy access to position and other info for a tree node.
*/
private class Info {
Info() {
start = 0;
pos = 0;
}
}
}
final int tag;
final int start;
final int pos;
final int end;
}
/**
* Names for tree tags.
* javac does not provide an API to convert tag values to strings, so this class uses
* reflection to determine names of public static final int values in JCTree.
*/
private static class TagNames {
for (Field f : c.getDeclaredFields()) {
int mods = f.getModifiers();
try {
} catch (IllegalAccessException e) {
}
}
}
}
}
}
}
/**
* Thrown when errors are found parsing a java file.
*/
super(msg);
}
}
/**
* DiagnosticListener to report diagnostics and count any errors that occur.
*/
}
switch (diagnostic.getKind()) {
case ERROR:
errors++;
}
}
int errors;
}
/**
* GUI viewer for issues found by TreePosTester. The viewer provides a drop
* down list for selecting error conditions, a header area providing details
* about an error, and a text area with the ranges of text highlighted as
* appropriate.
*/
/**
* Create a viewer.
*/
Viewer() {
initGUI();
}
/**
* Add another entry to the list of errors.
* @param file The file containing the error
* @param check The condition that was being tested, and which failed
* @param encl the enclosing tree node
* @param self the tree node containing the error
*/
m.addElement(e);
if (m.getSize() == 1)
}
/**
* Initialize the GUI window.
*/
private void initGUI() {
public void actionPerformed(ActionEvent e) {
}
});
public void caretUpdate(CaretEvent e) {
else
}
});
pack();
setVisible(true);
}
/** Show an entry that has been selected. */
try {
// update simple fields
// show file text with highlights
} catch (IOException ex) {
}
}
/** Create a test field. */
f.setEditable(false);
return f;
}
/** Add a highlighted region based on the positions in an Info object. */
return;
if (start == -1)
if (end == -1)
try {
}
} catch (BadLocationException e) {
e.printStackTrace();
}
}
/** Get the minimum valid position in a set of info objects. */
}
}
/** Set the background on a component. */
comp.setBackground(c);
return comp;
}
/** Scroll a text area to display a given position near the middle of the visible area. */
// Using invokeLater appears to give text a chance to sort itself out
// before the scroll happens; otherwise scrollRectToVisible doesn't work.
// Maybe there's a better way to sync with the text...
public void run() {
try {
t.scrollRectToVisible(r);
} catch (BadLocationException ignore) {
}
}
});
}
/** Panel to display an Info object. */
InfoPanel() {
}
}
f.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
}
});
return f;
}
}
/** Object to record information about an error to be displayed. */
private class Entry {
}
}
}
}
}