blob: beba0a3916f209db03db93bed2f99bae56c5cb29 [file] [log] [blame]
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001/*******************************************************************************
Stephan Herrmann4d079452014-03-27 18:01:49 +01002 * Copyright (c) 2000, 2014 IBM Corporation and others.
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00003 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
Stephan Herrmann5fa7f312012-07-13 01:52:51 +02007 *
8 * This is an implementation of an early-draft specification developed under the Java
9 * Community Process (JCP) and is made available for testing and evaluation purposes
10 * only. The code is not compatible with any specification of the JCP.
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000011 *
12 * Contributors:
13 * IBM Corporation - initial API and implementation
14 * Technical University Berlin - adapted for Object Teams
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +020015 * Stephan Herrmann - Contribution for
16 * bug 335093 - [compiler][null] minimal hook for future null annotation support
17 * bug 388800 - [1.8] adjust tests to 1.8 JRE
Stephan Herrmann307ebe32013-05-02 02:46:05 +020018 * bug 402237 - [1.8][compiler] investigate differences between compilers re MethodVerifyTest
19 * bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
Stephan Herrmann7c411a02013-12-29 14:47:52 +010020 * Bug 412203 - [compiler] Internal compiler error: java.lang.IllegalArgumentException: info cannot be null
Stephan Herrmannf087af32014-01-04 01:36:05 +010021 * Bug 422051 - [1.8][compiler][tests] cleanup excuses (JavacHasABug) in InterfaceMethodTests
Stephan Herrmannc1c48622014-01-04 23:19:31 +010022 * Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
Stephan Herrmann4d079452014-03-27 18:01:49 +010023 * Bug 425721 - [1.8][compiler] Nondeterministic results in GenericsRegressionTest_1_8.testBug424195a
Stephan Herrmann396f3342013-03-14 14:31:57 +010024 * Jesper S Moller - Contributions for bug 378674 - "The method can be declared as static" is wrong
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000025 *******************************************************************************/
26package org.eclipse.jdt.core.tests.compiler.regression;
27
28import java.io.BufferedReader;
29import java.io.BufferedWriter;
30import java.io.File;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000031import java.io.FileInputStream;
Stephan Herrmann618f6922012-08-10 22:00:05 +020032import java.io.FileOutputStream;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000033import java.io.FileWriter;
34import java.io.IOException;
35import java.io.InputStream;
36import java.io.InputStreamReader;
37import java.io.PrintWriter;
Stephan Herrmann71432c02011-10-25 16:30:36 +000038import java.net.URL;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000039import java.text.SimpleDateFormat;
40import java.util.ArrayList;
41import java.util.Date;
42import java.util.HashMap;
43import java.util.Iterator;
44import java.util.List;
45import java.util.Locale;
46import java.util.Map;
47import java.util.StringTokenizer;
48
Stephan Herrmann71432c02011-10-25 16:30:36 +000049import org.eclipse.core.runtime.FileLocator;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000050import org.eclipse.core.runtime.IPath;
51import org.eclipse.core.runtime.Path;
Stephan Herrmann71432c02011-10-25 16:30:36 +000052import org.eclipse.core.runtime.Platform;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000053import org.eclipse.jdt.core.JavaCore;
54import org.eclipse.jdt.core.ToolFactory;
55import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
56import org.eclipse.jdt.core.search.SearchDocument;
57import org.eclipse.jdt.core.search.SearchParticipant;
58import org.eclipse.jdt.core.tests.junit.extension.StopableTestCase;
59import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
60import org.eclipse.jdt.core.tests.util.CompilerTestSetup;
61import org.eclipse.jdt.core.tests.util.TestVerifier;
62import org.eclipse.jdt.core.tests.util.Util;
63import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
64import org.eclipse.jdt.core.util.ClassFormatException;
65import org.eclipse.jdt.internal.compiler.ASTVisitor;
66import org.eclipse.jdt.internal.compiler.Compiler;
67import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
68import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
69import org.eclipse.jdt.internal.compiler.IProblemFactory;
70import org.eclipse.jdt.internal.compiler.batch.FileSystem;
71import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
72import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
73import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
74import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
75import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
76import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
77import org.eclipse.jdt.internal.core.search.JavaSearchParticipant;
78import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
Stephan Herrmannaaa73af2013-12-29 16:34:59 +010079import org.osgi.framework.Bundle;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +000080
81public abstract class AbstractRegressionTest extends AbstractCompilerTest implements StopableTestCase {
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +020082
83 // for compiling against JRE 8:
84 static final boolean IS_JRE_8;
85 static final String COMPARATOR_IMPL_JRE8;
86 static final String COMPARATOR_RAW_IMPL_JRE8;
87 static final String COLLECTION_IMPL_JRE8;
88 static final String COLLECTION_RAW_IMPL_JRE8;
89 static final String LIST_IMPL_JRE8;
Stephan Herrmann307ebe32013-05-02 02:46:05 +020090 static final String COLLECTION_AND_LIST_IMPL_JRE8;
91 static final String COLLECTION_AND_LIST_RAW_IMPL_JRE8;
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +020092 static final String LIST_RAW_IMPL_JRE8;
93 static final String ITERABLE_IMPL_JRE8;
94 static final String ITERABLE_RAW_IMPL_JRE8;
Stephan Herrmann63010de2013-05-01 20:08:26 +020095 static final String ITERATOR_IMPL_JRE8;
96 static final String ITERATOR_RAW_IMPL_JRE8;
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +020097 static final String MAP_IMPL_JRE8;
98 static final String MAP_RAW_IMPL_JRE8;
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +020099
100 static {
101 String javaVersion = System.getProperty("java.specification.version");
102 IS_JRE_8 = "1.8".equals(javaVersion);
103 if (IS_JRE_8) { // TODO(stephan) accommodate future versions ...
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200104 COMPARATOR_IMPL_JRE8 = // replace '*' with T, '%' with U, $ with S
Stephan Herrmann63010de2013-05-01 20:08:26 +0200105 " public java.util.Comparator<*> reverseOrder() { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100106 " public java.util.Comparator<*> reversed() { return null;}\n" +
Stephan Herrmannc8a7ab72013-12-25 22:23:58 +0100107 " public java.util.Comparator<*> thenComparing(java.util.Comparator<? super *> other) { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100108 " public <% extends java.lang.Comparable<? super %>> java.util.Comparator<*> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor, java.util.Comparator<? super %> keyComparator) { return null;}\n" +
Stephan Herrmannc8a7ab72013-12-25 22:23:58 +0100109 " public <% extends java.lang.Comparable<? super %>> java.util.Comparator<*> thenComparing(java.util.function.Function<? super *, ? extends %> keyExtractor) { return null;}\n" +
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +0100110 " public java.util.Comparator<*> thenComparingInt(java.util.function.ToIntFunction<? super *> keyExtractor) { return null;}\n" +
111 " public java.util.Comparator<*> thenComparingLong(java.util.function.ToLongFunction<? super *> keyExtractor) { return null;}\n" +
112 " public java.util.Comparator<*> thenComparingDouble(java.util.function.ToDoubleFunction<? super *> keyExtractor) { return null;}\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200113 COMPARATOR_RAW_IMPL_JRE8 =
Stephan Herrmann64791942013-12-28 21:28:24 +0100114 " public java.util.Comparator reverseOrder() { return null;}\n" +
115 " public java.util.Comparator reversed() { return null;}\n" +
116 " public java.util.Comparator thenComparing(java.util.Comparator other) { return null;}\n" +
117 " public java.util.Comparator thenComparing(java.util.function.Function keyExtractor, java.util.Comparator keyComparator) { return null;}\n" +
118 " public java.util.Comparator thenComparing(java.util.function.Function keyExtractor) { return null;}\n" +
Stephan Herrmann5d5b2c32014-01-02 00:10:41 +0100119 " public java.util.Comparator thenComparingInt(java.util.function.ToIntFunction keyExtractor) { return null;}\n" +
120 " public java.util.Comparator thenComparingLong(java.util.function.ToLongFunction keyExtractor) { return null;}\n" +
121 " public java.util.Comparator thenComparingDouble(java.util.function.ToDoubleFunction keyExtractor) { return null;}\n";
Stephan Herrmann64791942013-12-28 21:28:24 +0100122 COLLECTION_IMPL_JRE8 =
123 " public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" +
124 " public boolean removeIf(java.util.function.Predicate<? super *> filter) { return false;}\n" +
125 " public java.util.stream.Stream<*> stream() { return null;}\n" +
126 " public java.util.stream.Stream<*> parallelStream() { return null;}\n";
127 COLLECTION_AND_LIST_IMPL_JRE8 =
128 " public boolean removeAll(java.util.function.Predicate<? super *> filter) { return false;}\n" +
129 " public boolean removeIf(java.util.function.Predicate<? super *> filter) { return false;}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200130 " public java.util.stream.Stream<*> stream() { return null;}\n" +
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200131 " public java.util.stream.Stream<*> parallelStream() { return null;}\n" +
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200132 " public void sort(java.util.Comparator<? super *> comparator) {}\n" +
133 " public void parallelSort(java.util.Comparator<? super *> comparator) {}\n" +
134 " public void replaceAll(java.util.function.UnaryOperator<*> operator) {}\n";
Stephan Herrmann64791942013-12-28 21:28:24 +0100135 COLLECTION_RAW_IMPL_JRE8 =
Stephan Herrmann63010de2013-05-01 20:08:26 +0200136 " public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100137 " public @SuppressWarnings(\"rawtypes\") boolean removeIf(java.util.function.Predicate filter) { return false;}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200138 " public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100139 " public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\n";
140 LIST_IMPL_JRE8 = // replace '*' with your concrete type argument
141 " public void sort(java.util.Comparator<? super *> comparator) {}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200142 " public void parallelSort(java.util.Comparator<? super *> comparator) {}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100143 " public void replaceAll(java.util.function.UnaryOperator<*> operator) {}\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200144 LIST_RAW_IMPL_JRE8 =
145 " public @SuppressWarnings(\"rawtypes\") void sort(java.util.Comparator comparator) {}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200146 " public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100147 " public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.UnaryOperator operator) {}\n";
148 COLLECTION_AND_LIST_RAW_IMPL_JRE8 =
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200149 " public @SuppressWarnings(\"rawtypes\") boolean removeAll(java.util.function.Predicate filter) { return false;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100150 " public @SuppressWarnings(\"rawtypes\") boolean removeIf(java.util.function.Predicate filter) { return false;}\n" +
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200151 " public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream stream() { return null;}\n" +
152 " public @SuppressWarnings(\"rawtypes\") java.util.stream.Stream parallelStream() { return null;}\n" +
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200153 " public @SuppressWarnings(\"rawtypes\") void sort(java.util.Comparator comparator) {}\n" +
154 " public @SuppressWarnings(\"rawtypes\") void parallelSort(java.util.Comparator comparator) {}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200155 " public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.UnaryOperator operator) {}\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200156 ITERABLE_IMPL_JRE8 = // replace '*' with your concrete type argument
Stephan Herrmannc8a7ab72013-12-25 22:23:58 +0100157 " public void forEach(java.util.function.Consumer<? super *> block){}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100158 " public void forEachRemaining(java.util.function.Consumer<? super *> action) {}\n" +
159 " public java.util.Spliterator<*> spliterator() {return null;}\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200160 ITERABLE_RAW_IMPL_JRE8 =
Stephan Herrmann64791942013-12-28 21:28:24 +0100161 " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer action) {}\n" +
162 " public @SuppressWarnings(\"rawtypes\") void forEachRemaining(java.util.function.Consumer action) {}\n" +
163 " public @SuppressWarnings(\"rawtypes\") java.util.Spliterator spliterator() {return null;}\n";
Stephan Herrmann63010de2013-05-01 20:08:26 +0200164 ITERATOR_IMPL_JRE8 = // replace '*' with your concrete type argument
Stephan Herrmannc8a7ab72013-12-25 22:23:58 +0100165 "public void forEach(java.util.function.Consumer<? super *> action) {}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100166 "public void forEachRemaining(java.util.function.Consumer<? super *> action) {}\n";
167 ITERATOR_RAW_IMPL_JRE8 =
168 " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.Consumer block) {}\n" +
169 " public @SuppressWarnings(\"rawtypes\") void forEachRemaining(java.util.function.Consumer action) {}\n";
Stephan Herrmann63010de2013-05-01 20:08:26 +0200170 MAP_IMPL_JRE8 = // '*' for 'K', '%' for 'V'
171 " public boolean remove(Object key, Object value) { return false;}\n" +
Stephan Herrmannc8a7ab72013-12-25 22:23:58 +0100172 " public % getOrDefault(Object key, % defaultValue) {return defaultValue;}\n" +
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200173 " public void forEach(java.util.function.BiConsumer<? super *, ? super %> block) {}\n" +
Stephan Herrmannc8a7ab72013-12-25 22:23:58 +0100174 " public void replaceAll(java.util.function.BiFunction<? super *, ? super %, ? extends %> function) {}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200175 " public % putIfAbsent(* key, % value) { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100176 " public boolean replace(* key, % oldValue, % newValue) { return false;}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200177 " public % replace(* key, % value) { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100178 " public % computeIfAbsent(* key, java.util.function.Function<? super *, ? extends %> mappingFunction) { return null;}\n" +
179 " public % computeIfPresent(* key, java.util.function.BiFunction<? super *, ? super %, ? extends %> remappingFunction) { return null;}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200180 " public % compute(* key, java.util.function.BiFunction<? super *, ? super %, ? extends %> remappingFunction) { return null;}\n" +
181 " public % merge(* key, % value, java.util.function.BiFunction<? super %, ? super %, ? extends %> remappingFunction) { return null;}\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200182 MAP_RAW_IMPL_JRE8 =
Stephan Herrmann63010de2013-05-01 20:08:26 +0200183 " public boolean remove(Object key, Object value) { return false;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100184 " public @SuppressWarnings(\"rawtypes\") Object getOrDefault(Object key, Object defaultValue) { return defaultValue;}\n" +
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200185 " public @SuppressWarnings(\"rawtypes\") void forEach(java.util.function.BiConsumer block) {}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200186 " public @SuppressWarnings(\"rawtypes\") void replaceAll(java.util.function.BiFunction function) {}\n" +
187 " public Object putIfAbsent(Object key, Object value) { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100188 " public boolean replace(Object key, Object oldValue, Object newValue) { return false;}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200189 " public Object replace(Object key, Object value) { return null;}\n" +
Stephan Herrmann64791942013-12-28 21:28:24 +0100190 " public @SuppressWarnings(\"rawtypes\") Object computeIfAbsent(Object key, java.util.function.Function mappingFunction) { return null;}\n" +
191 " public @SuppressWarnings(\"rawtypes\") Object computeIfPresent(Object key, java.util.function.BiFunction remappingFunction) { return null;}\n" +
Stephan Herrmann63010de2013-05-01 20:08:26 +0200192 " public @SuppressWarnings(\"rawtypes\") Object compute(Object key, java.util.function.BiFunction remappingFunction) { return null;}\n" +
193 " public @SuppressWarnings(\"rawtypes\") Object merge(Object key, Object value, java.util.function.BiFunction remappingFunction) { return null;}\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200194 } else {
195 COMPARATOR_IMPL_JRE8 = "";
196 COMPARATOR_RAW_IMPL_JRE8 = "";
197 COLLECTION_IMPL_JRE8 = "";
198 COLLECTION_RAW_IMPL_JRE8 = "";
199 LIST_IMPL_JRE8 = "";
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200200 COLLECTION_AND_LIST_IMPL_JRE8 = "";
201 COLLECTION_AND_LIST_RAW_IMPL_JRE8 = "";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200202 LIST_RAW_IMPL_JRE8 = "";
203 ITERABLE_IMPL_JRE8 = "";
204 ITERABLE_RAW_IMPL_JRE8 = "";
Stephan Herrmann64791942013-12-28 21:28:24 +0100205 ITERATOR_IMPL_JRE8 = "\n\n";
206 ITERATOR_RAW_IMPL_JRE8 = "\n\n";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200207 MAP_IMPL_JRE8 = "";
208 MAP_RAW_IMPL_JRE8 = "";
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200209 }
210 }
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200211 String getCollectionAndListRawImplJRE8() {
212 if (this.complianceLevel < ClassFileConstants.JDK1_5)
213 return COLLECTION_AND_LIST_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
214 return COLLECTION_AND_LIST_RAW_IMPL_JRE8;
215 }
Stephan Herrmannbf0ecd32013-04-04 15:17:36 +0200216 String getListRawImplJRE8() {
217 if (this.complianceLevel < ClassFileConstants.JDK1_5)
218 return LIST_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
219 return LIST_RAW_IMPL_JRE8;
220 }
221 String getIterableRawImplJRE8() {
222 if (this.complianceLevel < ClassFileConstants.JDK1_5)
223 return ITERABLE_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
224 return ITERABLE_RAW_IMPL_JRE8;
225 }
226 String getCollectionRawImplJRE8() {
227 if (this.complianceLevel < ClassFileConstants.JDK1_5)
228 return COLLECTION_RAW_IMPL_JRE8.replaceAll("@SuppressWarnings\\(\"rawtypes\"\\)", "");
229 return COLLECTION_RAW_IMPL_JRE8;
230 }
231
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000232 // javac comparison related types, fields and methods - see runJavac for
233 // details
234static class JavacCompiler {
235 String rootDirectoryPath;
236 String javacPathName;
237 String version; // not intended to be modified - one of JavaCore.VERSION_1_*
238 int minor;
239 String rawVersion; // not intended to be modified - more complete version name
240 long compliance;
241 public static final long EXIT_VALUE_MASK = 0x00000000FFFFFFFFL;
242 public static final long ERROR_LOG_MASK = 0xFFFFFFFF00000000L;
243 private static final String[] jarsNames = new String[] {
244 "/lib/vm.jar",
245 "/lib/rt.jar",
246 "/lib/core.jar",
247 "/lib/security.jar",
248 "/lib/xml.jar",
249 "/lib/graphics.jar"
250 };
251 private String classpath;
252 JavacCompiler(String rootDirectoryPath) throws IOException, InterruptedException {
253 this(rootDirectoryPath, null);
254 }
255 JavacCompiler(String rootDirectoryPath, String rawVersion) throws IOException, InterruptedException {
256 this.rootDirectoryPath = rootDirectoryPath;
257 this.javacPathName = new File(rootDirectoryPath + File.separator
258 + "bin" + File.separator + JAVAC_NAME).getCanonicalPath();
259 // WORK don't need JAVAC_NAME any more; suppress this as we work towards code cleanup
260 if (rawVersion == null) {
261 Process fetchVersionProcess = null;
262 try {
263 fetchVersionProcess = Runtime.getRuntime().exec(this.javacPathName
264 + " -version", null, null);
265 Logger versionLogger = new Logger(fetchVersionProcess.getErrorStream(), "");
266 versionLogger.start();
267 fetchVersionProcess.waitFor();
268 versionLogger.join(); // make sure we get the whole output
269 rawVersion = versionLogger.buffer.toString();
270 int eol = rawVersion.indexOf('\n');
271 if (eol != -1) {
272 rawVersion = rawVersion.substring(0, eol);
273 }
274 if (rawVersion.startsWith("javac ")) {
275 rawVersion = rawVersion.substring(6, rawVersion.length());
276 }
277 } finally {
278 if (fetchVersionProcess != null) {
279 fetchVersionProcess.destroy(); // closes process streams
280 }
281 }
282 }
283 if (rawVersion.indexOf("1.4") != -1 ||
284 this.javacPathName.indexOf("1.4") != -1
285 /* in fact, SUN javac 1.4 does not support the -version option;
286 * this is a imperfect heuristic to catch the case */) {
287 this.version = JavaCore.VERSION_1_4;
288 } else if (rawVersion.indexOf("1.5") != -1) {
289 this.version = JavaCore.VERSION_1_5;
290 } else if (rawVersion.indexOf("1.6") != -1) {
291 this.version = JavaCore.VERSION_1_6;
292 } else if (rawVersion.indexOf("1.7") != -1) {
293 this.version = JavaCore.VERSION_1_7;
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200294 } else if (rawVersion.indexOf("1.8") != -1) {
295 this.version = JavaCore.VERSION_1_8;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000296 } else {
297 throw new RuntimeException("unknown javac version: " + rawVersion);
298 }
299 this.compliance = CompilerOptions.versionToJdkLevel(this.version);
300 this.minor = minorFromRawVersion(this.version, rawVersion);
301 this.rawVersion = rawVersion;
302 StringBuffer classpathBuffer = new StringBuffer(" -classpath ");
303 for (int i = 0, l = jarsNames.length; i < l; i++) {
304 classpathBuffer.append(rootDirectoryPath);
305 classpathBuffer.append(jarsNames[i]);
306 classpathBuffer.append(File.pathSeparator);
307 }
308 this.classpath = classpathBuffer.toString();
309 }
310 // projects known raw versions to minors; minors should grow with time, so
311 // that before and after relationships be easy to implement upon compilers
312 // of the same version; two latest digits are used for variants into levels
313 // denoted by the two first digits
314 static int minorFromRawVersion (String version, String rawVersion) {
315 if (version == JavaCore.VERSION_1_5) {
316 if ("1.5.0_15-ea".equals(rawVersion)) {
317 return 1500;
318 }
319 if ("1.5.0_16-ea".equals(rawVersion)) { // b01
320 return 1600;
321 }
322 }
323 if (version == JavaCore.VERSION_1_6) {
324 if ("1.6.0_10-ea".equals(rawVersion)) {
325 return 1000;
326 }
327 if ("1.6.0_10-beta".equals(rawVersion)) { // b24
328 return 1010;
329 }
330 }
331 if (version == JavaCore.VERSION_1_7) {
332 if ("1.7.0-ea".equals(rawVersion)) {
333 return 0000;
334 }
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200335 if ("1.7.0_10".equals(rawVersion)) {
336 return 1000;
337 }
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100338 if ("1.7.0_25".equals(rawVersion)) {
339 return 2500;
340 }
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200341 }
342 if (version == JavaCore.VERSION_1_8) {
Stephan Herrmann4d079452014-03-27 18:01:49 +0100343 if ("1.8.0-ea".equals(rawVersion) || ("1.8.0".equals(rawVersion))) {
Stephan Herrmann307ebe32013-05-02 02:46:05 +0200344 return 0000;
345 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000346 }
347 throw new RuntimeException("unknown raw javac version: " + rawVersion);
348 }
349 // returns 0L if everything went fine; else the lower word contains the
350 // exit value and the upper word is non-zero iff the error log has contents
351 long compile(File directory, String options, String[] sourceFileNames, StringBuffer log) throws IOException, InterruptedException {
352 Process compileProcess = null;
353 long result = 0L;
354 // WORK classpath should depend on the compiler, not on the default runtime
355 try {
356 StringBuffer cmdLine = new StringBuffer(this.javacPathName);
357 cmdLine.append(this.classpath);
358 cmdLine.append(". ");
359 cmdLine.append(options);
360 for (int i = 0; i < sourceFileNames.length; i ++) {
361 cmdLine.append(' ');
362 cmdLine.append(sourceFileNames[i]);
363 }
364 String cmdLineAsString;
365 // WORK improve double-quotes management on Linux
366 if ("Linux".equals(System.getProperty("os.name"))) {
367 cmdLineAsString = cmdLine.toString().replaceAll("\"", "");
368 } else {
369 cmdLineAsString = cmdLine.toString();
370 }
371 compileProcess = Runtime.getRuntime().exec(cmdLineAsString, null, directory);
372 Logger errorLogger = new Logger(compileProcess.getErrorStream(),
373 "ERROR", log == null ? new StringBuffer() : log);
374 errorLogger.start();
375 int compilerResult = compileProcess.waitFor();
376 result |= compilerResult; // caveat: may never terminate under specific conditions
377 errorLogger.join(); // make sure we get the whole output
378 if (errorLogger.buffer.length() > 0) {
379 System.err.println("--- javac err: ---");
380 System.err.println(errorLogger.buffer.toString());
381 result |= ERROR_LOG_MASK;
382 }
383 } finally {
384 if (compileProcess != null) {
385 compileProcess.destroy();
386 }
387 }
388 return result;
389 }
390}
391static class JavaRuntime {
392 private String rootDirectoryPath;
393 private String javaPathName;
394 String version; // not intended to be modified - one of JavaCore.VERSION_1_*
395 String rawVersion; // not intended to be modified - more complete version name
396 int minor;
397 private static HashMap runtimes = new HashMap();
398 static JavaRuntime runtimeFor(JavacCompiler compiler) throws IOException, InterruptedException {
399 JavaRuntime cached = (JavaRuntime) runtimes.get(compiler.rawVersion);
400 if (cached == null) {
401 cached = new JavaRuntime(compiler.rootDirectoryPath, compiler.version, compiler.rawVersion, compiler.minor);
402 runtimes.put(compiler.rawVersion, cached);
403 }
404 return cached;
405 }
406 private JavaRuntime(String rootDirectoryPath, String version, String rawVersion, int minor) throws IOException, InterruptedException {
407 this.rootDirectoryPath = rootDirectoryPath;
408 this.javaPathName = new File(this.rootDirectoryPath + File.separator
409 + "bin" + File.separator + JAVA_NAME).getCanonicalPath();
410 this.version = version;
411 this.rawVersion = rawVersion;
412 this.minor = minor;
413 }
414 // returns 0 if everything went fine
415 int execute(File directory, String options, String className, StringBuffer stdout, StringBuffer stderr) throws IOException, InterruptedException {
416 Process executionProcess = null;
417 try {
418 StringBuffer cmdLine = new StringBuffer(this.javaPathName);
419 cmdLine.append(" -classpath . "); // default classpath
420 cmdLine.append(options);
421 cmdLine.append(' ');
422 cmdLine.append(className);
423 executionProcess = Runtime.getRuntime().exec(cmdLine.toString(), null, directory);
424 Logger outputLogger = new Logger(executionProcess.getInputStream(),
425 "RUNTIME OUTPUT", stdout == null ? new StringBuffer() : stdout);
426 outputLogger.start();
427 Logger errorLogger = new Logger(executionProcess.getErrorStream(),
428 "RUNTIME ERROR", stderr == null ? new StringBuffer() : stderr);
429 errorLogger.start();
430 int result = executionProcess.waitFor(); // caveat: may never terminate under specific conditions
431 outputLogger.join(); // make sure we get the whole output
432 errorLogger.join(); // make sure we get the whole output
433 return result;
434 } finally {
435 if (executionProcess != null) {
436 executionProcess.destroy();
437 }
438 }
439 }
440}
441protected static class JavacTestOptions {
442 static final JavacTestOptions DEFAULT = new JavacTestOptions();
443 static final JavacTestOptions SKIP = new JavacTestOptions() {
444 boolean skip(JavacCompiler compiler) {
445 return true;
446 }
447 };
448 // TODO (maxime) enable selective javac output dir manipulations between
449 // tests steps
450 // some tests manipulate the OUTPUT_DIR explicitly between run*Test calls;
451 // however, these manipulations are not reflected in the javac output
452 // directory (yet); skipping until we fix this
453 static final JavacTestOptions SKIP_UNTIL_FRAMEWORK_FIX = new JavacTestOptions() {
454 boolean skip(JavacCompiler compiler) {
455 return true;
456 }
457 };
458 private String compilerOptions = "";
459 public JavacTestOptions() {
460 }
461 public JavacTestOptions(String compilerOptions) {
462 this.compilerOptions = compilerOptions;
463 }
464 String getCompilerOptions() {
465 return this.compilerOptions;
466 }
Stephan Herrmann4d079452014-03-27 18:01:49 +0100467 public void setCompilerOptions(String options) {
468 this.compilerOptions = options;
469 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000470 boolean skip(JavacCompiler compiler) {
471 return false;
472 }
473 static class MismatchType {
474 static final int EclipseErrorsJavacNone = 0x0001;
475 static final int EclipseErrorsJavacWarnings = 0x0002;
476 static final int JavacErrorsEclipseNone = 0x0004;
477 static final int JavacErrorsEclipseWarnings = 0x0008;
478 static final int EclipseWarningsJavacNone = 0x0010;
479 static final int JavacWarningsEclipseNone = 0x0020;
480 static final int StandardOutputMismatch = 0x0040;
481 static final int ErrorOutputMismatch = 0x0080;
482 static final int JavacAborted = 0x0100;
483 static final int JavacNotLaunched = 0x0200;
484 static final int JavaAborted = 0x0400;
485 static final int JavaNotLaunched = 0x0800;
486 }
487 public static class Excuse extends JavacTestOptions {
488 protected int mismatchType;
489 Excuse(int mismatchType) {
490 this.mismatchType = mismatchType;
491 }
492 Excuse excuseFor(JavacCompiler compiler) {
493 return this;
494 }
495 public boolean clears(int mismatch) {
496 return this.mismatchType == 0 || (this.mismatchType & mismatch) == mismatch; // one excuse can clear multiple mismatches
497 }
498 public static Excuse
499 EclipseHasSomeMoreWarnings = RUN_JAVAC ?
500 new Excuse(MismatchType.EclipseWarningsJavacNone) : null,
501 EclipseWarningConfiguredAsError = RUN_JAVAC ?
502 new Excuse(MismatchType.EclipseErrorsJavacWarnings | MismatchType.EclipseErrorsJavacNone) : null,
503 JavacCompilesBogusReferencedFileAgain = RUN_JAVAC ?
504 new Excuse(MismatchType.JavacErrorsEclipseNone) : null;
505 }
506 Excuse excuseFor(JavacCompiler compiler) {
507 return null;
508 }
509 public static class EclipseHasABug extends Excuse {
510 EclipseHasABug(int mismatchType) {
511 super(mismatchType);
512 }
513 public static EclipseHasABug
514 EclipseBug159851 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=159851
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100515 new EclipseHasABug(MismatchType.JavacErrorsEclipseNone) {
516 Excuse excuseFor(JavacCompiler compiler) {
517 return compiler.compliance < ClassFileConstants.JDK1_7 ? this : null;
518 }
519 } : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000520 EclipseBug177715 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=177715
521 new EclipseHasABug(MismatchType.JavacErrorsEclipseNone) : null,
522 EclipseBug207935 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=207935
523 new EclipseHasABug(MismatchType.EclipseErrorsJavacNone | MismatchType.EclipseWarningsJavacNone) : null,
524 EclipseBug216558 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=216558
525 new EclipseHasABug(MismatchType.JavacErrorsEclipseNone) : null,
526 EclipseBug235550 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=235550
527 new EclipseHasABug(MismatchType.JavacErrorsEclipseNone) : null,
528 EclipseBug235809 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=235809
529 new EclipseHasABug(MismatchType.StandardOutputMismatch) : null,
530 EclipseBug236217 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236217
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100531 new EclipseHasABug(MismatchType.JavacErrorsEclipseNone) {
532 Excuse excuseFor(JavacCompiler compiler) {
533 return compiler.compliance < ClassFileConstants.JDK1_8 ? this : null; // in 1.8 accepted by both compilers
534 }
535 } : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000536 EclipseBug236236 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236236
537 new EclipseHasABug(MismatchType.EclipseErrorsJavacNone) {
538 Excuse excuseFor(JavacCompiler compiler) {
539 return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
540 }
541 }: null,
542 EclipseBug236242 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236242
543 new EclipseHasABug(MismatchType.EclipseErrorsJavacWarnings) {
544 Excuse excuseFor(JavacCompiler compiler) {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100545 return compiler.compliance == ClassFileConstants.JDK1_7 ? this : null;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000546 }
547 }: null,
548 EclipseBug236243 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236243
549 new EclipseHasABug(MismatchType.EclipseErrorsJavacNone) {
550 Excuse excuseFor(JavacCompiler compiler) {
551 return compiler.compliance > ClassFileConstants.JDK1_6 ? this : null;
552 }
553 }: null,
554 EclipseBug236370 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236370
555 new EclipseHasABug(MismatchType.EclipseErrorsJavacNone) {
556 Excuse excuseFor(JavacCompiler compiler) {
557 return compiler.compliance > ClassFileConstants.JDK1_6 ? this : null;
558 }
559 }: null,
560 EclipseBug236379 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=236379
561 new EclipseHasABug(MismatchType.EclipseWarningsJavacNone) {
562 Excuse excuseFor(JavacCompiler compiler) {
563 return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
564 }
565 }: null;
566 }
567 // Justification based upon:
568 // - Eclipse bugs opened to investigate differences and closed as INVALID
569 // on grounds other than an identified javac bug;
570 // - Eclipse bugs that discuss the topic in depth and explain why we made a
571 // given choice;
572 // - explanations inlined here (no bug available, apparently not worth
573 // opening one).
574 public static class EclipseJustification extends Excuse {
575 EclipseJustification(int mismatchType) {
576 super(mismatchType);
577 }
578 public static final EclipseJustification
579 EclipseBug40839 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40839
580 new EclipseJustification(MismatchType.JavacWarningsEclipseNone) : null,
581 EclipseBug72704 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=72704
582 new EclipseJustification(MismatchType.EclipseErrorsJavacNone) : null,
583 EclipseBug83902 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=83902
584 new EclipseJustification(MismatchType.EclipseWarningsJavacNone) {
585 Excuse excuseFor(JavacCompiler compiler) {
586 return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
587 }
588 } : null,
589 EclipseBug83902b = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=83902
590 new EclipseJustification(MismatchType.JavacErrorsEclipseWarnings) : null,
591 EclipseBug95021 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=95021
592 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) {
593 Excuse excuseFor(JavacCompiler compiler) {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100594 return compiler.compliance == ClassFileConstants.JDK1_7 ? this : null;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000595 }
596 // WORK consider adding reversed pivots
597 } : null,
598 EclipseBug112433 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=112433
599 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) : null,
600 EclipseBug126712 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=126712 & http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6342411
601 new EclipseJustification(MismatchType.StandardOutputMismatch) {
602 Excuse excuseFor(JavacCompiler compiler) {
603 return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
604 }
605 // WORK consider adding reversed pivots
606 } : null,
607 EclipseBug126744 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=126744
608 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000609 EclipseBug151275 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=151275
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100610 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) {
611 Excuse excuseFor(JavacCompiler compiler) {
612 return compiler.compliance < ClassFileConstants.JDK1_7 ? this : null;
613 }
614 } : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000615 EclipseBug159214 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=159214
616 new EclipseJustification(MismatchType.EclipseErrorsJavacNone) {
617 Excuse excuseFor(JavacCompiler compiler) {
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100618 return compiler.compliance == ClassFileConstants.JDK1_6 ? this : null;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000619 }
620 // WORK consider adding reversed pivots
621 } : null,
622 EclipseBug169017 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=169017
623 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) {
624 Excuse excuseFor(JavacCompiler compiler) {
625 return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
626 }
627 // WORK consider adding reversed pivots
628 } : null,
629 EclipseBug180789 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=180789
630 new EclipseJustification(MismatchType.EclipseErrorsJavacWarnings) : null,
631 EclipseBug183211 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=183211
632 new EclipseJustification(MismatchType.JavacErrorsEclipseNone | MismatchType.EclipseErrorsJavacNone) : null,
633 EclipseBug183211b = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=183211
634 new EclipseJustification(MismatchType.EclipseErrorsJavacNone) {
635 Excuse excuseFor(JavacCompiler compiler) {
636 return compiler.compliance > ClassFileConstants.JDK1_5 ? this : null;
637 }
638 } : null,
639 EclipseBug185422 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=185422
640 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) : null,
641 EclipseBug218677 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=218677
642 new EclipseJustification(MismatchType.EclipseErrorsJavacNone) {
643 Excuse excuseFor(JavacCompiler compiler) {
644 return compiler.compliance > ClassFileConstants.JDK1_6 ? this : null;
645 }
646 // WORK consider adding reversed pivots
647 } : null,
648 EclipseBug234815 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=234815
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100649 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) {
650 Excuse excuseFor(JavacCompiler compiler) {
651 return compiler.compliance < ClassFileConstants.JDK1_7 ? this : null;
652 }
653 }: null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000654 EclipseBug235543 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=235543
655 new EclipseJustification(MismatchType.EclipseErrorsJavacNone) : null,
656 EclipseBug235546 = RUN_JAVAC ? // https://bugs.eclipse.org/bugs/show_bug.cgi?id=235546
657 new EclipseJustification(MismatchType.JavacErrorsEclipseNone) : null;
658 public static final EclipseJustification
659 EclipseJustification0001 = RUN_JAVAC ?
660 new EclipseJustification(MismatchType.EclipseErrorsJavacNone) : null;
661 /* javac properly detects duplicate attributes in annotations in the
662 * simplest case (AnnotationTest#18b) but fails on a slightly more
663 * complex one where the duplicate is within an embedded annotation;
664 * there seems to be no reason for not reporting the error
665 * (AnnotationTest#18) */
666 }
667 public static class JavacHasABug extends Excuse {
668 long pivotCompliance;
669 int pivotMinor;
670 int[] minorsFixed;
671 static final int NO_FIX = -1;
672 static final int IRRELEVANT = -2;
673 JavacHasABug(int mismatchType) {
674 super(mismatchType);
675 }
676// private JavacHasABug(int mismatchType, int[] minorsFixed) {
677// super(mismatchType);
678// this.minorsFixed = minorsFixed;
679// }
680 private JavacHasABug(int mismatchType, long pivotCompliance, int pivotMinor) {
681 super(mismatchType);
682 this.pivotCompliance = pivotCompliance;
683 this.pivotMinor = pivotMinor;
684 }
685 Excuse excuseFor(JavacCompiler compiler) {
686 if (this.minorsFixed != null) {
Stephan Herrmann5fa7f312012-07-13 01:52:51 +0200687 if (compiler.compliance == ClassFileConstants.JDK1_8) {
688 return this.minorsFixed[5] > compiler.minor || this.minorsFixed[5] < 0 ?
689 this : null;
690 } else if (compiler.compliance == ClassFileConstants.JDK1_7) {
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000691 return this.minorsFixed[4] > compiler.minor || this.minorsFixed[4] < 0 ?
692 this : null;
693 } else if (compiler.compliance == ClassFileConstants.JDK1_6) {
694 return this.minorsFixed[3] > compiler.minor || this.minorsFixed[3] < 0 ?
695 this : null;
696 } else if (compiler.compliance == ClassFileConstants.JDK1_5) {
697 return this.minorsFixed[2] > compiler.minor || this.minorsFixed[2] < 0 ?
698 this : null;
699 } else if (compiler.compliance == ClassFileConstants.JDK1_4) {
700 return this.minorsFixed[1] > compiler.minor || this.minorsFixed[1] < 0 ?
701 this : null;
702 } else if (compiler.compliance == ClassFileConstants.JDK1_3) {
703 return this.minorsFixed[0] > compiler.minor || this.minorsFixed[0] < 0 ?
704 this : null;
705 }
706 throw new RuntimeException(); // should not get there
707 } else if (this.pivotCompliance > 0) {
708 if (this.pivotCompliance < compiler.compliance) {
709 return null;
710 } else if (this.pivotCompliance > compiler.compliance) {
711 return this;
712 } else {
713 return this.pivotMinor > compiler.minor ? this : null;
714 }
715 } else if (this.pivotCompliance < 0) {
716 if (this.pivotCompliance < -compiler.compliance) {
717 return null;
718 } else if (this.pivotCompliance > -compiler.compliance) {
719 return this;
720 } else {
721 return this.pivotMinor <= compiler.minor ? this : null;
722 }
723 }
724 return this;
725 }
726 // bugs that we know precisely of
727 public static JavacHasABug
728 JavacBug4094180 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4094180
729 new JavacHasABug(MismatchType.EclipseErrorsJavacNone) : null,
730 JavacBug4660984 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4660984 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=235555
731 new JavacHasABug(MismatchType.JavacErrorsEclipseNone) : null,
732 JavacBug5042462 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5042462 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=208873
733 new JavacHasABug(
734 MismatchType.JavacErrorsEclipseNone,
735 ClassFileConstants.JDK1_7, 0 /* 1.7.0 b17 */) : null,
736 JavacBug5061359 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5061359
737 new JavacHasABug(
738 MismatchType.EclipseErrorsJavacNone,
739 ClassFileConstants.JDK1_7, 0 /* 1.7.0 b03 */) : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000740 JavacBug6302954 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=98379
741 new JavacHasABug(
742 MismatchType.JavacErrorsEclipseNone,
743 ClassFileConstants.JDK1_7, 0 /* 1.7.0 b03 */) : null,
744 JavacBug6400189 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6400189 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=106744 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=167952
745 new JavacHasABug(
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100746 MismatchType.EclipseErrorsJavacNone) {
747 Excuse excuseFor(JavacCompiler compiler) {
748 return compiler.compliance == ClassFileConstants.JDK1_6 ? this : null;
749 }
750 } : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000751 JavacBug6500701 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6500701 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=209779
752 new JavacHasABug(
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100753 MismatchType.StandardOutputMismatch,
754 ClassFileConstants.JDK1_7, 0) : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000755 JavacBug6531075 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6531075
756 new JavacHasABug(
757 MismatchType.StandardOutputMismatch,
758 ClassFileConstants.JDK1_7, 0) : null, // fixed in jdk7 b27; unfortunately, we do not have a distinct minor for this, hence former jdk7s will report an unused excuse
759 JavacBug6569404 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6569404
760 new JavacHasABug(
Stephan Herrmannc1c48622014-01-04 23:19:31 +0100761 MismatchType.JavacErrorsEclipseNone) {
762 Excuse excuseFor(JavacCompiler compiler) {
763 // present only in javac6 between 1.6.0_10_b08 and EOL
764 return (compiler.compliance == ClassFileConstants.JDK1_6 && compiler.minor >= 10) ? this : null;
765 }
766 } : null,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000767 JavacBug6557661 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6557661 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=129261
768 new JavacHasABug(
769 MismatchType.EclipseErrorsJavacNone) : null,
770 JavacBug6573446 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6573446 & https://bugs.eclipse.org/bugs/show_bug.cgi?id=190945
771 new JavacHasABug(
772 MismatchType.EclipseErrorsJavacNone) : null,
773 JavacBug6575821 = RUN_JAVAC ? // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6575821
774 new JavacHasABug(
775 MismatchType.JavacErrorsEclipseNone,
776 ClassFileConstants.JDK1_6, 10 /* 1.6.0_10_b08 or better - maybe before */) : null;
777 // bugs that have been fixed but that we've not identified
778 public static JavacHasABug
779 JavacBugFixed_6_10 = RUN_JAVAC ?
780 new JavacHasABug(
781 0 /* all */,
782 ClassFileConstants.JDK1_6, 1000 /* 1.6.0_10_b08 or better - maybe before */) : null,
783 JavacBugFixed_6_10_b24 = RUN_JAVAC ?
784 new JavacHasABug(
785 0 /* all */,
786 ClassFileConstants.JDK1_6, 1010 /* 1.6.0_10_b24 or better - maybe before */) : null,
787 JavacBugFixed_7 = RUN_JAVAC ?
788 new JavacHasABug(
789 0 /* all */,
790 ClassFileConstants.JDK1_7, 0 /* 1.7.0_b24 or better - maybe before */) : null;
791 // bugs that have neither been fixed nor formally identified but which outcomes are obvious enough to clear any doubts
792 public static JavacHasABug
793 JavacGeneratesByteCodeUponWhichJavaThrowsAnException = RUN_JAVAC ?
794 new JavacHasABug(
795 MismatchType.StandardOutputMismatch) : null,
796 JavacThrowsAnException = RUN_JAVAC ? // some of these are transient - that is, depend on the system on which the test is run, aka stack overflow
797 new JavacHasABug(
798 MismatchType.JavacErrorsEclipseNone) : null,
799 JavacThrowsAnExceptionForJava_1_5_0_16 = RUN_JAVAC ?
800 new JavacHasABug(
801 MismatchType.JavacErrorsEclipseNone) {
802 Excuse excuseFor(JavacCompiler compiler) {
803 return compiler.compliance != ClassFileConstants.JDK1_5 ||
804 compiler.minor != 1600 ? null : this;
805 }
Stephan Herrmannf087af32014-01-04 01:36:05 +0100806 }: null;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +0000807 }
808}
809
810// PREMATURE: Logger helps us monitor processes outputs (standard and error);
811// some asynchronous mechanism is needed here since not consuming
812// the streams fast enough can result into bad behaviors (as
813// documented in Process); however, we could have a single worker
814// take care of this
815 static class Logger extends Thread {
816 StringBuffer buffer;
817 InputStream inputStream;
818 String type;
819 Logger(InputStream inputStream, String type) {
820 this.inputStream = inputStream;
821 this.type = type;
822 this.buffer = new StringBuffer();
823 }
824 Logger(InputStream inputStream, String type, StringBuffer buffer) {
825 this.inputStream = inputStream;
826 this.type = type;
827 this.buffer = buffer;
828 }
829
830 public void run() {
831 try {
832 BufferedReader reader = new BufferedReader(new InputStreamReader(this.inputStream));
833 String line = null;
834 while ((line = reader.readLine()) != null) {
835 this.buffer./*append(this.type).append("->").*/append(line).append("\n");
836 }
837 reader.close();
838 } catch (IOException e) {
839 e.printStackTrace();
840 }
841 }
842 }
843 protected static int[] DIFF_COUNTERS = new int[3];
844 protected static final String EVAL_DIRECTORY = Util.getOutputDirectory() + File.separator + "eval";
845 public static int INDENT = 2;
846 protected static final String JAVA_NAME =
847 File.pathSeparatorChar == ':' ? "java" : "java.exe";
848 protected static final String JAVAC_NAME =
849 File.pathSeparatorChar == ':' ? "javac" : "javac.exe";
850
851 protected static String JAVAC_OUTPUT_DIR_NAME =
852 Util.getOutputDirectory() + File.separator + "javac";
853 static File JAVAC_OUTPUT_DIR;
854 protected static String javacCommandLineHeader;
855 protected static PrintWriter javacFullLog;
856 // flags errors so that any error in a test case prevents
857 // java execution
858 private static String javacFullLogFileName;
859 protected static String javaCommandLineHeader;
860
861 // needed for multiple test calls within a single test method
862 protected static boolean javacTestErrorFlag;
863
864 protected static String javacTestName;
865
866 protected static IPath jdkRootDirPath;
867
868 // list of available javac compilers, as defined by the jdk.roots
869 // variable, which should hold a File.pathSeparatorChar separated
870 // list of paths for to-be-tested JDK root directories
871 protected static List javacCompilers = null;
872
873 public static final String OUTPUT_DIR = Util.getOutputDirectory() + File.separator + "regression";
874 public static final String LIB_DIR = Util.getOutputDirectory() + File.separator + "lib";
875
876 public final static String PACKAGE_INFO_NAME = new String(TypeConstants.PACKAGE_INFO_NAME);
877
878 public static boolean SHIFT = false;
879
880 protected static final String SOURCE_DIRECTORY = Util.getOutputDirectory() + File.separator + "source";
881
882 protected String[] classpaths;
883 protected boolean createdVerifier;
884 protected INameEnvironment javaClassLib;
885 protected TestVerifier verifier;
886 public AbstractRegressionTest(String name) {
887 super(name);
888 }
889 protected void checkClassFile(String className, String source, String expectedOutput) throws ClassFormatException, IOException {
890 this.checkClassFile("", className, source, expectedOutput, ClassFileBytesDisassembler.SYSTEM);
891 }
892 protected void checkClassFile(String className, String source, String expectedOutput, int mode) throws ClassFormatException, IOException {
893 this.checkClassFile("", className, source, expectedOutput, mode);
894 }
895 protected void checkClassFile(String directoryName, String className, String disassembledClassName, String source, String expectedOutput, int mode) throws ClassFormatException, IOException {
896 compileAndDeploy(source, directoryName, className);
897 try {
898 File directory = new File(EVAL_DIRECTORY, directoryName);
899 if (!directory.exists()) {
900 assertTrue(".class file not generated properly in " + directory, false);
901 }
902 File f = new File(directory, disassembledClassName + ".class");
903 byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
904 ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
905 String result = disassembler.disassemble(classFileBytes, "\n", mode);
906 int index = result.indexOf(expectedOutput);
907 if (index == -1 || expectedOutput.length() == 0) {
908 System.out.println(Util.displayString(result, 3));
909 }
910 if (index == -1) {
911 assertEquals("Wrong contents", expectedOutput, result);
912 }
913 FileInputStream stream = null;
914 try {
915 stream = new FileInputStream(f);
916 ClassFileReader.read(stream, className + ".class", true);
917 } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
918 e.printStackTrace();
919 assertTrue("ClassFormatException", false);
920 } catch (IOException e) {
921 e.printStackTrace();
922 assertTrue("IOException", false);
923 } finally {
924 if (stream != null) {
925 try {
926 stream.close();
927 } catch (IOException e) {
928 /* ignore */
929 }
930 }
931 }
932 } finally {
933 removeTempClass(className);
934 }
935 }
936
937 protected void checkClassFile(String directoryName, String className, String source, String expectedOutput, int mode) throws ClassFormatException, IOException {
938 this.checkClassFile(directoryName, className, className, source, expectedOutput, mode);
939 }
940
941 protected ClassFileReader getInternalClassFile(String directoryName, String className, String disassembledClassName, String source) throws ClassFormatException, IOException {
942 compileAndDeploy(source, directoryName, className);
943 try {
944 File directory = new File(EVAL_DIRECTORY, directoryName);
945 if (!directory.exists()) {
946 assertTrue(".class file not generated properly in " + directory, false);
947 }
948 File f = new File(directory, disassembledClassName + ".class");
949 ClassFileReader classFileReader = null;
950 FileInputStream stream = null;
951 try {
952 stream = new FileInputStream(f);
953 classFileReader = ClassFileReader.read(stream, className + ".class", true);
954 } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
955 e.printStackTrace();
956 assertTrue("ClassFormatException", false);
957 } catch (IOException e) {
958 e.printStackTrace();
959 assertTrue("IOException", false);
960 } finally {
961 if (stream != null) {
962 try {
963 stream.close();
964 } catch (IOException e) {
965 /* ignore */
966 }
967 }
968 }
969 return classFileReader;
970 } finally {
971 removeTempClass(className);
972 }
973 }
974
975 protected void checkDisassembledClassFile(String fileName, String className, String expectedOutput) throws Exception {
976 this.checkDisassembledClassFile(fileName, className, expectedOutput, ClassFileBytesDisassembler.DETAILED);
977 }
978 protected void checkDisassembledClassFile(String fileName, String className, String expectedOutput, int mode) throws Exception {
979 File classFile = new File(fileName);
980 if (!classFile.exists()) {
981 assertTrue(".class file doesn't exist", false);
982 }
983 byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(classFile);
984 ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
985 String result = disassembler.disassemble(classFileBytes, "\n", mode);
986 int index = result.indexOf(expectedOutput);
987 if (index == -1 || expectedOutput.length() == 0) {
988 System.out.println(Util.displayString(result, 2));
989 }
990 if (index == -1) {
991 assertEquals("Wrong contents", expectedOutput, result);
992 }
993 FileInputStream stream = null;
994 try {
995 stream = new FileInputStream(classFile);
996 ClassFileReader.read(stream, className + ".class", true);
997 } finally {
998 if (stream != null) {
999 try {
1000 stream.close();
1001 } catch (IOException e) {
1002 /* ignore */
1003 }
1004 }
1005 }
1006 }
1007
1008 protected void compileAndDeploy(String source, String directoryName, String className) {
1009 File directory = new File(SOURCE_DIRECTORY);
1010 if (!directory.exists()) {
1011 if (!directory.mkdirs()) {
1012 System.out.println("Could not create " + SOURCE_DIRECTORY);
1013 return;
1014 }
1015 }
1016 if (directoryName != null && directoryName.length() != 0) {
1017 directory = new File(SOURCE_DIRECTORY, directoryName);
1018 if (!directory.exists()) {
1019 if (!directory.mkdirs()) {
1020 System.out.println("Could not create " + directory);
1021 return;
1022 }
1023 }
1024 }
1025 String fileName = directory.getAbsolutePath() + File.separator + className + ".java";
1026 try {
1027 BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
1028 writer.write(source);
1029 writer.flush();
1030 writer.close();
1031 } catch (IOException e) {
1032 e.printStackTrace();
1033 return;
1034 }
1035 StringBuffer buffer = new StringBuffer()
1036 .append("\"")
1037 .append(fileName)
1038 .append("\" -d \"")
1039 .append(EVAL_DIRECTORY);
1040 if (this.complianceLevel < ClassFileConstants.JDK1_5) {
1041 buffer.append("\" -1.4 -source 1.3 -target 1.2");
1042 } else if (this.complianceLevel == ClassFileConstants.JDK1_5) {
1043 buffer.append("\" -1.5");
1044 } else if (this.complianceLevel == ClassFileConstants.JDK1_6) {
Stephan Herrmann0717d572010-04-21 22:04:13 +00001045 buffer.append("\" -1.6 -proc:none");
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001046 } else if (this.complianceLevel == ClassFileConstants.JDK1_7) {
Stephan Herrmann0717d572010-04-21 22:04:13 +00001047 buffer.append("\" -1.7 -proc:none");
Stephan Herrmann5fa7f312012-07-13 01:52:51 +02001048 } else if (this.complianceLevel == ClassFileConstants.JDK1_8) {
1049 buffer.append("\" -1.8 -proc:none");
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001050 }
1051 buffer
1052 .append(" -preserveAllLocals -nowarn -g -classpath \"")
1053 .append(Util.getJavaClassLibsAsString())
1054 .append(SOURCE_DIRECTORY)
1055 .append("\"");
1056 BatchCompiler.compile(buffer.toString(), new PrintWriter(System.out), new PrintWriter(System.err), null/*progress*/);
1057 }
1058
1059 /*
1060 * Compute the problem log from given requestor and compare the result to
1061 * the expected one.
1062 * When there's a difference, display the expected output in the console as
1063 * code string to allow easy copy/paste in the test to fix the failure.
1064 * Also write test files to the console output.
1065 * Fail if exception is non null.
1066 */
1067 protected void checkCompilerLog(String[] testFiles, Requestor requestor,
Stephan Herrmann4d079452014-03-27 18:01:49 +01001068 String[] alternatePlatformIndependantExpectedLogs, Throwable exception) {
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001069 String computedProblemLog = Util.convertToIndependantLineDelimiter(requestor.problemLog.toString());
Stephan Herrmann4d079452014-03-27 18:01:49 +01001070 int i;
1071 for (i = 0; i < alternatePlatformIndependantExpectedLogs.length; i++) {
1072 if (alternatePlatformIndependantExpectedLogs[i].equals(computedProblemLog))
1073 return; // OK
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001074 }
Stephan Herrmann4d079452014-03-27 18:01:49 +01001075 logTestTitle();
1076 System.out.println(Util.displayString(computedProblemLog, INDENT, SHIFT));
1077 logTestFiles(false, testFiles);
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001078 if (exception == null) {
Stephan Herrmann4d079452014-03-27 18:01:49 +01001079 assertEquals("Invalid problem log ", alternatePlatformIndependantExpectedLogs[i-1], computedProblemLog);
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001080 }
1081 }
1082
1083 protected void dualPrintln(String message) {
1084 System.out.println(message);
1085 javacFullLog.println(message);
1086 }
1087 protected void executeClass(
1088 String sourceFile,
1089 String expectedSuccessOutputString,
1090 String[] classLib,
1091 boolean shouldFlushOutputDirectory,
1092 String[] vmArguments,
1093 Map customOptions,
1094 ICompilerRequestor clientRequestor) {
1095
1096 // Compute class name by removing ".java" and replacing slashes with dots
1097 String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.');
1098 if (className.endsWith(PACKAGE_INFO_NAME)) return;
1099
1100 if (vmArguments != null) {
1101 if (this.verifier != null) {
1102 this.verifier.shutDown();
1103 }
1104 this.verifier = new TestVerifier(false);
1105 this.createdVerifier = true;
1106 }
1107 boolean passed =
1108 this.verifier.verifyClassFiles(
1109 sourceFile,
1110 className,
1111 expectedSuccessOutputString,
1112 this.classpaths,
1113 null,
1114 vmArguments);
1115 assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action
1116 passed);
1117 if (vmArguments != null) {
1118 if (this.verifier != null) {
1119 this.verifier.shutDown();
1120 }
1121 this.verifier = new TestVerifier(false);
1122 this.createdVerifier = true;
1123 }
1124 }
1125
1126 /*
1127 * Returns the references in the given .class file.
1128 */
1129 protected String findReferences(String classFilePath) {
1130 // check that "new Z().init()" is bound to "AbstractB.init()"
1131 final StringBuffer references = new StringBuffer(10);
1132 final SearchParticipant participant = new JavaSearchParticipant() {
1133 final SearchParticipant searchParticipant = this;
1134 public SearchDocument getDocument(final String documentPath) {
1135 return new SearchDocument(documentPath, this.searchParticipant) {
1136 public byte[] getByteContents() {
1137 try {
1138 return org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(getPath()));
1139 } catch (IOException e) {
1140 e.printStackTrace();
1141 return null;
1142 }
1143 }
1144 public char[] getCharContents() {
1145 // not used
1146 return null;
1147 }
1148 public String getEncoding() {
1149 // not used
1150 return null;
1151 }
1152 };
1153 }
1154 };
1155 SearchDocument document = participant.getDocument(new File(classFilePath).getPath());
1156 BinaryIndexer indexer = new BinaryIndexer(document) {
1157 protected void addIndexEntry(char[] category, char[] key) {
1158 references.append(category);
1159 references.append('/');
1160 references.append(key);
1161 references.append('\n');
1162 }
1163 };
1164 indexer.indexDocument();
1165 String computedReferences = references.toString();
1166 return computedReferences;
1167 }
1168
1169 protected ClassFileReader getClassFileReader(String fileName, String className) {
1170 File classFile = new File(fileName);
1171 if (!classFile.exists()) {
1172 assertTrue(".class file doesn't exist", false);
1173 }
1174 FileInputStream stream = null;
1175 try {
1176 stream = new FileInputStream(classFile);
1177 ClassFileReader reader = ClassFileReader.read(stream, className + ".class", true);
1178 return reader;
1179 } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
1180 e.printStackTrace();
1181 assertTrue("ClassFormatException", false);
1182 } catch (IOException e) {
1183 e.printStackTrace();
1184 assertTrue("IOException", false);
1185 } finally {
1186 if (stream != null) {
1187 try {
1188 stream.close();
1189 } catch (IOException e) {
1190 /* ignore */
1191 }
1192 }
1193 }
1194 return null;
1195 }
1196
Stephan Herrmann618f6922012-08-10 22:00:05 +02001197 protected INameEnvironment[] getClassLibs(boolean useDefaultClasspaths) {
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001198 String encoding = (String)getCompilerOptions().get(CompilerOptions.OPTION_Encoding);
1199 if ("".equals(encoding))
1200 encoding = null;
Stephan Herrmann618f6922012-08-10 22:00:05 +02001201 if (useDefaultClasspaths && encoding == null)
1202 return DefaultJavaRuntimeEnvironment.create(this.classpaths);
1203 // fall back to FileSystem
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001204 INameEnvironment[] classLibs = new INameEnvironment[1];
1205 classLibs[0] = new FileSystem(this.classpaths, new String[]{}, // ignore initial file names
1206 encoding // default encoding
1207 );
1208 return classLibs;
1209 }
1210 protected Map getCompilerOptions() {
1211 Map defaultOptions = super.getCompilerOptions();
1212 defaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
1213 defaultOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.WARNING);
1214 defaultOptions.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.WARNING);
1215 defaultOptions.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.WARNING);
1216 defaultOptions.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.WARNING);
1217 defaultOptions.put(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, CompilerOptions.WARNING);
1218 defaultOptions.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.WARNING);
1219 defaultOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
1220 defaultOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.WARNING );
1221 defaultOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
1222//{ObjectTeams: try to let our keywords not interfere with pure Java tests:
1223 defaultOptions.put(CompilerOptions.OPTION_AllowScopedKeywords, CompilerOptions.ENABLED);
1224// SH}
1225 return defaultOptions;
1226 }
1227
1228 protected String[] getDefaultClassPaths() {
Stephan Herrmann618f6922012-08-10 22:00:05 +02001229 return DefaultJavaRuntimeEnvironment.getDefaultClassPaths();
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001230 }
Stephan Herrmann7c411a02013-12-29 14:47:52 +01001231 /** Get class library paths built from default class paths plus the JDT null annotations. */
Stephan Herrmannaaa73af2013-12-29 16:34:59 +01001232 protected String[] getLibsWithNullAnnotations(long sourceLevel) throws IOException {
Stephan Herrmann7c411a02013-12-29 14:47:52 +01001233 String[] defaultLibs = getDefaultClassPaths();
1234 int len = defaultLibs.length;
1235 String[] libs = new String[len+1];
1236 System.arraycopy(defaultLibs, 0, libs, 0, len);
Stephan Herrmannaaa73af2013-12-29 16:34:59 +01001237 String version = sourceLevel < ClassFileConstants.JDK1_8 ? "[1.1.0,2.0.0)" : "[2.0.0,3.0.0)";
1238 Bundle[] bundles = Platform.getBundles("org.eclipse.jdt.annotation", version);
1239 File bundleFile = FileLocator.getBundleFile(bundles[0]);
Stephan Herrmann7c411a02013-12-29 14:47:52 +01001240 if (bundleFile.isDirectory())
1241 libs[len] = bundleFile.getPath()+"/bin";
1242 else
1243 libs[len] = bundleFile.getPath();
1244 return libs;
1245 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001246 protected IErrorHandlingPolicy getErrorHandlingPolicy() {
1247 return new IErrorHandlingPolicy() {
1248 public boolean stopOnFirstError() {
1249 return false;
1250 }
1251 public boolean proceedOnErrors() {
1252 return true;
1253 }
Stephan Herrmann307ebe32013-05-02 02:46:05 +02001254 public boolean ignoreAllErrors() {
1255 return false;
1256 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001257 };
1258 }
1259 /*
1260 * Will consider first the source units passed as arguments, then investigate the classpath: jdklib + output dir
1261 */
1262 protected INameEnvironment getNameEnvironment(final String[] testFiles, String[] classPaths) {
1263 this.classpaths = classPaths == null ? getDefaultClassPaths() : classPaths;
Stephan Herrmann618f6922012-08-10 22:00:05 +02001264 return new InMemoryNameEnvironment(testFiles, getClassLibs(classPaths == null));
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001265 }
1266 protected IProblemFactory getProblemFactory() {
1267 return new DefaultProblemFactory(Locale.getDefault());
1268 }
1269
1270 public void initialize(CompilerTestSetup setUp) {
1271 super.initialize(setUp);
1272 if (setUp instanceof RegressionTestSetup) {
1273 RegressionTestSetup regressionTestSetUp = (RegressionTestSetup)setUp;
1274 this.javaClassLib = regressionTestSetUp.javaClassLib;
1275 this.verifier = regressionTestSetUp.verifier;
1276 }
1277 }
1278
1279 void logTestFiles(boolean logTitle, String[] testFiles) {
1280 if (logTitle) {
1281 logTestTitle();
1282 }
1283 for (int i = 0; i < testFiles.length; i += 2) {
1284 System.out.print(testFiles[i]);
1285 System.out.println(" ["); //$NON-NLS-1$
1286 System.out.println(testFiles[i + 1]);
1287 System.out.println("]"); //$NON-NLS-1$
1288 }
1289 }
1290 void logTestTitle() {
1291 System.out.println(getClass().getName() + '#' + getName());
1292 }
1293
1294 /*
1295 * Write given source test files in current output sub-directory.
1296 * Use test name for this sub-directory name (ie. test001, test002, etc...)
1297 */
1298 protected void printFiles(String[] testFiles) {
1299 for (int i=0, length=testFiles.length; i<length; i++) {
1300 System.out.println(testFiles[i++]);
1301 System.out.println(testFiles[i]);
1302 }
1303 System.out.println("");
1304 }
1305 protected void printJavacResultsSummary() {
1306 if (RUN_JAVAC) {
1307 Integer count = (Integer)TESTS_COUNTERS.get(CURRENT_CLASS_NAME);
1308 if (count != null) {
1309 int newCount = count.intValue()-1;
1310 TESTS_COUNTERS.put(CURRENT_CLASS_NAME, new Integer(newCount));
1311 if (newCount == 0) {
1312 if (DIFF_COUNTERS[0]!=0 || DIFF_COUNTERS[1]!=0 || DIFF_COUNTERS[2]!=0) {
1313 dualPrintln("===========================================================================");
1314 dualPrintln("Results summary:");
1315 }
1316 if (DIFF_COUNTERS[0]!=0)
1317 dualPrintln(" - "+DIFF_COUNTERS[0]+" test(s) where Javac found errors/warnings but Eclipse did not");
1318 if (DIFF_COUNTERS[1]!=0)
1319 dualPrintln(" - "+DIFF_COUNTERS[1]+" test(s) where Eclipse found errors/warnings but Javac did not");
1320 if (DIFF_COUNTERS[2]!=0)
1321 dualPrintln(" - "+DIFF_COUNTERS[2]+" test(s) where Eclipse and Javac did not have same output");
1322 System.out.println("\n");
1323 }
1324 }
1325 dualPrintln("\n\nFull results sent to " + javacFullLogFileName);
1326 javacFullLog.flush();
1327 }
1328 }
1329 protected void removeTempClass(String className) {
1330 File dir = new File(SOURCE_DIRECTORY);
1331 String[] fileNames = dir.list();
1332 if (fileNames != null) {
1333 for (int i = 0, max = fileNames.length; i < max; i++) {
1334 if (fileNames[i].indexOf(className) != -1) {
1335 Util.delete(SOURCE_DIRECTORY + File.separator + fileNames[i]);
1336 }
1337 }
1338 }
1339
1340 dir = new File(EVAL_DIRECTORY);
1341 fileNames = dir.list();
1342 if (fileNames != null) {
1343 for (int i = 0, max = fileNames.length; i < max; i++) {
1344 if (fileNames[i].indexOf(className) != -1) {
1345 Util.delete(EVAL_DIRECTORY + File.separator + fileNames[i]);
1346 }
1347 }
1348 }
1349
1350 }
1351
1352// WORK replace null logs (no test) by empty string in most situations (more
1353// complete coverage) and see what happens
1354 protected void runConformTest(String[] testFiles) {
1355 runTest(
1356 // test directory preparation
1357 true /* flush output directory */,
1358 testFiles /* test files */,
1359 // compiler options
1360 null /* no class libraries */,
1361 null /* no custom options */,
1362 false /* do not perform statements recovery */,
1363 null /* no custom requestor */,
1364 // compiler results
1365 false /* expecting no compiler errors */,
1366 null /* do not check compiler log */,
1367 // runtime options
1368 false /* do not force execution */,
1369 null /* no vm arguments */,
1370 // runtime results
1371 null /* do not check output string */,
1372 null /* do not check error string */,
1373 // javac options
1374 JavacTestOptions.DEFAULT /* default javac test options */);
1375 }
1376
1377 // WORK replace null logs (no test) by empty string in most situations (more
1378 // complete coverage) and see what happens
1379 protected void runConformTest(String[] testFiles, ASTVisitor visitor) {
1380 runTest(
1381 // test directory preparation
1382 true /* flush output directory */,
1383 testFiles /* test files */,
Stephan Herrmannde4efa92010-09-26 16:11:28 +00001384 new String[] {},
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001385 // compiler options
1386 null /* no class libraries */,
1387 null /* no custom options */,
1388 false /* do not perform statements recovery */,
1389 null /* no custom requestor */,
1390 // compiler results
1391 false /* expecting no compiler errors */,
1392 null /* do not check compiler log */,
Stephan Herrmann4d079452014-03-27 18:01:49 +01001393 null /* no alternate compiler logs */,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001394 // runtime options
1395 false /* do not force execution */,
1396 null /* no vm arguments */,
1397 // runtime results
1398 null /* do not check output string */,
1399 null /* do not check error string */,
1400 visitor,
1401 // javac options
1402 JavacTestOptions.DEFAULT /* default javac test options */);
1403 }
1404
1405 protected void runConformTest(String[] testFiles, String expectedOutputString) {
1406 runTest(
Stephan Herrmann13a070b2010-04-02 03:54:26 +00001407 // test directory preparation
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001408 true /* flush output directory */,
1409 testFiles /* test files */,
1410 // compiler options
1411 null /* no class libraries */,
1412 null /* no custom options */,
1413 false /* do not perform statements recovery */,
1414 null /* no custom requestor */,
1415 // compiler results
1416 false /* expecting no compiler errors */,
1417 null /* do not check compiler log */,
1418 // runtime options
1419 false /* do not force execution */,
1420 null /* no vm arguments */,
1421 // runtime results
1422 expectedOutputString /* expected output string */,
1423 null /* do not check error string */,
1424 // javac options
1425 JavacTestOptions.DEFAULT /* default javac test options */);
1426 }
Stephan Herrmann396f3342013-03-14 14:31:57 +01001427 protected void runConformTest(String[] testFiles, Map customOptions) {
1428 runTest(
1429 // test directory preparation
1430 true /* flush output directory */,
1431 testFiles /* test files */,
1432 // compiler options
1433 null /* no class libraries */,
1434 customOptions /* no custom options */,
1435 false /* do not perform statements recovery */,
1436 null /* no custom requestor */,
1437 // compiler results
1438 false /* expecting no compiler errors */,
1439 null /* do not check compiler log */,
1440 // runtime options
1441 false /* do not force execution */,
1442 null /* no vm arguments */,
1443 // runtime results
1444 null /* expected output string */,
1445 null /* do not check error string */,
1446 // javac options
1447 JavacTestOptions.DEFAULT /* default javac test options */);
1448 }
Stephan Herrmann31907e22014-01-03 15:27:45 +01001449 protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions) {
1450 runTest(
1451 // test directory preparation
1452 true /* flush output directory */,
1453 testFiles /* test files */,
1454 // compiler options
1455 null /* no class libraries */,
1456 customOptions /* no custom options */,
1457 false /* do not perform statements recovery */,
1458 null /* no custom requestor */,
1459 // compiler results
1460 false /* expecting no compiler errors */,
1461 null /* do not check compiler log */,
1462 // runtime options
1463 false /* do not force execution */,
1464 null /* no vm arguments */,
1465 // runtime results
1466 expectedOutput /* expected output string */,
1467 null /* do not check error string */,
1468 // javac options
1469 JavacTestOptions.DEFAULT /* default javac test options */);
1470 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001471 protected void runConformTest(
Stephan Herrmannde4efa92010-09-26 16:11:28 +00001472 String[] testFiles,
1473 String[] dependantFiles,
1474 String expectedSuccessOutputString) {
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001475 runTest(
Stephan Herrmannde4efa92010-09-26 16:11:28 +00001476 true,
1477 testFiles,
1478 dependantFiles,
1479 null,
1480 null,
1481 false,
1482 null,
1483 false,
1484 null,
Stephan Herrmann4d079452014-03-27 18:01:49 +01001485 null,
Stephan Herrmannde4efa92010-09-26 16:11:28 +00001486 false,
1487 null,
1488 expectedSuccessOutputString,
1489 null,
1490 null,
1491 JavacTestOptions.DEFAULT);
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001492 }
1493
1494 protected void runConformTest(
1495 String[] testFiles,
1496 String expectedOutputString,
1497 String[] classLibraries,
1498 boolean shouldFlushOutputDirectory,
1499 String[] vmArguments) {
1500 runTest(
1501 // test directory preparation
1502 shouldFlushOutputDirectory /* should flush output directory */,
1503 testFiles /* test files */,
1504 // compiler options
1505 classLibraries /* class libraries */,
1506 null /* no custom options */,
1507 false /* do not perform statements recovery */,
1508 null /* no custom requestor */,
1509 // compiler results
1510 false /* expecting no compiler errors */,
1511 null /* do not check compiler log */,
1512 // runtime options
1513 false /* do not force execution */,
1514 vmArguments /* vm arguments */,
1515 // runtime results
1516 expectedOutputString /* expected output string */,
1517 null /* do not check error string */,
1518 // javac options
1519 JavacTestOptions.DEFAULT /* default javac test options */);
1520 }
1521
1522 protected void runConformTest(
1523 String[] testFiles,
1524 String expectedOutputString,
1525 String[] classLibraries,
1526 boolean shouldFlushOutputDirectory,
1527 String[] vmArguments,
1528 Map customOptions,
1529 ICompilerRequestor customRequestor) {
1530 runTest(
1531 // test directory preparation
1532 shouldFlushOutputDirectory /* should flush output directory */,
1533 testFiles /* test files */,
1534 // compiler options
1535 classLibraries /* class libraries */,
1536 customOptions /* custom options */,
1537 false /* do not perform statements recovery */,
1538 customRequestor /* custom requestor */,
1539 // compiler results
1540 false /* expecting no compiler errors */,
1541 null /* do not check compiler log */,
1542 // runtime options
1543 false /* do not force execution */,
1544 vmArguments /* vm arguments */,
1545 // runtime results
1546 expectedOutputString /* expected output string */,
1547 null /* do not check error string */,
1548 // javac options
1549 JavacTestOptions.DEFAULT /* default javac test options */);
1550 }
1551
1552 // WORK good candidate for elimination (8 instances)
1553 protected void runConformTest(
1554 String[] testFiles,
1555 String expectedSuccessOutputString,
1556 String[] classLib,
1557 boolean shouldFlushOutputDirectory,
1558 String[] vmArguments,
1559 Map customOptions,
1560 ICompilerRequestor clientRequestor,
1561 boolean skipJavac) {
1562 runTest(
1563 shouldFlushOutputDirectory,
1564 testFiles,
1565 classLib,
1566 customOptions,
1567 false /* do not perform statements recovery */,
1568 clientRequestor,
1569 false,
1570 null,
1571 false,
1572 vmArguments,
1573 expectedSuccessOutputString,
1574 null,
1575 (skipJavac ?
1576 JavacTestOptions.SKIP :
1577 JavacTestOptions.DEFAULT));
1578 }
1579
1580 /*
1581 * Run Sun compilation using javac.
1582 * Launch compilation in a thread and verify that it does not take more than 5s
1583 * to perform it. Otherwise abort the process and log in console.
1584 * TODO (maxime) not sure we really do that 5s cap any more.
1585 * A semi verbose output is sent to the console that analyzes differences
1586 * of behaviors between javac and Eclipse on a per test basis. A more
1587 * verbose output is produced into a file which name is printed on the
1588 * console. Such files can be compared between various javac releases
1589 * to check potential changes.
1590 * To enable such tests, specify the following VM properies in the launch
1591 * configuration:
1592 * -Drun.javac=enabled
1593 * mandatory - tells the test suite to run javac tests
1594 * -Djdk.root=<the root directory of the tested javac>
1595 * optional - enables to find the javac that will be run by the tests
1596 * suite; the root directory must be specified as an absolute path and
1597 * should point to the JDK root, aka /opt/jdk1.5.0_05 for Linux or
1598 * c:/JDK_50 for Windows; in case this property is not specified, the
1599 * tests suite will use the runtime JRE of the launching configuration.
1600 * Note that enabling javac tests implies running into 1.5 compliance level
1601 * (or higher).
1602 */
1603 protected void runJavac(
1604 String[] testFiles,
1605 final String expectedProblemLog,
1606 final String expectedSuccessOutputString,
1607 boolean shouldFlushOutputDirectory) {
1608 String testName = null;
1609 Process compileProcess = null;
1610 Process execProcess = null;
1611 try {
1612 // Init test name
1613 testName = testName();
1614
1615 // Cleanup javac output dir if needed
1616 File javacOutputDirectory = new File(JAVAC_OUTPUT_DIR_NAME);
1617 if (shouldFlushOutputDirectory) {
1618 Util.delete(javacOutputDirectory);
1619 }
1620
1621 // Write files in dir
1622 writeFiles(testFiles);
1623
1624 // Prepare command line
1625 StringBuffer cmdLine = new StringBuffer(javacCommandLineHeader);
1626 // compute extra classpath
1627 String[] classpath = Util.concatWithClassLibs(JAVAC_OUTPUT_DIR_NAME, false);
1628 StringBuffer cp = new StringBuffer(" -classpath ");
1629 int length = classpath.length;
1630 for (int i = 0; i < length; i++) {
1631 if (i > 0)
1632 cp.append(File.pathSeparatorChar);
1633 if (classpath[i].indexOf(" ") != -1) {
1634 cp.append("\"" + classpath[i] + "\"");
1635 } else {
1636 cp.append(classpath[i]);
1637 }
1638 }
1639 cmdLine.append(cp);
1640 // add source files
1641 for (int i = 0; i < testFiles.length; i += 2) {
1642 // *.java is not enough (p1/X.java, p2/Y.java)
1643 cmdLine.append(' ');
1644 cmdLine.append(testFiles[i]);
1645 }
1646
1647 // Launch process
1648 compileProcess = Runtime.getRuntime().exec(
1649 cmdLine.toString(), null, this.outputTestDirectory);
1650
1651 // Log errors
1652 Logger errorLogger = new Logger(compileProcess.getErrorStream(), "ERROR");
1653
1654 // Log output
1655 Logger outputLogger = new Logger(compileProcess.getInputStream(), "OUTPUT");
1656
1657 // start the threads to run outputs (standard/error)
1658 errorLogger.start();
1659 outputLogger.start();
1660
1661 // Wait for end of process
1662 int exitValue = compileProcess.waitFor();
1663 errorLogger.join(); // make sure we get the whole output
1664 outputLogger.join();
1665
1666 // Report raw javac results
1667 if (! testName.equals(javacTestName)) {
1668 javacTestName = testName;
1669 javacTestErrorFlag = false;
1670 javacFullLog.println("-----------------------------------------------------------------");
1671 javacFullLog.println(CURRENT_CLASS_NAME + " " + testName);
1672 }
1673 if (exitValue != 0) {
1674 javacTestErrorFlag = true;
1675 }
1676 if (errorLogger.buffer.length() > 0) {
1677 javacFullLog.println("--- javac err: ---");
1678 javacFullLog.println(errorLogger.buffer.toString());
1679 }
1680 if (outputLogger.buffer.length() > 0) {
1681 javacFullLog.println("--- javac out: ---");
1682 javacFullLog.println(outputLogger.buffer.toString());
1683 }
1684
1685 // Compare compilation results
1686 if (expectedProblemLog == null || expectedProblemLog.length() == 0) {
1687 // Eclipse found no error and no warning
1688 if (exitValue != 0) {
1689 // Javac found errors
1690 System.out.println("----------------------------------------");
1691 System.out.println(testName + " - Javac has found error(s) but Eclipse expects conform result:\n");
1692 javacFullLog.println("JAVAC_MISMATCH: Javac has found error(s) but Eclipse expects conform result");
1693 System.out.println(errorLogger.buffer.toString());
1694 printFiles(testFiles);
1695 DIFF_COUNTERS[0]++;
1696 }
1697 else {
1698 // Javac found no error - may have found warnings
1699 if (errorLogger.buffer.length() > 0) {
1700 System.out.println("----------------------------------------");
1701 System.out.println(testName + " - Javac has found warning(s) but Eclipse expects conform result:\n");
1702 javacFullLog.println("JAVAC_MISMATCH: Javac has found warning(s) but Eclipse expects conform result");
1703 System.out.println(errorLogger.buffer.toString());
1704 printFiles(testFiles);
1705 DIFF_COUNTERS[0]++;
1706 }
1707 if (expectedSuccessOutputString != null && !javacTestErrorFlag) {
1708 // Neither Eclipse nor Javac found errors, and we have a runtime
1709 // bench value
1710 StringBuffer javaCmdLine = new StringBuffer(javaCommandLineHeader);
1711 javaCmdLine.append(cp);
1712 javaCmdLine.append(' ').append(testFiles[0].substring(0, testFiles[0].indexOf('.')));
1713 // assume executable class is name of first test file - PREMATURE check if this is also the case in other test fwk classes
1714 execProcess = Runtime.getRuntime().exec(javaCmdLine.toString(), null, this.outputTestDirectory);
1715 Logger logger = new Logger(execProcess.getInputStream(), "");
1716 // PREMATURE implement consistent error policy
1717 logger.start();
1718 exitValue = execProcess.waitFor();
1719 logger.join(); // make sure we get the whole output
1720 String javaOutput = logger.buffer.toString().trim();
1721 if (!expectedSuccessOutputString.equals(javaOutput)) {
1722 System.out.println("----------------------------------------");
1723 System.out.println(testName + " - Javac and Eclipse runtime output is not the same:");
1724 javacFullLog.println("JAVAC_MISMATCH: Javac and Eclipse runtime output is not the same");
1725 dualPrintln("eclipse:");
1726 dualPrintln(expectedSuccessOutputString);
1727 dualPrintln("javac:");
1728 dualPrintln(javaOutput);
1729 System.out.println("\n");
1730 printFiles(testFiles); // PREMATURE consider printing files to the log as well
1731 DIFF_COUNTERS[2]++;
1732 }
1733 }
1734 }
1735 }
1736 else {
1737 // Eclipse found errors or warnings
1738 if (errorLogger.buffer.length() == 0) {
1739 System.out.println("----------------------------------------");
1740 System.out.println(testName + " - Eclipse has found error(s)/warning(s) but Javac did not find any:");
1741 javacFullLog.println("JAVAC_MISMATCH: Eclipse has found error(s)/warning(s) but Javac did not find any");
1742 dualPrintln("eclipse:");
1743 dualPrintln(expectedProblemLog);
1744 printFiles(testFiles);
1745 DIFF_COUNTERS[1]++;
1746 } else if (expectedProblemLog.indexOf("ERROR") > 0 && exitValue == 0){
1747 System.out.println("----------------------------------------");
1748 System.out.println(testName + " - Eclipse has found error(s) but Javac only found warning(s):");
1749 javacFullLog.println("JAVAC_MISMATCH: Eclipse has found error(s) but Javac only found warning(s)");
1750 dualPrintln("eclipse:");
1751 dualPrintln(expectedProblemLog);
1752 System.out.println("javac:");
1753 System.out.println(errorLogger.buffer.toString());
1754 printFiles(testFiles);
1755 DIFF_COUNTERS[1]++;
1756 } else {
1757 // PREMATURE refine comparison
1758 // TODO (frederic) compare warnings in each result and verify they are similar...
1759// System.out.println(testName+": javac has found warnings :");
1760// System.out.print(errorLogger.buffer.toString());
1761// System.out.println(testName+": we're expecting warning results:");
1762// System.out.println(expectedProblemLog);
1763 }
1764 }
1765 }
1766 catch (InterruptedException e1) {
1767 if (compileProcess != null) compileProcess.destroy();
1768 if (execProcess != null) execProcess.destroy();
1769 System.out.println(testName+": Sun javac compilation was aborted!");
1770 javacFullLog.println("JAVAC_WARNING: Sun javac compilation was aborted!");
1771 e1.printStackTrace(javacFullLog);
1772 }
1773 catch (Throwable e) {
1774 System.out.println(testName+": could not launch Sun javac compilation!");
1775 e.printStackTrace();
1776 javacFullLog.println("JAVAC_ERROR: could not launch Sun javac compilation!");
1777 e.printStackTrace(javacFullLog);
1778 // PREMATURE failing the javac pass or comparison could also fail
1779 // the test itself
1780 }
1781 finally {
1782 // Clean up written file(s)
1783 Util.delete(this.outputTestDirectory);
1784 }
1785 }
1786 // WORK factorize all runJavac implementations, including overrides
1787 protected boolean runJavac(String options, String[] testFileNames, String currentDirectoryPath) {
1788 Process compileProcess = null;
1789 try {
1790 // Prepare command line
1791 StringBuffer cmdLine = new StringBuffer(javacCommandLineHeader);
1792 cmdLine.append(' ');
1793 cmdLine.append(options);
1794 // add source files
1795 for (int i = 0; i < testFileNames.length; i ++) {
1796 // *.java is not enough (p1/X.java, p2/Y.java)
1797 cmdLine.append(' ');
1798 cmdLine.append(testFileNames[i]);
1799 }
1800 // Launch process
1801 File currentDirectory = new File(currentDirectoryPath);
1802 compileProcess = Runtime.getRuntime().exec(
1803 cmdLine.toString(), null, currentDirectory);
1804
1805 // Log errors
1806 Logger errorLogger = new Logger(compileProcess.getErrorStream(), "ERROR");
1807 errorLogger.start();
1808
1809 // Wait for end of process
1810 int exitValue = compileProcess.waitFor();
1811 errorLogger.join(); // make sure we get the whole output
1812
1813 // Check results
1814 if (exitValue != 0) {
1815 return false;
1816 }
1817 if (errorLogger.buffer.length() > 0) {
1818 System.err.println("--- javac err: ---");
1819 System.err.println(errorLogger.buffer.toString());
1820 return false;
1821 }
1822 }
1823 catch (Throwable e) {
1824 e.printStackTrace(System.err);
1825 }
1826 finally {
1827 if (compileProcess != null) {
1828 compileProcess.destroy(); // closes process streams
1829 }
1830 }
1831 return true;
1832 }
1833/*
1834 * Run Sun compilation using one or more versions of javac. Compare the
1835 * results to expected ones, raising mismatches as needed.
1836 * To enable such tests, specify the following VM properies in the launch
1837 * configuration:
1838 * -Drun.javac=enabled
1839 * mandatory - tells the test suite to run javac tests
1840 * -Djdk.roots=<the root directories of the tested javac(s)>
1841 * optional - enables to find the versions of javac that will be run by
1842 * the tests suite; the root directories must be specified as a
1843 * File.pathSeparator separated list of absolute paths which should
1844 * point each to a JDK root, aka /opt/jdk1.5.0_05 for Linux or
1845 * c:/JDK_50 for Windows; in case this property is not specified, the
1846 * tests suite will use the runtime JRE of the launching configuration.
1847 * Note that enabling javac tests implies running into 1.5 compliance level
1848 * (or higher).
1849 */
1850// WORK unify use of output, error, log, etc...
1851protected void runJavac(
1852 String[] testFiles,
1853 boolean expectingCompilerErrors,
1854 String expectedCompilerLog,
1855 String expectedOutputString,
1856 String expectedErrorString,
1857 boolean shouldFlushOutputDirectory,
1858 JavacTestOptions options,
1859 String[] vmArguments) {
1860 // WORK we're probably doing too much around class libraries in general - java should be able to fetch its own runtime libs
1861 // WORK reorder parameters
1862 if (options == JavacTestOptions.SKIP) {
1863 return;
1864 }
Stephan Herrmann4d079452014-03-27 18:01:49 +01001865 if (options == null) {
1866 options = JavacTestOptions.DEFAULT;
1867 }
1868 String newOptions = options.getCompilerOptions();
1869 if (newOptions.indexOf(" -d ") < 0) {
1870 options.setCompilerOptions(newOptions.concat(" -d ."));
1871 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001872 String testName = testName();
1873 Iterator compilers = javacCompilers.iterator();
1874 while (compilers.hasNext()) {
1875 JavacCompiler compiler = (JavacCompiler) compilers.next();
1876 if (!options.skip(compiler) && compiler.compliance == this.complianceLevel) {
1877 // WORK this may exclude some compilers under some conditions (when
1878 // complianceLevel is not set); consider accepting the compiler
1879 // in such case and see what happens
1880 JavacTestOptions.Excuse excuse = options.excuseFor(compiler);
1881 StringBuffer compilerLog = new StringBuffer();
1882 File javacOutputDirectory = null;
1883 int mismatch = 0;
1884 String sourceFileNames[] = null;
1885 try {
1886 // cleanup javac output dir if needed
1887 javacOutputDirectory = new File(JAVAC_OUTPUT_DIR_NAME +
1888 File.separator + compiler.rawVersion); // need to change output directory per javac version
1889 if (shouldFlushOutputDirectory) {
1890 Util.delete(javacOutputDirectory);
1891 }
1892 javacOutputDirectory.mkdirs();
1893 // write test files
1894 for (int i = 0, length = testFiles.length; i < length; ) {
1895 String fileName = testFiles[i++];
1896 String contents = testFiles[i++];
1897 File file = new File(javacOutputDirectory, fileName);
1898 if (fileName.lastIndexOf('/') >= 0) {
1899 File dir = file.getParentFile();
1900 if (!dir.exists()) {
1901 dir.mkdirs();
1902 }
1903 }
1904 Util.writeToFile(contents, file.getPath());
1905 }
1906 // compute source file names
1907 int testFilesLength = testFiles.length;
1908 sourceFileNames = new String[testFilesLength / 2];
1909 for (int i = 0, j = 0; i < testFilesLength; i += 2, j++) {
1910 sourceFileNames[j] = testFiles[i];
1911 }
1912 // compile
1913 long compilerResult = compiler.compile(javacOutputDirectory, options.getCompilerOptions() /* options */, sourceFileNames, compilerLog);
1914 // check cumulative javac results
1915 // WORK need to use a per compiler approach
1916 if (! testName.equals(javacTestName)) {
1917 javacTestName = testName;
1918 javacTestErrorFlag = false;
1919 }
1920 if ((compilerResult & JavacCompiler.EXIT_VALUE_MASK) != 0) {
1921 javacTestErrorFlag = true;
1922 }
1923 // compare compilation results
1924 if (expectingCompilerErrors) {
1925 if ((compilerResult & JavacCompiler.EXIT_VALUE_MASK) == 0) {
1926 if ((compilerResult & JavacCompiler.ERROR_LOG_MASK) == 0) {
1927 mismatch = JavacTestOptions.MismatchType.EclipseErrorsJavacNone;
1928 } else {
1929 mismatch = JavacTestOptions.MismatchType.EclipseErrorsJavacWarnings;
1930 }
1931 }
1932 } else {
1933 if ((compilerResult & JavacCompiler.EXIT_VALUE_MASK) != 0) {
1934 if (expectedCompilerLog != null /* null skips warnings test */ && expectedCompilerLog.length() > 0) {
1935 mismatch = JavacTestOptions.MismatchType.JavacErrorsEclipseWarnings;
1936 } else {
1937 mismatch = JavacTestOptions.MismatchType.JavacErrorsEclipseNone;
1938 }
1939 } else if (expectedCompilerLog != null /* null skips warnings test */) {
1940 if (expectedCompilerLog.length() > 0 && (compilerResult & JavacCompiler.ERROR_LOG_MASK) == 0) {
1941 mismatch = JavacTestOptions.MismatchType.EclipseWarningsJavacNone;
1942 } else if (expectedCompilerLog.length() == 0 && (compilerResult & JavacCompiler.ERROR_LOG_MASK) != 0) {
1943 mismatch = JavacTestOptions.MismatchType.JavacWarningsEclipseNone;
1944 }
1945 }
1946 }
1947 }
1948 catch (InterruptedException e1) {
1949 e1.printStackTrace();
1950 mismatch = JavacTestOptions.MismatchType.JavacAborted;
1951 }
1952 catch (Throwable e) {
1953 e.printStackTrace();
1954 mismatch = JavacTestOptions.MismatchType.JavacNotLaunched;
1955 }
1956 String output = null;
1957 String err = null;
1958 try {
1959 if ((expectedOutputString != null || expectedErrorString != null) &&
1960 !javacTestErrorFlag && mismatch == 0 && sourceFileNames != null) {
1961 JavaRuntime runtime = JavaRuntime.runtimeFor(compiler);
1962 StringBuffer stderr = new StringBuffer();
1963 StringBuffer stdout = new StringBuffer();
1964 String vmOptions = "";
1965 if (vmArguments != null) {
1966 int l = vmArguments.length;
1967 if (l > 0) {
1968 StringBuffer buffer = new StringBuffer(vmArguments[0]);
1969 for (int i = 1; i < l; i++) {
1970 buffer.append(' ');
1971 buffer.append(vmArguments[i]);
1972 }
1973 vmOptions = buffer.toString();
1974 }
1975 }
1976 runtime.execute(javacOutputDirectory, vmOptions, testFiles[0].substring(0, testFiles[0].length() - 5), stdout, stderr);
1977 if (expectedOutputString != null /* null skips output test */) {
1978 output = stdout.toString().trim();
1979 if (!expectedOutputString.equals(output)) {
1980 mismatch = JavacTestOptions.MismatchType.StandardOutputMismatch;
1981 }
1982 }
1983 // WORK move to a logic in which if stdout is empty whereas
1984 // it should have had contents, stderr is leveraged as
1985 // potentially holding indications regarding the failure
1986 if (expectedErrorString != null /* null skips error test */ && mismatch == 0) {
1987 err = stderr.toString().trim();
1988 if (!expectedErrorString.equals(err) && // special case: command-line java does not like missing main methods
1989 !(expectedErrorString.length() == 0 &&
Stephan Herrmannc1c48622014-01-04 23:19:31 +01001990 (err.indexOf("java.lang.NoSuchMethodError: main") != -1)
1991 || err.indexOf("Error: Main method not found in class") != -1)) {
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00001992 mismatch = JavacTestOptions.MismatchType.ErrorOutputMismatch;
1993 }
1994 }
1995 }
1996 }
1997 catch (InterruptedException e1) {
1998 e1.printStackTrace();
1999 mismatch = JavacTestOptions.MismatchType.JavaAborted;
2000 }
2001 catch (Throwable e) {
2002 e.printStackTrace();
2003 mismatch = JavacTestOptions.MismatchType.JavaNotLaunched;
2004 }
2005 if (mismatch != 0) {
2006 if (excuse != null && excuse.clears(mismatch)) {
2007 excuse = null;
2008 } else {
2009 System.err.println("----------------------------------------");
2010 logTestFiles(true, testFiles);
2011 switch (mismatch) {
2012 case JavacTestOptions.MismatchType.EclipseErrorsJavacNone:
2013 assertEquals(testName + " - Eclipse found error(s) but Javac did not find any",
2014 "", expectedCompilerLog.toString());
2015 break;
2016 case JavacTestOptions.MismatchType.EclipseErrorsJavacWarnings:
2017 assertEquals(testName + " - Eclipse found error(s) but Javac only found warning(s)",
2018 expectedCompilerLog.toString(), compilerLog.toString());
2019 break;
2020 case JavacTestOptions.MismatchType.JavacErrorsEclipseNone:
2021 assertEquals(testName + " - Javac found error(s) but Eclipse did not find any",
2022 "", compilerLog.toString());
2023 break;
2024 case JavacTestOptions.MismatchType.JavacErrorsEclipseWarnings:
2025 assertEquals(testName + " - Javac found error(s) but Eclipse only found warning(s)",
2026 expectedCompilerLog.toString(), compilerLog.toString());
2027 break;
2028 case JavacTestOptions.MismatchType.EclipseWarningsJavacNone:
2029 assertEquals(testName + " - Eclipse found warning(s) but Javac did not find any",
2030 "", expectedCompilerLog.toString());
2031 break;
2032 case JavacTestOptions.MismatchType.JavacWarningsEclipseNone:
2033 assertEquals(testName + " - Javac found warning(s) but Eclipse did not find any",
2034 "", compilerLog.toString());
2035 break;
2036 case JavacTestOptions.MismatchType.StandardOutputMismatch:
2037 assertEquals(testName + " - Eclipse/Javac standard output mismatch",
2038 expectedOutputString, output);
2039 break;
2040 case JavacTestOptions.MismatchType.ErrorOutputMismatch:
2041 assertEquals(testName + " - Eclipse/Javac standard error mismatch",
2042 expectedErrorString, err);
2043 break;
2044 case JavacTestOptions.MismatchType.JavacAborted:
2045 case JavacTestOptions.MismatchType.JavacNotLaunched:
2046 fail(testName + " - Javac failure");
2047 break;
2048 case JavacTestOptions.MismatchType.JavaAborted:
2049 case JavacTestOptions.MismatchType.JavaNotLaunched:
2050 fail(testName + " - Java failure");
2051 break;
2052 default:
2053 throw new RuntimeException("unexpected mismatch value: " + mismatch);
2054 }
2055 }
2056 }
2057 if (excuse != null) {
2058 fail(testName + ": unused excuse " + excuse + " for compiler " + compiler);
2059 }
2060 }
2061 }
2062}
2063
2064//runNegativeTest(
2065// // test directory preparation
2066// new String[] { /* test files */
2067// },
2068// // compiler results
2069// "" /* expected compiler log */);
2070protected void runNegativeTest(String[] testFiles, String expectedCompilerLog) {
2071 runTest(
2072 // test directory preparation
2073 true /* flush output directory */,
2074 testFiles /* test files */,
2075 // compiler options
2076 null /* no class libraries */,
2077 null /* no custom options */,
2078 false /* do not perform statements recovery */,
2079 new Requestor( /* custom requestor */
2080 false,
2081 null /* no custom requestor */,
2082 false,
2083 false),
2084 // compiler results
2085 expectedCompilerLog == null || /* expecting compiler errors */
2086 expectedCompilerLog.indexOf("ERROR") != -1,
2087 expectedCompilerLog /* expected compiler log */,
2088 // runtime options
2089 false /* do not force execution */,
2090 null /* no vm arguments */,
2091 // runtime results
2092 null /* do not check output string */,
2093 null /* do not check error string */,
2094 // javac options
2095 JavacTestOptions.DEFAULT /* default javac test options */);
2096 }
Stephan Herrmann5fa7f312012-07-13 01:52:51 +02002097protected void runNegativeTest(String[] testFiles, String expectedCompilerLog, boolean performStatementRecovery) {
2098 runTest(
2099 // test directory preparation
2100 true /* flush output directory */,
2101 testFiles /* test files */,
2102 // compiler options
2103 null /* no class libraries */,
2104 null /* no custom options */,
2105 performStatementRecovery,
2106 new Requestor( /* custom requestor */
2107 false,
2108 null /* no custom requestor */,
2109 false,
2110 false),
2111 // compiler results
2112 expectedCompilerLog == null || /* expecting compiler errors */
2113 expectedCompilerLog.indexOf("ERROR") != -1,
2114 expectedCompilerLog /* expected compiler log */,
2115 // runtime options
2116 false /* do not force execution */,
2117 null /* no vm arguments */,
2118 // runtime results
2119 null /* do not check output string */,
2120 null /* do not check error string */,
2121 // javac options
2122 JavacTestOptions.DEFAULT /* default javac test options */);
2123}
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002124 // WORK potential elimination candidate (24 calls) - else clean up inline
2125 protected void runNegativeTest(
2126 String[] testFiles,
2127 String expectedProblemLog,
2128 String[] classLib,
2129 boolean shouldFlushOutputDirectory) {
2130 runTest(
2131 shouldFlushOutputDirectory,
2132 testFiles,
2133 classLib,
2134 null,
2135 false,
2136 new Requestor( /* custom requestor */
2137 false,
2138 null /* no custom requestor */,
2139 false,
2140 false),
2141 // compiler results
2142 expectedProblemLog == null || /* expecting compiler errors */
2143 expectedProblemLog.indexOf("ERROR") != -1,
2144 expectedProblemLog,
2145 // runtime options
2146 false /* do not force execution */,
2147 null /* no vm arguments */,
2148 // runtime results
2149 null /* do not check output string */,
2150 null /* do not check error string */,
2151 // javac options
2152 /* false ?
2153 JavacTestOptions.SKIP :*/
2154 JavacTestOptions.DEFAULT /* javac test options */);
2155 }
2156 protected void runNegativeTest(
2157 String[] testFiles,
2158 String expectedCompilerLog,
2159 String[] classLibraries,
2160 boolean shouldFlushOutputDirectory,
2161 Map customOptions) {
2162 runTest(
2163 // test directory preparation
2164 shouldFlushOutputDirectory /* should flush output directory */,
2165 testFiles /* test files */,
2166 // compiler options
2167 classLibraries /* class libraries */,
2168 customOptions /* custom options */,
2169 false /* do not perform statements recovery */,
2170 new Requestor( /* custom requestor */
2171 false,
2172 null /* no custom requestor */,
2173 false,
2174 false),
2175 // compiler results
2176 expectedCompilerLog == null || /* expecting compiler errors */
2177 expectedCompilerLog.indexOf("ERROR") != -1,
2178 expectedCompilerLog /* expected compiler log */,
2179 // runtime options
2180 false /* do not force execution */,
2181 null /* no vm arguments */,
2182 // runtime results
2183 null /* do not check output string */,
2184 null /* do not check error string */,
2185 // javac options
2186 JavacTestOptions.DEFAULT /* default javac test options */);
2187 }
2188 protected void runNegativeTest(
Stephan Herrmann13a070b2010-04-02 03:54:26 +00002189 String[] testFiles,
2190 String expectedCompilerLog,
2191 String[] classLibraries,
2192 boolean shouldFlushOutputDirectory,
2193 Map customOptions,
2194 String expectedErrorString) {
2195 runTest(
2196 // test directory preparation
2197 shouldFlushOutputDirectory /* should flush output directory */,
2198 testFiles /* test files */,
2199 // compiler options
2200 classLibraries /* class libraries */,
2201 customOptions /* custom options */,
2202 false /* do not perform statements recovery */,
2203 new Requestor( /* custom requestor */
2204 false,
2205 null /* no custom requestor */,
2206 false,
2207 false),
2208 // compiler results
2209 expectedCompilerLog == null || /* expecting compiler errors */
2210 expectedCompilerLog.indexOf("ERROR") != -1,
2211 expectedCompilerLog /* expected compiler log */,
2212 // runtime options
2213 false /* do not force execution */,
2214 null /* no vm arguments */,
2215 // runtime results
2216 null /* do not check output string */,
2217 expectedErrorString /* do not check error string */,
2218 // javac options
2219 JavacTestOptions.DEFAULT /* default javac test options */);
2220 }
2221 protected void runNegativeTest(
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002222 String[] testFiles,
2223 String expectedProblemLog,
2224 String[] classLibraries,
2225 boolean shouldFlushOutputDirectory,
2226 Map customOptions,
2227 boolean generateOutput,
2228 boolean showCategory,
2229 boolean showWarningToken) {
2230 runTest(
2231 // test directory preparation
2232 shouldFlushOutputDirectory /* should flush output directory */,
2233 testFiles /* test files */,
2234 // compiler options
2235 classLibraries /* class libraries */,
2236 customOptions /* custom options */,
2237 false,
2238 new Requestor( /* custom requestor */
2239 generateOutput,
2240 null /* no custom requestor */,
2241 showCategory,
2242 showWarningToken),
2243 // compiler results
2244 expectedProblemLog == null || /* expecting compiler errors */
2245 expectedProblemLog.indexOf("ERROR") != -1,
2246 expectedProblemLog,
2247 // runtime options
2248 false /* do not force execution */,
2249 null /* no vm arguments */,
2250 // runtime results
2251 null /* do not check output string */,
2252 null /* do not check error string */,
2253 // javac options
2254 JavacTestOptions.DEFAULT /* javac test options */);
2255 }
2256
2257 /**
2258 * Log contains all problems (warnings+errors)
2259 */
2260 // WORK potential candidate for elimination (19 calls)
2261 protected void runNegativeTest(
2262 String[] testFiles,
2263 String expectedCompilerLog,
2264 String[] classLibraries,
2265 boolean shouldFlushOutputDirectory,
2266 Map customOptions,
2267 boolean generateOutput,
2268 boolean showCategory,
2269 boolean showWarningToken,
2270 boolean skipJavac,
2271 boolean performStatementsRecovery) {
2272 runTest(
2273 // test directory preparation
2274 shouldFlushOutputDirectory /* should flush output directory */,
2275 testFiles /* test files */,
2276 // compiler options
2277 classLibraries /* class libraries */,
2278 customOptions /* custom options */,
2279 performStatementsRecovery /* perform statements recovery */,
2280 new Requestor( /* custom requestor */
2281 generateOutput,
2282 null /* no custom requestor */,
2283 showCategory,
2284 showWarningToken),
2285 // compiler results
2286 expectedCompilerLog == null || /* expecting compiler errors */
2287 expectedCompilerLog.indexOf("ERROR") != -1,
2288 expectedCompilerLog /* expected compiler log */,
2289 // runtime options
2290 false /* do not force execution */,
2291 null /* no vm arguments */,
2292 // runtime results
2293 null /* do not check output string */,
2294 null /* do not check error string */,
2295 // javac options
2296 skipJavac ?
2297 JavacTestOptions.SKIP :
2298 JavacTestOptions.DEFAULT /* javac test options */);
2299 }
Stephan Herrmann4d079452014-03-27 18:01:49 +01002300 protected void runNegativeTest(
2301 String[] testFiles,
2302 String expectedCompilerLog,
2303 String[] classLibraries,
2304 boolean shouldFlushOutputDirectory,
2305 Map customOptions,
2306 boolean generateOutput,
2307 boolean showCategory,
2308 boolean showWarningToken,
2309 boolean skipJavac,
2310 JavacTestOptions javacOptions,
2311 boolean performStatementsRecovery) {
2312 runTest(
2313 // test directory preparation
2314 shouldFlushOutputDirectory /* should flush output directory */,
2315 testFiles /* test files */,
2316 // compiler options
2317 classLibraries /* class libraries */,
2318 customOptions /* custom options */,
2319 performStatementsRecovery /* perform statements recovery */,
2320 new Requestor( /* custom requestor */
2321 generateOutput,
2322 null /* no custom requestor */,
2323 showCategory,
2324 showWarningToken),
2325 // compiler results
2326 expectedCompilerLog == null || /* expecting compiler errors */
2327 expectedCompilerLog.indexOf("ERROR") != -1,
2328 expectedCompilerLog /* expected compiler log */,
2329 // runtime options
2330 false /* do not force execution */,
2331 null /* no vm arguments */,
2332 // runtime results
2333 null /* do not check output string */,
2334 null /* do not check error string */,
2335 // javac options
2336 skipJavac ?
2337 JavacTestOptions.SKIP :
2338 javacOptions/* javac test options */);
2339 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002340 protected void runTest(
2341 String[] testFiles,
2342 boolean expectingCompilerErrors,
2343 String expectedCompilerLog,
2344 String expectedOutputString,
2345 String expectedErrorString,
2346 boolean forceExecution,
2347 String[] classLibraries,
2348 boolean shouldFlushOutputDirectory,
2349 String[] vmArguments,
2350 Map customOptions,
2351 ICompilerRequestor customRequestor,
2352 boolean skipJavac) {
2353 runTest(
2354 // test directory preparation
2355 shouldFlushOutputDirectory /* should flush output directory */,
2356 testFiles /* test files */,
2357 // compiler options
2358 classLibraries /* class libraries */,
2359 customOptions /* custom options */,
2360 false /* do not perform statements recovery */,
2361 customRequestor /* custom requestor */,
2362 // compiler results
2363 expectingCompilerErrors /* expecting compiler errors */,
2364 expectedCompilerLog /* expected compiler log */,
2365 // runtime options
2366 forceExecution /* force execution */,
2367 vmArguments /* vm arguments */,
2368 // runtime results
2369 expectedOutputString /* expected output string */,
2370 expectedErrorString /* expected error string */,
2371 // javac options
2372 skipJavac ?
2373 JavacTestOptions.SKIP :
2374 JavacTestOptions.DEFAULT /* javac test options */);
2375
2376 }
2377
2378 // WORK get this out
2379 protected void runTest(
2380 String[] testFiles,
2381 boolean expectingCompilerErrors,
2382 String expectedCompilerLog,
2383 String expectedOutputString,
2384 String expectedErrorString,
2385 boolean forceExecution,
2386 String[] classLibraries,
2387 boolean shouldFlushOutputDirectory,
2388 String[] vmArguments,
2389 Map customOptions,
2390 ICompilerRequestor clientRequestor,
2391 JavacTestOptions javacTestOptions) {
2392 runTest(
2393 // test directory preparation
2394 shouldFlushOutputDirectory /* should flush output directory */,
2395 testFiles /* test files */,
2396 // compiler options
2397 classLibraries /* class libraries */,
2398 customOptions /* custom options */,
2399 false /* do not perform statements recovery */,
2400 clientRequestor /* custom requestor */,
2401 // compiler results
2402 expectingCompilerErrors /* expecting compiler errors */,
2403 expectedCompilerLog /* expected compiler log */,
2404 // runtime options
2405 forceExecution /* force execution */,
2406 vmArguments /* vm arguments */,
2407 // runtime results
2408 expectedOutputString /* expected output string */,
2409 expectedErrorString /* expected error string */,
2410 // javac options
2411 javacTestOptions /* javac test options */);
2412 }
Stephan Herrmann024160d2013-05-02 04:29:33 +02002413//{ObjectTeams: made accessible to sub-classes:
2414 protected void runTest(
2415// SH}
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002416 // test directory preparation
2417 boolean shouldFlushOutputDirectory,
2418 String[] testFiles,
2419 // compiler options
2420 String[] classLibraries,
2421 Map customOptions,
2422 boolean performStatementsRecovery,
2423 ICompilerRequestor customRequestor,
2424 // compiler results
2425 boolean expectingCompilerErrors,
2426 String expectedCompilerLog,
2427 // runtime options
2428 boolean forceExecution,
2429 String[] vmArguments,
2430 // runtime results
2431 String expectedOutputString,
2432 String expectedErrorString,
2433 // javac options
2434 JavacTestOptions javacTestOptions) {
Stephan Herrmannde4efa92010-09-26 16:11:28 +00002435 runTest(
2436 shouldFlushOutputDirectory,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002437 testFiles,
Stephan Herrmannde4efa92010-09-26 16:11:28 +00002438 new String[] {},
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002439 classLibraries,
2440 customOptions,
2441 performStatementsRecovery,
2442 customRequestor,
2443 expectingCompilerErrors,
2444 expectedCompilerLog,
Stephan Herrmann4d079452014-03-27 18:01:49 +01002445 null, // alternate compile errors
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002446 forceExecution,
2447 vmArguments,
2448 expectedOutputString,
2449 expectedErrorString,
2450 null,
2451 javacTestOptions);
2452 }
Stephan Herrmann4d079452014-03-27 18:01:49 +01002453 /** Call this if the compiler randomly produces different error logs. */
2454 protected void runNegativeTestMultiResult(String[] testFiles, Map options, String[] alternateCompilerErrorLogs) {
2455 runTest(
2456 false,
2457 testFiles,
2458 new String[] {},
2459 null,
2460 options,
2461 false,
2462 new Requestor( /* custom requestor */
2463 false,
2464 null /* no custom requestor */,
2465 false,
2466 false),
2467 true,
2468 null,
2469 alternateCompilerErrorLogs,
2470 false,
2471 null,
2472 null,
2473 null,
2474 null,
2475 JavacTestOptions.DEFAULT);
2476 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002477// This is a worker method to support regression tests. To ease policy changes,
2478// it should not be called directly, but through the runConformTest and
2479// runNegativeTest series.
2480// calling templates:
2481// runTest(
2482// // test directory preparation
2483// true /* flush output directory */,
2484// false /* do not flush output directory */,
2485// shouldFlushOutputDirectory /* should flush output directory */,
2486//
2487// new String[] { /* test files */
2488// },
2489// null /* no test files */,
2490// testFiles /* test files */,
2491//
2492// // compiler options
2493// null /* no class libraries */,
2494// new String[] { /* class libraries */
2495// },
2496// classLibraries /* class libraries */,
2497//
2498// null /* no custom options */,
2499// customOptions /* custom options */,
2500//
2501// true /* perform statements recovery */,
2502// false /* do not perform statements recovery */,
2503// performStatementsRecovery /* perform statements recovery */,
2504//
2505// null /* no custom requestor */,
2506// customRequestor /* custom requestor */,
2507//
2508// // compiler results
2509// false /* expecting no compiler errors */,
2510// true /* expecting compiler errors */,
2511// expectingCompilerErrors /* expecting compiler errors */,
2512//
2513// null /* do not check compiler log */,
2514// "" /* expected compiler log */,
2515// expectedCompilerLog /* expected compiler log */,
2516//
2517// // runtime options
2518// false /* do not force execution */,
2519// true /* force execution */,
2520// forceExecution /* force execution */,
2521//
2522// null /* no vm arguments */,
2523// new String[] { /* vm arguments */
2524// },
2525// vmArguments /* vm arguments */,
2526//
2527// // runtime results
2528// null /* do not check output string */,
2529// "" /* expected output string */,
2530// expectedOutputString /* expected output string */,
2531//
2532// null /* do not check error string */,
2533// "" /* expected error string */,
2534// expectedErrorString /* expected error string */,
2535//
2536// // javac options
2537// JavacTestOptions.SKIP /* skip javac tests */);
2538// JavacTestOptions.DEFAULT /* default javac test options */);
2539// javacTestOptions /* javac test options */);
2540// TODO Maxime future work:
2541// - reduce the number of tests that implicitly skip parts like logs
2542// comparisons; while this is due to eat up more time, we will gain in
2543// coverage (and detection of unwanted changes); of course, this will tend
2544// to 'over constrain' some tests, but a reasonable approach would be to
2545// unable the comparison for tests which just happen to be fine;
2546// - check the callees statistics for wrapper methods and tune them accordingly
2547// (aka, suppress low profile ones).
2548// WORK log test files in all failure cases (ez cut and paste)
2549 private void runTest(
2550 // test directory preparation
2551 boolean shouldFlushOutputDirectory,
2552 String[] testFiles,
Stephan Herrmannde4efa92010-09-26 16:11:28 +00002553 String[] dependantFiles,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002554 // compiler options
2555 String[] classLibraries,
2556 Map customOptions,
2557 boolean performStatementsRecovery,
2558 ICompilerRequestor customRequestor,
2559 // compiler results
2560 boolean expectingCompilerErrors,
2561 String expectedCompilerLog,
Stephan Herrmann4d079452014-03-27 18:01:49 +01002562 String[] alternateCompilerLogs,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002563 // runtime options
2564 boolean forceExecution,
2565 String[] vmArguments,
2566 // runtime results
2567 String expectedOutputString,
2568 String expectedErrorString,
2569 final ASTVisitor visitor,
2570 // javac options
2571 JavacTestOptions javacTestOptions) {
2572 // non-javac part
2573 if (shouldFlushOutputDirectory)
2574 Util.flushDirectoryContent(new File(OUTPUT_DIR));
2575 // complain early in RUN_JAVAC mode (avoid to do it else until we've fixed all tests)
2576 if (RUN_JAVAC && testFiles != null && (testFiles.length % 2) != 0) {
2577 fail("odd number of strings in testFiles");
2578 }
2579
2580 Requestor requestor =
2581 customRequestor instanceof Requestor ?
2582 (Requestor) customRequestor :
2583 new Requestor(
2584 forceExecution,
2585 customRequestor,
2586 false, /* show category */
2587 false /* show warning token*/);
2588 requestor.outputPath = OUTPUT_DIR.endsWith(File.separator) ? OUTPUT_DIR : OUTPUT_DIR + File.separator;
2589 // WORK should not have to test a constant?
2590
2591 Map options = getCompilerOptions();
2592 if (customOptions != null) {
2593 options.putAll(customOptions);
2594 }
2595 CompilerOptions compilerOptions = new CompilerOptions(options);
2596 compilerOptions.performMethodsFullRecovery = performStatementsRecovery;
2597 compilerOptions.performStatementsRecovery = performStatementsRecovery;
Stephan Herrmannde4efa92010-09-26 16:11:28 +00002598 INameEnvironment nameEnvironment = getNameEnvironment(dependantFiles, classLibraries);
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002599 Compiler batchCompiler =
2600 new Compiler(
2601 nameEnvironment,
2602 getErrorHandlingPolicy(),
2603 compilerOptions,
2604 requestor,
2605 getProblemFactory()) {
2606 public void process(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, int i) {
2607 super.process(unit, i);
2608 if (visitor != null) {
2609 unit.traverse(visitor, unit.scope);
2610 }
2611 }
2612 };
2613 compilerOptions.produceReferenceInfo = true;
2614 Throwable exception = null;
2615 try {
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002616//{ObjectTeams: extracted as new hook:
2617/* orig:
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002618 batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002619 :giro */
2620 compileTestFiles(batchCompiler, testFiles);
2621// SH}
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002622 } catch(RuntimeException e){
2623 exception = e;
2624 throw e;
2625 } catch(Error e) {
2626 exception = e;
2627 throw e;
2628 } finally {
2629 nameEnvironment.cleanup();
Stephan Herrmann4d079452014-03-27 18:01:49 +01002630 String[] alternatePlatformIndepentLogs = null;
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002631 if (expectedCompilerLog != null) {
Stephan Herrmann4d079452014-03-27 18:01:49 +01002632 alternatePlatformIndepentLogs = new String[] {Util.convertToIndependantLineDelimiter(expectedCompilerLog)};
2633 } else if (alternateCompilerLogs != null) {
2634 alternatePlatformIndepentLogs = new String[alternateCompilerLogs.length];
2635 for (int i = 0; i < alternateCompilerLogs.length; i++)
2636 alternatePlatformIndepentLogs[i] = Util.convertToIndependantLineDelimiter(alternateCompilerLogs[i]);
2637 }
2638 if (alternatePlatformIndepentLogs != null) {
2639 checkCompilerLog(testFiles, requestor, alternatePlatformIndepentLogs, exception);
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002640 }
2641 if (exception == null) {
2642 if (expectingCompilerErrors) {
2643 if (!requestor.hasErrors) {
2644 logTestFiles(true, testFiles);
2645 fail("Unexpected success");
2646 }
2647 } else if (requestor.hasErrors) {
2648 if (!"".equals(requestor.problemLog)) {
2649 logTestFiles(true, testFiles);
2650 System.out.println("Copy-paste compiler log:");
2651 System.out.println(Util.displayString(Util.convertToIndependantLineDelimiter(requestor.problemLog.toString()), INDENT, SHIFT));
2652 assertEquals("Unexpected failure", "", requestor.problemLog);
2653 }
2654 }
2655 }
2656 }
2657 if (!requestor.hasErrors || forceExecution) {
2658 String sourceFile = testFiles[0];
2659
2660 // Compute class name by removing ".java" and replacing slashes with dots
2661 String className = sourceFile.substring(0, sourceFile.length() - 5).replace('/', '.').replace('\\', '.');
2662 if (className.endsWith(PACKAGE_INFO_NAME)) return;
2663
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002664//{ObjectTeams: also reuse if same set of vmArguments:
2665/* orig:
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002666 if (vmArguments != null) {
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002667 :giro */
2668 if (this.verifier != null && !this.verifier.vmArgsEqual(vmArguments)) {
2669// SH}
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002670 if (this.verifier != null) {
2671 this.verifier.shutDown();
2672 }
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002673//{ObjectTeams: make configurable:
2674/* orig:
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002675 this.verifier = new TestVerifier(false);
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002676 :giro */
2677 this.verifier = getTestVerifier(false);
2678// SH}
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002679 this.createdVerifier = true;
2680 }
2681 boolean passed =
2682 this.verifier.verifyClassFiles(
2683 sourceFile,
2684 className,
2685 expectedOutputString,
2686 expectedErrorString,
2687 this.classpaths,
2688 null,
2689 vmArguments);
2690 if (!passed) {
2691 System.out.println(getClass().getName() + '#' + getName());
2692 String execErrorString = this.verifier.getExecutionError();
2693 if (execErrorString != null && execErrorString.length() > 0) {
2694 System.out.println("[ERR]:"+execErrorString); //$NON-NLS-1$
2695 }
2696 String execOutputString = this.verifier.getExecutionOutput();
2697 if (execOutputString != null && execOutputString.length() > 0) {
2698 System.out.println("[OUT]:"+execOutputString); //$NON-NLS-1$
2699 }
2700 for (int i = 0; i < testFiles.length; i += 2) {
2701 System.out.print(testFiles[i]);
2702 System.out.println(" ["); //$NON-NLS-1$
2703 System.out.println(testFiles[i + 1]);
2704 System.out.println("]"); //$NON-NLS-1$
2705 }
2706 }
2707 assertTrue(this.verifier.failureReason, // computed by verifyClassFiles(...) action
2708 passed);
2709 if (vmArguments != null) {
2710 if (this.verifier != null) {
2711 this.verifier.shutDown();
2712 }
2713 this.verifier = new TestVerifier(false);
2714 this.createdVerifier = true;
2715 }
2716 }
2717 // javac part
2718 if (RUN_JAVAC && javacTestOptions != JavacTestOptions.SKIP) {
2719 runJavac(testFiles, expectingCompilerErrors, expectedCompilerLog,
2720 expectedOutputString, expectedErrorString, shouldFlushOutputDirectory,
2721 javacTestOptions, vmArguments);
2722 }
2723 }
Stephan Herrmanned07f3b2010-04-21 21:57:08 +00002724//{ObjectTeams: new hooks:
2725 protected TestVerifier getTestVerifier(boolean reuseVM) {
2726 return new TestVerifier(reuseVM);
2727 }
2728 protected void compileTestFiles(Compiler batchCompiler, String[] testFiles) {
2729 batchCompiler.compile(Util.compilationUnits(testFiles)); // compile all files together
2730 }
2731// SH}
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002732
2733// runConformTest(
2734// // test directory preparation
2735// new String[] { /* test files */
2736// },
2737// // javac options
2738// JavacTestOptions.SKIP /* skip javac tests */);
2739// JavacTestOptions.DEFAULT /* default javac test options */);
2740// javacTestOptions /* javac test options */);
2741public void runConformTest(
2742 // test directory preparation
2743 String[] testFiles,
2744 // javac options
2745 JavacTestOptions javacTestOptions) {
2746runTest(
2747 // test directory preparation
2748 true /* flush output directory */,
2749 testFiles /* test files */,
2750 // compiler options
2751 null /* no class libraries */,
2752 null /* no custom options */,
2753 false /* do not perform statements recovery */,
2754 null /* no custom requestor */,
2755 // compiler results
2756 false /* expecting no compiler errors */,
2757 "" /* expected compiler log */,
2758 // runtime options
2759 false /* do not force execution */,
2760 null /* no vm arguments */,
2761 // runtime results
2762 "" /* expected output string */,
2763 "" /* expected error string */,
2764 // javac options
2765 javacTestOptions /* javac test options */);
2766}
2767// runConformTest(
2768// // test directory preparation
2769// true /* flush output directory */,
2770// false /* do not flush output directory */,
2771// shouldFlushOutputDirectory /* should flush output directory */,
2772//
2773// new String[] { /* test files */
2774// },
2775// null /* no test files */,
2776// testFiles /* test files */,
2777//
2778// // compiler results
2779// null /* do not check compiler log */,
2780// "" /* expected compiler log */,
2781// expectedCompilerLog /* expected compiler log */,
2782//
2783// // runtime results
2784// null /* do not check output string */,
2785// "" /* expected output string */,
2786// expectedOutputString /* expected output string */,
2787//
2788// null /* do not check error string */,
2789// "" /* expected error string */,
2790// expectedErrorString /* expected error string */,
2791//
2792// // javac options
2793// JavacTestOptions.SKIP /* skip javac tests */);
2794// JavacTestOptions.DEFAULT /* default javac test options */);
2795// javacTestOptions /* javac test options */);
2796protected void runConformTest(
2797 // test directory preparation
2798 boolean shouldFlushOutputDirectory,
2799 String[] testFiles,
2800 // compiler results
2801 String expectedCompilerLog,
2802 // runtime results
2803 String expectedOutputString,
2804 String expectedErrorString,
2805 // javac options
2806 JavacTestOptions javacTestOptions) {
2807 runTest(
2808 // test directory preparation
2809 shouldFlushOutputDirectory /* should flush output directory */,
2810 testFiles /* test files */,
2811 // compiler options
2812 null /* no class libraries */,
2813 null /* no custom options */,
2814 false /* do not perform statements recovery */,
2815 null /* no custom requestor */,
2816 // compiler results
2817 false /* expecting no compiler errors */,
2818 expectedCompilerLog /* expected compiler log */,
2819 // runtime options
2820 false /* do not force execution */,
2821 null /* no vm arguments */,
2822 // runtime results
2823 expectedOutputString /* expected output string */,
2824 expectedErrorString /* expected error string */,
2825 // javac options
2826 javacTestOptions /* javac test options */);
2827}
2828// runConformTest(
2829// // test directory preparation
2830// true /* flush output directory */,
2831// false /* do not flush output directory */,
2832//
2833// new String[] { /* test files */
2834// },
2835// null /* no test files */,
2836//
2837// // compiler options
2838// null /* no class libraries */,
2839// new String[] { /* class libraries */
2840// },
2841//
2842// null /* no custom options */,
2843// customOptions /* custom options */,
2844//
2845// // compiler results
2846// null /* do not check compiler log */,
2847// "----------\n" + /* expected compiler log */
2848// "" /* expected compiler log */,
2849//
2850// // runtime results
2851// null /* do not check output string */,
2852// "" /* expected output string */,
2853// expectedOutputString /* expected output string */,
2854//
2855// null /* do not check error string */,
2856// "" /* expected error string */,
2857// expectedErrorString /* expected error string */,
2858//
2859// // javac options
2860// JavacTestOptions.SKIP /* skip javac tests */);
2861// JavacTestOptions.DEFAULT /* default javac test options */);
2862// javacTestOptions /* javac test options */);
2863protected void runConformTest(
2864 // test directory preparation
2865 boolean shouldFlushOutputDirectory,
2866 String[] testFiles,
2867 //compiler options
2868 String[] classLibraries /* class libraries */,
2869 Map customOptions /* custom options */,
2870 // compiler results
2871 String expectedCompilerLog,
2872 // runtime results
2873 String expectedOutputString,
2874 String expectedErrorString,
2875 // javac options
2876 JavacTestOptions javacTestOptions) {
2877 runTest(
2878 // test directory preparation
2879 shouldFlushOutputDirectory /* should flush output directory */,
2880 testFiles /* test files */,
2881 // compiler options
2882 classLibraries /* class libraries */,
2883 customOptions /* custom options */,
2884 false /* do not perform statements recovery */,
2885 null /* no custom requestor */,
2886 // compiler results
2887 false /* expecting no compiler errors */,
2888 expectedCompilerLog /* expected compiler log */,
2889 // runtime options
2890 false /* do not force execution */,
2891 null /* no vm arguments */,
2892 // runtime results
2893 expectedOutputString /* expected output string */,
2894 expectedErrorString /* expected error string */,
2895 // javac options
2896 javacTestOptions /* javac test options */);
2897}
2898// runNegativeTest(
2899// // test directory preparation
2900// new String[] { /* test files */
2901// },
2902// null /* no test files */,
2903// // compiler results
2904// "----------\n" + /* expected compiler log */
2905// // javac options
2906// JavacTestOptions.SKIP /* skip javac tests */);
2907// JavacTestOptions.DEFAULT /* default javac test options */);
2908// javacTestOptions /* javac test options */);
2909protected void runNegativeTest(
2910 // test directory preparation
2911 String[] testFiles,
2912 // compiler results
2913 String expectedCompilerLog,
2914 // javac options
2915 JavacTestOptions javacTestOptions) {
2916 runTest(
2917 // test directory preparation
2918 true /* flush output directory */,
2919 testFiles /* test files */,
2920 // compiler options
2921 null /* no class libraries */,
2922 null /* no custom options */,
2923 false /* do not perform statements recovery */,
2924 null /* no custom requestor */,
2925 // compiler results
Stephan Herrmannb0a2f8b2013-09-08 15:00:03 +02002926 true /* expecting compiler errors */,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002927 expectedCompilerLog /* expected compiler log */,
2928 // runtime options
2929 false /* do not force execution */,
2930 null /* no vm arguments */,
2931 // runtime results
2932 null /* do not check output string */,
2933 null /* do not check error string */,
2934 // javac options
2935 javacTestOptions /* javac test options */);
2936}
2937// runNegativeTest(
2938// // test directory preparation
2939// true /* flush output directory */,
2940// false /* do not flush output directory */,
2941// shouldFlushOutputDirectory /* should flush output directory */,
2942//
2943// new String[] { /* test files */
2944// },
2945// null /* no test files */,
2946//
2947// // compiler options
2948// null /* no class libraries */,
2949// new String[] { /* class libraries */
2950// },
2951// classLibraries /* class libraries */,
2952//
2953// null /* no custom options */,
2954// customOptions /* custom options */,
2955//
2956// // compiler results
2957// null /* do not check compiler log */,
2958// "----------\n" + /* expected compiler log */
2959//
2960// // javac options
2961// JavacTestOptions.SKIP /* skip javac tests */);
2962// JavacTestOptions.DEFAULT /* default javac test options */);
2963// javacTestOptions /* javac test options */);
2964protected void runNegativeTest(
2965 // test directory preparation
2966 boolean shouldFlushOutputDirectory,
2967 String[] testFiles,
2968 // compiler options
2969 String[] classLibraries,
2970 Map customOptions,
2971 // compiler results
2972 String expectedCompilerLog,
2973 // javac options
2974 JavacTestOptions javacTestOptions) {
2975 runTest(
2976 // test directory preparation
2977 shouldFlushOutputDirectory /* should flush output directory */,
2978 testFiles /* test files */,
2979 // compiler options
2980 classLibraries /* class libraries */,
2981 customOptions /* custom options */,
2982 false /* do not perform statements recovery */,
2983 null /* no custom requestor */,
2984 // compiler results
Stephan Herrmannb0a2f8b2013-09-08 15:00:03 +02002985 expectedCompilerLog == null || /* expecting compiler errors */
2986 expectedCompilerLog.indexOf("ERROR") != -1,
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00002987 expectedCompilerLog /* expected compiler log */,
2988 // runtime options
2989 false /* do not force execution */,
2990 null /* no vm arguments */,
2991 // runtime results
2992 null /* do not check output string */,
2993 null /* do not check error string */,
2994 // javac options
2995 javacTestOptions /* javac test options */);
2996}
2997// runNegativeTest(
2998// // test directory preparation
2999// true /* flush output directory */,
3000// false /* do not flush output directory */,
3001// shouldFlushOutputDirectory /* should flush output directory */,
3002//
3003// new String[] { /* test files */
3004// },
3005// null /* no test files */,
3006//
3007// // compiler options
3008// null /* no class libraries */,
3009// new String[] { /* class libraries */
3010// },
3011// classLibraries /* class libraries */,
3012//
3013// null /* no custom options */,
3014// customOptions /* custom options */,
3015//
3016// // compiler results
3017// null /* do not check compiler log */,
3018// "----------\n" + /* expected compiler log */
3019//
3020// //runtime results
3021// null /* do not check output string */,
3022// "" /* expected output string */,
3023// expectedOutputString /* expected output string */,
3024//
3025// null /* do not check error string */,
3026// "" /* expected error string */,
3027// expectedErrorString /* expected error string */,
3028//
3029// // javac options
3030// JavacTestOptions.SKIP /* skip javac tests */);
3031// JavacTestOptions.DEFAULT /* default javac test options */);
3032// javacTestOptions /* javac test options */);
Stephan Herrmannc6f62842011-01-27 12:07:14 +00003033protected void runNegativeTest(
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00003034 // test directory preparation
3035 boolean shouldFlushOutputDirectory,
3036 String[] testFiles,
3037 // compiler options
3038 String[] classLibraries,
3039 Map customOptions,
3040 // compiler results
3041 String expectedCompilerLog,
3042 // runtime results
3043 String expectedOutputString,
3044 String expectedErrorString,
3045 // javac options
3046 JavacTestOptions javacTestOptions) {
3047 runTest(
3048 // test directory preparation
3049 shouldFlushOutputDirectory /* should flush output directory */,
3050 testFiles /* test files */,
3051 // compiler options
3052 classLibraries /* class libraries */,
3053 customOptions /* custom options */,
3054 false /* do not perform statements recovery */,
3055 null /* no custom requestor */,
3056 // compiler results
3057 true /* expecting compiler errors */,
3058 expectedCompilerLog /* expected compiler log */,
3059 // runtime options
3060 true /* force execution */,
3061 null /* no vm arguments */,
3062 // runtime results
3063 expectedOutputString /* expected output string */,
3064 expectedErrorString /* expected error string */,
3065 // javac options
3066 javacTestOptions /* javac test options */);
3067}
3068 protected void setUp() throws Exception {
3069 super.setUp();
3070 if (this.verifier == null) {
3071 this.verifier = new TestVerifier(true);
3072 this.createdVerifier = true;
3073 }
3074 if (RUN_JAVAC) {
3075 // WORK make all needed inits once and for all
3076 if (isFirst()) {
3077 if (javacFullLog == null) {
3078 // One time initialization of javac related concerns
3079 // compute command lines and extract javac version
3080 JAVAC_OUTPUT_DIR = new File(JAVAC_OUTPUT_DIR_NAME);
3081 // WORK simplify jdk.root out
3082 String jdkRootDirectory = System.getProperty("jdk.root");
3083 if (jdkRootDirectory == null)
3084 jdkRootDirPath = (new Path(Util.getJREDirectory())).removeLastSegments(1);
3085 else
3086 jdkRootDirPath = new Path(jdkRootDirectory);
3087
3088 StringBuffer cmdLineHeader = new StringBuffer(jdkRootDirPath.
3089 append("bin").append(JAVA_NAME).toString()); // PREMATURE replace JAVA_NAME and JAVAC_NAME with locals? depends on potential reuse
3090 javaCommandLineHeader = cmdLineHeader.toString();
3091 cmdLineHeader = new StringBuffer(jdkRootDirPath.
3092 append("bin").append(JAVAC_NAME).toString());
3093 cmdLineHeader.append(" -classpath . ");
3094 // start with the current directory which contains the source files
3095 Process compileProcess = Runtime.getRuntime().exec(
3096 cmdLineHeader.toString() + " -version", null, null);
3097 Logger versionLogger = new Logger(compileProcess.getErrorStream(), "");
3098 // PREMATURE implement consistent error policy
3099 versionLogger.start();
3100 compileProcess.waitFor();
3101 versionLogger.join(); // make sure we get the whole output
3102 String version = versionLogger.buffer.toString();
3103 int eol = version.indexOf('\n');
3104 version = version.substring(0, eol);
3105 cmdLineHeader.append(" -d ");
3106 cmdLineHeader.append(JAVAC_OUTPUT_DIR_NAME.indexOf(" ") != -1 ? "\"" + JAVAC_OUTPUT_DIR_NAME + "\"" : JAVAC_OUTPUT_DIR_NAME);
3107 cmdLineHeader.append(" -source 1.5 -deprecation -Xlint:unchecked "); // enable recommended warnings
3108 // WORK new javac system does not do that... reconsider
3109 // REVIEW consider enabling all warnings instead? Philippe does not see
3110 // this as ez to use (too many changes in logs)
3111 javacCommandLineHeader = cmdLineHeader.toString();
3112 new File(Util.getOutputDirectory()).mkdirs();
3113 // TODO maxime check why this happens to miss in some cases
3114 // WORK if we keep a full log, it should not mix javac versions...
3115 javacFullLogFileName = Util.getOutputDirectory() + File.separatorChar +
3116 version.replace(' ', '_') + "_" +
3117 (new SimpleDateFormat("yyyyMMdd_HHmmss")).format(new Date()) +
3118 ".txt";
3119 javacFullLog =
3120 new PrintWriter(new FileOutputStream(javacFullLogFileName)); // static that is initialized once, closed at process end
3121 javacFullLog.println(version); // so that the contents is self sufficient
3122 System.out.println("***************************************************************************");
3123 System.out.println("* Sun Javac compiler output archived into file:");
3124 System.out.println("* " + javacFullLogFileName);
3125 System.out.println("***************************************************************************");
3126 javacCompilers = new ArrayList();
3127 String jdkRoots = System.getProperty("jdk.roots");
3128 if (jdkRoots == null) {
3129 javacCompilers.add(new JavacCompiler(jdkRootDirPath.toString()));
3130 } else {
3131 StringTokenizer tokenizer = new StringTokenizer(jdkRoots, File.pathSeparator);
3132 while (tokenizer.hasMoreTokens()) {
3133 javacCompilers.add(new JavacCompiler(tokenizer.nextToken()));
3134 }
3135 }
3136 }
3137 // per class initialization
3138 CURRENT_CLASS_NAME = getClass().getName();
3139 dualPrintln("***************************************************************************");
3140 System.out.print("* Comparison with Sun Javac compiler for class ");
3141 dualPrintln(CURRENT_CLASS_NAME.substring(CURRENT_CLASS_NAME.lastIndexOf('.')+1) +
3142 " (" + TESTS_COUNTERS.get(CURRENT_CLASS_NAME) + " tests)");
3143 System.out.println("***************************************************************************");
3144 DIFF_COUNTERS[0] = 0;
3145 DIFF_COUNTERS[1] = 0;
3146 DIFF_COUNTERS[2] = 0;
3147 }
3148 }
3149 }
3150
3151 public void stop() {
3152 this.verifier.shutDown();
3153 }
3154
3155 protected void tearDown() throws Exception {
3156 if (this.createdVerifier) {
3157 stop();
3158 }
3159 // clean up output dir
3160 File outputDir = new File(OUTPUT_DIR);
3161 if (outputDir.exists()) {
3162 Util.flushDirectoryContent(outputDir);
3163 }
3164 super.tearDown();
3165 if (RUN_JAVAC) {
3166 if (JAVAC_OUTPUT_DIR.exists()) {
3167 Util.flushDirectoryContent(JAVAC_OUTPUT_DIR);
3168 }
3169 printJavacResultsSummary();
3170 }
3171 }
Stephan Herrmann71432c02011-10-25 16:30:36 +00003172 /**
3173 * Returns the OS path to the directory that contains this plugin.
3174 */
3175 protected String getCompilerTestsPluginDirectoryPath() {
3176 try {
3177 URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.compiler").getEntry("/");
3178 return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath();
3179 } catch (IOException e) {
3180 e.printStackTrace();
3181 }
3182 return null;
3183 }
Stephan Herrmann5ed21e42010-04-01 21:40:57 +00003184}