langtools/test/jdk/jshell/CompletenessStressTest.java
author jlahoda
Thu, 05 May 2016 12:55:21 +0200
changeset 37939 3eb8c2a89b77
parent 33362 65ec6de1d6b4
child 38908 f0c186d76c8a
permissions -rw-r--r--
8153761: JShell: Completion -- Show parameter names if possible Summary: Compiling code with -parameters; keeping parameter names when reading classfiles; searching JDK sources if parameter names are not available. Reviewed-by: rfield
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     1
/*
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     4
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     7
 * published by the Free Software Foundation.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     8
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    13
 * accompanied this code).
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    14
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    18
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    21
 * questions.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    22
 */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    23
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    24
import java.io.File;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    25
import java.io.IOException;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    26
import java.io.StringWriter;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    27
import java.nio.charset.StandardCharsets;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    28
import java.nio.file.Files;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    29
import java.nio.file.Path;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    30
import java.nio.file.Paths;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    31
import java.util.ArrayList;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    32
import java.util.List;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    33
import java.util.Set;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    34
import java.util.stream.Collectors;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    35
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    36
import javax.lang.model.element.Modifier;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    37
import javax.tools.JavaCompiler;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    38
import javax.tools.JavaFileObject;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    39
import javax.tools.StandardJavaFileManager;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    40
import javax.tools.ToolProvider;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    41
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    42
import com.sun.source.tree.BlockTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    43
import com.sun.source.tree.BreakTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    44
import com.sun.source.tree.CaseTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    45
import com.sun.source.tree.ClassTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    46
import com.sun.source.tree.CompilationUnitTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    47
import com.sun.source.tree.ContinueTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    48
import com.sun.source.tree.DoWhileLoopTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    49
import com.sun.source.tree.ExpressionStatementTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    50
import com.sun.source.tree.ForLoopTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    51
import com.sun.source.tree.IfTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    52
import com.sun.source.tree.ImportTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    53
import com.sun.source.tree.LabeledStatementTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    54
import com.sun.source.tree.LineMap;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    55
import com.sun.source.tree.MethodTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    56
import com.sun.source.tree.ReturnTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    57
import com.sun.source.tree.StatementTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    58
import com.sun.source.tree.SwitchTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    59
import com.sun.source.tree.Tree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    60
import com.sun.source.tree.WhileLoopTree;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    61
import com.sun.source.util.SourcePositions;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    62
import com.sun.source.util.Trees;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    63
import com.sun.tools.javac.api.JavacTaskImpl;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    64
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    65
import jdk.jshell.SourceCodeAnalysis;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    66
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    67
import org.testng.annotations.DataProvider;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    68
import org.testng.annotations.Test;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    69
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    70
import static java.lang.Integer.max;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    71
import static java.lang.Integer.min;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    72
import static jdk.jshell.SourceCodeAnalysis.Completeness.*;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    73
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    74
public class CompletenessStressTest extends KullaTesting {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    75
    public final static String JDK_ROOT_SRC_PROP = "jdk.root.src";
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    76
    public final static String JDK_ROOT_SRC;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    77
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    78
    static {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    79
        JDK_ROOT_SRC = System.getProperty(JDK_ROOT_SRC_PROP);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    80
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    81
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    82
    public File getSourceFile(String fileName) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    83
        for (File dir : getDirectoriesToTest()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    84
            File file = new File(dir, fileName);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    85
            if (file.exists()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    86
                return file;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    87
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    88
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    89
        throw new AssertionError("File not found: " + fileName);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    90
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    91
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    92
    public File[] getDirectoriesToTest() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    93
        return new File[]{
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    94
                new File(JDK_ROOT_SRC, "nashorn/src"),
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    95
                new File(JDK_ROOT_SRC, "langtools/src"),
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    96
                new File(JDK_ROOT_SRC, "jaxp/src"),
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    97
                new File(JDK_ROOT_SRC, "jaxws/src"),
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    98
                new File(JDK_ROOT_SRC, "jdk/src"),
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    99
                new File(JDK_ROOT_SRC, "corba/src")
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   100
        };
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   101
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   102
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   103
    @DataProvider(name = "crawler")
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   104
    public Object[][] dataProvider() throws IOException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   105
        File[] srcDirs = getDirectoriesToTest();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   106
        List<String[]> list = new ArrayList<>();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   107
        for (File srcDir : srcDirs) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   108
            String srcDirName = srcDir.getAbsolutePath();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   109
            // this is just to obtain pretty test names for testng tests
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   110
            List<String[]> a = Files.walk(Paths.get(srcDirName))
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   111
                    .map(Path::toFile)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   112
                    .map(File::getAbsolutePath)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   113
                    .filter(n -> n.endsWith(".java"))
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   114
                    .map(n -> n.replace(srcDirName, ""))
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   115
                    .map(n -> new String[]{n})
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   116
                    .collect(Collectors.toList());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   117
            if (a.isEmpty()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   118
                throw new AssertionError("Java sources have not been found in directory: " + srcDirName);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   119
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   120
            list.addAll(a);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   121
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   122
        return list.toArray(new String[list.size()][]);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   123
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   124
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   125
    @Test(dataProvider = "crawler")
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   126
    public void testFile(String fileName) throws IOException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   127
        File file = getSourceFile(fileName);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   128
        final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   129
        final StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   130
        boolean success = true;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   131
        StringWriter writer = new StringWriter();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   132
        writer.write("Testing : " + file.toString() + "\n");
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   133
        String text = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   134
        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(file);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   135
        JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fileManager, null, null, null, compilationUnits);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   136
        Iterable<? extends CompilationUnitTree> asts = task.parse();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   137
        Trees trees = Trees.instance(task);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   138
        SourcePositions sp = trees.getSourcePositions();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   139
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   140
        for (CompilationUnitTree cut : asts) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   141
            for (ImportTree imp : cut.getImports()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   142
                success &= testStatement(writer, sp, text, cut, imp);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   143
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   144
            for (Tree decl : cut.getTypeDecls()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   145
                success &= testStatement(writer, sp, text, cut, decl);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   146
                if (decl instanceof ClassTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   147
                    ClassTree ct = (ClassTree) decl;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   148
                    for (Tree mem : ct.getMembers()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   149
                        if (mem instanceof MethodTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   150
                            MethodTree mt = (MethodTree) mem;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   151
                            BlockTree bt = mt.getBody();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   152
                            // No abstract methods or constructors
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   153
                            if (bt != null && mt.getReturnType() != null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   154
                                // The modifiers synchronized, abstract, and default are not allowed on
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   155
                                // top-level declarations and are errors.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   156
                                Set<Modifier> modifier = mt.getModifiers().getFlags();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   157
                                if (!modifier.contains(Modifier.ABSTRACT)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   158
                                        && !modifier.contains(Modifier.SYNCHRONIZED)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   159
                                        && !modifier.contains(Modifier.DEFAULT)) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   160
                                    success &= testStatement(writer, sp, text, cut, mt);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   161
                                }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   162
                                testBlock(writer, sp, text, cut, bt);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   163
                            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   164
                        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   165
                    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   166
                }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   167
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   168
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   169
        fileManager.close();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   170
        if (!success) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   171
            throw new AssertionError(writer.toString());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   172
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   173
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   174
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   175
    private boolean isLegal(StatementTree st) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   176
        return !(st instanceof ReturnTree) &&
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   177
                !(st instanceof ContinueTree) && !(st instanceof BreakTree);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   178
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   179
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   180
    private boolean testBranch(StringWriter writer, SourcePositions sp, String text, CompilationUnitTree cut, StatementTree statementTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   181
        if (statementTree instanceof BlockTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   182
            return testBlock(writer, sp, text, cut, (BlockTree) statementTree);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   183
        } else if (isLegal(statementTree)) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   184
            return testStatement(writer, sp, text, cut, statementTree);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   185
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   186
        return true;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   187
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   188
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   189
    private boolean testBlock(StringWriter writer, SourcePositions sp, String text, CompilationUnitTree cut, BlockTree blockTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   190
        boolean success = true;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   191
        for (StatementTree st : blockTree.getStatements()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   192
            if (isLegal(st)) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   193
                success &= testStatement(writer, sp, text, cut, st);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   194
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   195
            if (st instanceof IfTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   196
                IfTree ifTree = (IfTree) st;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   197
                success &= testBranch(writer, sp, text, cut, ifTree.getThenStatement());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   198
                success &= testBranch(writer, sp, text, cut, ifTree.getElseStatement());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   199
            } else if (st instanceof WhileLoopTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   200
                WhileLoopTree whileLoopTree = (WhileLoopTree) st;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   201
                success &= testBranch(writer, sp, text, cut, whileLoopTree.getStatement());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   202
            } else if (st instanceof DoWhileLoopTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   203
                DoWhileLoopTree doWhileLoopTree = (DoWhileLoopTree) st;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   204
                success &= testBranch(writer, sp, text, cut, doWhileLoopTree.getStatement());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   205
            } else if (st instanceof ForLoopTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   206
                ForLoopTree forLoopTree = (ForLoopTree) st;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   207
                success &= testBranch(writer, sp, text, cut, forLoopTree.getStatement());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   208
            } else if (st instanceof LabeledStatementTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   209
                LabeledStatementTree labelTree = (LabeledStatementTree) st;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   210
                success &= testBranch(writer, sp, text, cut, labelTree.getStatement());
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   211
            } else if (st instanceof SwitchTree) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   212
                SwitchTree switchTree = (SwitchTree) st;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   213
                for (CaseTree caseTree : switchTree.getCases()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   214
                    for (StatementTree statementTree : caseTree.getStatements()) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   215
                        success &= testBranch(writer, sp, text, cut, statementTree);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   216
                    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   217
                }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   218
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   219
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   220
        return success;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   221
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   222
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   223
    private boolean testStatement(StringWriter writer, SourcePositions sp, String text, CompilationUnitTree cut, Tree statement) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   224
        if (statement == null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   225
            return true;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   226
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   227
        int start = (int) sp.getStartPosition(cut, statement);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   228
        int end = (int) sp.getEndPosition(cut, statement);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   229
        char ch = text.charAt(end - 1);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   230
        SourceCodeAnalysis.Completeness expected = COMPLETE;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   231
        LineMap lineMap = cut.getLineMap();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   232
        int row = (int) lineMap.getLineNumber(start);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   233
        int column = (int) lineMap.getColumnNumber(start);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   234
        switch (ch) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   235
            case ',':
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   236
            case ';':
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   237
                expected = (statement instanceof ExpressionStatementTree)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   238
                        ? COMPLETE
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   239
                        : COMPLETE_WITH_SEMI;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   240
                --end;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   241
                break;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   242
            case '}':
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   243
                break;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   244
            default:
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   245
                writer.write(String.format("Unexpected end: row %d, column %d: '%c' -- %s\n",
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   246
                        row, column, ch, text.substring(start, end)));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   247
                return true;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   248
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   249
        String unit = text.substring(start, end);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   250
        SourceCodeAnalysis.CompletionInfo ci = getAnalysis().analyzeCompletion(unit);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   251
        if (ci.completeness != expected) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   252
            if (expected == COMPLETE_WITH_SEMI && (ci.completeness == CONSIDERED_INCOMPLETE || ci.completeness == EMPTY)) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   253
                writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   254
                        start, end, unit));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   255
            } else {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   256
                String oops = unit.substring(max(0, ci.unitEndPos - 10), ci.unitEndPos) + "|||" +
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   257
                        unit.substring(ci.unitEndPos, min(unit.length(), ci.unitEndPos + 10));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   258
                writer.write(String.format("Expected %s got %s: '%s'  row %d, column %d: -- %s\n",
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   259
                        expected, ci.completeness, oops, row, column, unit));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   260
                return false;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   261
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   262
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   263
        return true;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   264
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   265
}