/*******************************************************************************
 * Copyright (c) 2011, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann - Contribution for
 *								Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE.
 *******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;

import java.util.Map;

import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;

import junit.framework.Test;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class Compliance_1_7 extends AbstractComparableTest {

public Compliance_1_7(String name) {
	super(name);
}
public static Test suite() {
	return buildMinimalComplianceTestSuite(testClass(), F_1_7);
}
static {
// Names of tests to run: can be "testBugXXXX" or "BugXXXX")
//		TESTS_NAMES = new String[] { "Bug58069" };
// Numbers of tests to run: "test<number>" will be run for each number of this array
//	TESTS_NUMBERS = new int[] { 104 };
// Range numbers of tests to run: all tests between "test<first>" and "test<last>" will be run for { first, last }
//		TESTS_RANGE = new int[] { 85, -1 };
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=283225
public void test1() {
	this.runConformTest(
		new String[] {
			"p1/Z.java",
			"package p1;\n" +
			"import java.util.List;\n" +
			"public class Z  {\n" +
			"	@SafeVarargs\n" +
			"	public static <T> List<T> asList(T... a) {\n" + 
			"		return null;\n" + 
			"	}\n" +
			"}"
		},
		""); // no special vm args

		String computedReferences = findReferences(OUTPUT_DIR + "/p1/Z.class");
		boolean check = computedReferences.indexOf("annotationRef/SafeVarargs") >= 0;
		if (!check){
			System.out.println(computedReferences);
		}
		assertTrue("did not indexed the reference to SafeVarargs", check);
}
public void test2() {
	this.runConformTest(
		new String[] {
			"p2/Z.java",
			"package p2;\n" +
			"import java.lang.annotation.Inherited;\n" +
			"@Inherited\n" +
			"public @interface Z  {\n" +
			"}"
		},
		""); // no special vm args

		String computedReferences = findReferences(OUTPUT_DIR + "/p2/Z.class");
		boolean check = computedReferences.indexOf("annotationRef/Inherited") >= 0;
		if (!check){
			System.out.println(computedReferences);
		}
		assertTrue("did not indexed the reference to Inherited", check);
}
// Project with 1.7 compliance compiled against JRE 7, 8
// regular case
public void testBug390889_a() {
	Map options = getCompilerOptions();
	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
	this.runConformTest(
			new String[] {
					"MyComp.java",
					"import java.util.Comparator;\n" + 
					"public class MyComp implements Comparator {\n" + 
					"	@Override\n" + 
					"	public int compare(Object o1, Object o2) {\n" + 
					"		return 0;\n" + 
					"	}\n" + 
					"}\n" + 
					"class MyStringComp implements Comparator<String> {\n" + 
					"	@Override\n" + 
					"	public int compare(String o1, String o2) {\n" + 
					"		return 0;\n" + 
					"	}\n" + 
					"}\n"
			},
			"",
			null /* no extra class libraries */,
			true /* flush output directory */,
			null,
			options,
			null/* do not perform statements recovery */);
}
// Project with 1.7 compliance compiled against JRE 8
// default method implements a regular abstract interface method
public void testBug390889_b() {
	if (this.complianceLevel < ClassFileConstants.JDK1_8)
		return;
	runConformTest(
			new String[] {
				"I1.java",
				"interface I0 {\n" + 
				"  void foo();\n" + 
				"}\n" + 
				"public interface I1 extends I0 {\n" +
				"  @Override\n" + 
				"  default void foo() {}\n" + 
				"}\n"
			});

	Map options = getCompilerOptions();
	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
	this.runConformTest(
			new String[] {
					"C1.java",
					"public class C1 implements I1 {\n" + 
					"}\n"
			},
			"",
			null /* no extra class libraries */,
			false /* don't flush output directory */,
			null,
			options,
			null/* do not perform statements recovery */);
}
// Project with 1.7 compliance compiled against JRE 7, 8
// assert that different forms of method invocation do not produce different result (as javac does)
public void testBug390889_c() {
	if (this.complianceLevel < ClassFileConstants.JDK1_8)
		return;
	runConformTest(
			new String[] {
				"I.java",
				"interface I {\n" + 
				"  default void foo() {}\n" + 
				"}\n"
			});

	Map options = getCompilerOptions();
	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
	this.runConformTest(
			new String[] {
				"CI.java",
				"public class CI implements I {\n" + 
				"	 void test(I i) {\n" + 
				"      this.foo();\n" + 
				"      i.foo();\n" + 
				"    }\n" + 
				"}\n"
			},
			"",
			null /* no extra class libraries */,
			false /* don't flush output directory */,
			null,
			options,
			null/* do not perform statements recovery */);
}
// Project with 1.7 compliance compiled against JRE 8
// assert that 1.8 constructs are not allowed at compliance 1.7
public void testBug490988() {
	if (this.complianceLevel < ClassFileConstants.JDK1_8)
		return;
	Map options = getCompilerOptions();
	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
	this.runNegativeTest(
			new String[] {
				"Thing.java",
				"import java.util.Comparator;\n" + 
				"import java.util.Iterator;\n" + 
				"public class Thing implements Iterator<Object> {\n" + 
				"    void breaking() {\n" + 
				"        Iterator.super.remove(); // not 1.7-compliant (must be an error)\n" + 
				"        Comparator.naturalOrder(); // not 1.7-compliant (bad error message)\n" + 
				"    }\n" + 
				"    @Override\n" + 
				"    public boolean hasNext() {\n" + 
				"        return false;\n" + 
				"    }\n" + 
				"    @Override\n" + 
				"    public Object next() {\n" + 
				"        return null;\n" + 
				"    }\n" + 
				"    public static void main(String[] args) {\n" + 
				"        new Thing().breaking();\n" + 
				"    }\n" + 
				"}"
			},
			"----------\n" +
			"1. ERROR in Thing.java (at line 5)\n" +
			"	Iterator.super.remove(); // not 1.7-compliant (must be an error)\n" +
			"	^^^^^^^^^^^^^^\n" + 
			"Super method references to interface default methods are allowed only at source level 1.8 or above\n" +
			"----------\n" +
			"2. ERROR in Thing.java (at line 6)\n" +
			"	Comparator.naturalOrder(); // not 1.7-compliant (bad error message)\n" +
			"	           ^^^^^^^^^^^^\n" + 
			"References to interface static methods are allowed only at source level 1.8 or above\n" +
			"----------\n",
			null,
			false,
			options);
}
public static Class testClass() {
	return Compliance_1_7.class;
}
}
