test/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

     1 /*
     2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 /**@test
    25  * @bug 8035890
    26  * @summary Verify that the parser correctly checks for source level 8 on the new places where
    27  *          annotations can appear in 8.
    28  * @run main CheckErrorsForSource7 CheckErrorsForSource7.java
    29  */
    30 import java.io.File;
    31 import java.io.IOException;
    32 import java.lang.annotation.ElementType;
    33 import java.lang.annotation.Target;
    34 import java.net.URI;
    35 import java.net.URISyntaxException;
    36 import java.util.ArrayList;
    37 import java.util.Arrays;
    38 import java.util.Collections;
    39 import java.util.Comparator;
    40 import java.util.HashSet;
    41 import java.util.List;
    42 import java.util.Set;
    43 import javax.tools.Diagnostic;
    44 import javax.tools.DiagnosticCollector;
    45 import javax.tools.JavaFileObject;
    46 import javax.tools.SimpleJavaFileObject;
    47 import com.sun.source.tree.AnnotationTree;
    48 import com.sun.source.tree.CompilationUnitTree;
    49 import com.sun.source.tree.IdentifierTree;
    50 import com.sun.source.tree.Tree.Kind;
    51 import com.sun.source.util.JavacTask;
    52 import com.sun.source.util.TreePathScanner;
    53 import com.sun.source.util.Trees;
    54 import com.sun.tools.javac.api.JavacTool;
    55 import com.sun.tools.javac.file.JavacFileManager;
    57 /**For each place where an annotation can syntactically appear with -source 8, but not with
    58  * -source 7, this test verifies that an error is correctly emitted from the parser for
    59  * the annotation for -source 7. This test first gathers the occurrences of @TA from
    60  * the CheckErrorsForSource7Data class below, and then repeatedly removes all these annotations
    61  * except one and checks the parser reports an expected error. This is needed as as the parser
    62  * typically produces only one 'insufficient source level' error for each new feature used.
    63  */
    64 public class CheckErrorsForSource7 {
    65     public static void main(String... args) throws IOException, URISyntaxException {
    66         new CheckErrorsForSource7().run(args);
    67     }
    69     private void run(String... args) throws IOException, URISyntaxException {
    70         //the first and only parameter must be the name of the file to be analyzed:
    71         if (args.length != 1) throw new IllegalStateException("Must provide source file!");
    72         File testSrc = new File(System.getProperty("test.src"));
    73         File testFile = new File(testSrc, args[0]);
    74         if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source");
    75         JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
    77         //gather spans of the @TA annotations into typeAnnotationSpans:
    78         JavacTask task = JavacTool.create().getTask(null,
    79                                                     fm,
    80                                                     null,
    81                                                     Collections.<String>emptyList(),
    82                                                     null,
    83                                                     fm.getJavaFileObjects(testFile));
    84         final Trees trees = Trees.instance(task);
    85         final CompilationUnitTree cut = task.parse().iterator().next();
    86         final List<int[]> typeAnnotationSpans = new ArrayList<>();
    88         new TreePathScanner<Void, Void>() {
    89             @Override
    90             public Void visitAnnotation(AnnotationTree node, Void p) {
    91                 if (node.getAnnotationType().getKind() == Kind.IDENTIFIER &&
    92                     ((IdentifierTree) node.getAnnotationType()).getName().contentEquals("TA")) {
    93                     int start = (int) trees.getSourcePositions().getStartPosition(cut, node);
    94                     int end = (int) trees.getSourcePositions().getEndPosition(cut, node);
    95                     typeAnnotationSpans.add(new int[] {start, end});
    96                 }
    97                 return null;
    98             }
    99         }.scan(cut, null);
   101         //sort the spans in the reverse order, to simplify removing them from the source:
   102         Collections.sort(typeAnnotationSpans, new Comparator<int[]>() {
   103             @Override
   104             public int compare(int[] o1, int[] o2) {
   105                 return o2[0] - o1[0];
   106             }
   107         });
   109         //verify the errors are produce correctly:
   110         String originalSource = cut.getSourceFile().getCharContent(false).toString();
   112         for (int[] toKeep : typeAnnotationSpans) {
   113             //prepare updated source code by removing all the annotations except the toKeep one:
   114             String updated = originalSource;
   116             for (int[] span : typeAnnotationSpans) {
   117                 if (span == toKeep) continue;
   119                 updated = updated.substring(0, span[0]) + updated.substring(span[1]);
   120             }
   122             //parse and verify:
   123             JavaFileObject updatedFile = new TestFO(cut.getSourceFile().toUri(), updated);
   124             DiagnosticCollector<JavaFileObject> errors = new DiagnosticCollector<>();
   125             JavacTask task2 = JavacTool.create().getTask(null,
   126                                                          fm,
   127                                                          errors,
   128                                                          Arrays.asList("-source", "7"),
   129                                                          null,
   130                                                          Arrays.asList(updatedFile));
   131             task2.parse();
   133             boolean found = false;
   135             for (Diagnostic<? extends JavaFileObject> d : errors.getDiagnostics()) {
   136                 if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERRORS.contains(d.getCode())) {
   137                     if (found) {
   138                         throw new IllegalStateException("More than one expected error found.");
   139                     }
   140                     found = true;
   141                 }
   142             }
   144             if (!found)
   145                 throw new IllegalStateException("Did not produce proper errors for: " + updated);
   146         }
   147     }
   149     static final Set<String> EXPECTED_ERRORS = new HashSet<>(Arrays.asList(
   150         "compiler.err.type.annotations.not.supported.in.source",
   151         "compiler.err.annotations.after.type.params.not.supported.in.source"
   152     ));
   154     class TestFO extends SimpleJavaFileObject {
   155         private final String content;
   156         public TestFO(URI uri, String content) {
   157             super(uri, Kind.SOURCE);
   158             this.content = content;
   159         }
   161         @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
   162             return content;
   163         }
   165         @Override public boolean isNameCompatible(String simpleName, Kind kind) {
   166             return true;
   167         }
   168     }
   169 }
   171 //data on which the source level check is verified:
   172 class CheckErrorsForSource7Data {
   173     @Target(ElementType.TYPE_USE)
   174     @interface TA { }
   176     Object n1 = new @TA ArrayList<@TA String>();
   177     Object n2 = new @TA Object() {};
   178     Object [] @TA [] arr @TA[];
   179     <T> @TA int @TA[] ret(Object obj) @TA[] throws @TA Exception {
   180         this.<@TA String>ret(null);
   181         Object c1 = new @TA String[1];
   183         int val = obj instanceof @TA String ? ((@TA String) obj).length() : 0;
   184         List<@TA ?> l;
   185         return null;
   186     }
   187     void vararg(String @TA ... args) { }
   189     abstract class C<@TA T extends @TA Number & @TA Runnable>
   190                extends @TA ArrayList<@TA String>
   191                implements java.util. @TA Comparator<@TA T> { }
   193     interface I extends java.util. @TA Comparator<@TA String> { }
   195 }

mercurial