/*******************************************************************************
 * Copyright (c) 2013, 2016 GK Software AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Stephan Herrmann - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;

import java.util.Map;

import junit.framework.Test;

import org.eclipse.jdt.core.JavaCore;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class FlowAnalysisTest8 extends AbstractNullAnnotationTest {

//Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which do not belong to the class are skipped...
static {
//	TESTS_NAMES = new String[] { "testReferenceExpression" };
//	TESTS_NUMBERS = new int[] { 561 };
//	TESTS_RANGE = new int[] { 1, 2049 };
}

public FlowAnalysisTest8(String name) {
	super(name);
}

public static Test suite() {
	return buildMinimalComplianceTestSuite(testClass(), F_1_8);
}

public static Class testClass() {
	return FlowAnalysisTest8.class;
}

// Lambda with elided args inherits null contract from the super method
public void testLambda_01() {
	Map customOptions = getCompilerOptions();
	runNegativeTestWithLibs(
		new String[] {
			"ISAM.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public interface ISAM {\n" +
			"	@NonNull String toString(@NonNull String prefix, @Nullable Object o);\n" +
			"}\n",
			"X.java",
			"public class X {\n" +
			"	void test() {\n" +
			"		ISAM printer = (p,o) -> p.concat(o.toString());\n" +
			"	}\n" +
			"}\n"
		}, 
		customOptions,
		"----------\n" + 
		"1. WARNING in X.java (at line 3)\n" + 
		"	ISAM printer = (p,o) -> p.concat(o.toString());\n" + 
		"	                        ^^^^^^^^^^^^^^^^^^^^^^\n" + 
		"Null type safety (type annotations): The expression of type 'String' needs unchecked conversion to conform to \'@NonNull String\'\n" + 
		"----------\n" + 
		"2. ERROR in X.java (at line 3)\n" + 
		"	ISAM printer = (p,o) -> p.concat(o.toString());\n" + 
		"	                                 ^\n" + 
		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
		"----------\n",
		true /* skipJavac */);
}

// Lambda with declared args violates null contract of super
public void testLambda_02() {
	Map customOptions = getCompilerOptions();
	runNegativeTestWithLibs(
		new String[] {
			"ISAM.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public interface ISAM {\n" +
			"	void process(@NonNull Object nn, @Nullable Object n, Object u);\n" +
			"}\n",
			"X.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public class X {\n" +
			"	void test() {\n" +
					// try to override, illegal except for unchanged o1:
			"		ISAM printer = (@NonNull  Object o1, @NonNull 	Object o2, @NonNull	 Object o3) -> System.out.println(2);\n" +
			"	}\n" +
			"}\n"
		}, 
		customOptions,
		"----------\n" + 
		"1. ERROR in X.java (at line 4)\n" + 
		"	ISAM printer = (@NonNull  Object o1, @NonNull 	Object o2, @NonNull	 Object o3) -> System.out.println(2);\n" + 
		"	                                     ^^^^^^^^^^^^^^^^\n" + 
		"Illegal redefinition of parameter o2, inherited method from ISAM declares this parameter as @Nullable\n" + 
		"----------\n" + 
		"2. ERROR in X.java (at line 4)\n" + 
		"	ISAM printer = (@NonNull  Object o1, @NonNull 	Object o2, @NonNull	 Object o3) -> System.out.println(2);\n" + 
		"	                                              	           ^^^^^^^^^^^^^^^^\n" + 
		"Illegal redefinition of parameter o3, inherited method from ISAM does not constrain this parameter\n" + 
		"----------\n",
		true /* skipJavac */);
}

// Lambda with declared args inherits / modifies contract of super
public void testLambda_03() {
	Map customOptions = getCompilerOptions();
	runNegativeTestWithLibs(
		new String[] {
			"ISAM.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public interface ISAM {\n" +
			"	void process(@NonNull Object nn, @Nullable Object n, Object u);\n" +
			"}\n",
			"X.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public class X {\n" +
			"	void test() {\n" +
					// fill-in all from super:
			"		ISAM printer1 = (Object 		  o1, 			Object o2, 			 Object o3) \n" +
			"							-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" +
					// legal overrides: (however, @NonNull -> @Nullable is probably nonsense)
			"		ISAM printer3 = (@Nullable Object o1, @Nullable Object o2, @Nullable Object o3) \n" +
			"							-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" +
			"	}\n" +
			"}\n"
		}, 
		customOptions,
		"----------\n" + 
		"1. ERROR in X.java (at line 5)\n" + 
		"	-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" + 
		"	                                    ^^\n" + 
		"Potential null pointer access: The variable o2 may be null at this location\n" + 
		"----------\n" + 
		"2. ERROR in X.java (at line 7)\n" + 
		"	-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" + 
		"	                      ^^\n" + 
		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
		"----------\n" + 
		"3. ERROR in X.java (at line 7)\n" + 
		"	-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" + 
		"	                                    ^^\n" + 
		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
		"----------\n" + 
		"4. ERROR in X.java (at line 7)\n" + 
		"	-> System.out.println(o1.toString()+o2.toString()+o3.toString());\n" + 
		"	                                                  ^^\n" + 
		"Potential null pointer access: this expression has a '@Nullable' type\n" + 
		"----------\n",
		true /* skipJavac */);
}

// Lambda with declared args has illegal @NonNull an primitive argument
public void testLambda_04() {
	Map customOptions = getCompilerOptions();
	runNegativeTestWithLibs(
		new String[] {
			"ISAM.java",
			"public interface ISAM {\n" +
			"	void process(int i);\n" +
			"}\n",
			"X.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public class X {\n" +
			"	void test() {\n" +
			"		ISAM printer1 = (@NonNull int i) \n" +
			"							-> System.out.println(i);\n" +
			"	}\n" +
			"}\n"
		}, 
		customOptions,
		"----------\n" + 
		"1. ERROR in X.java (at line 4)\n" + 
		"	ISAM printer1 = (@NonNull int i) \n" + 
		"	                 ^^^^^^^^\n" + 
		"The nullness annotation @NonNull is not applicable for the primitive type int\n" + 
		"----------\n", 
		true /* skipJavac */);
}

// Lambda inherits null contract and has block with return statement 
public void testLambda_05() {
	Map customOptions = getCompilerOptions();
	runNegativeTestWithLibs(
		new String[] {
			"ISAM.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public interface ISAM {\n" +
			"	@NonNull String toString(Object o);\n" +
			"}\n",
			"X.java",
			"public class X {\n" +
			"	void test() {\n" +
			"		ISAM printer = (o) -> {\n" +
			"			System.out.print(13);\n" +
			"			return null; // error\n" +
			"		};\n" +
			"	}\n" +
			"}\n"
		}, 
		customOptions,
		"----------\n" + 
		"1. ERROR in X.java (at line 5)\n" + 
		"	return null; // error\n" + 
		"	       ^^^^\n" + 
		"Null type mismatch: required \'@NonNull String\' but the provided value is null\n" + 
		"----------\n",
		true /* skipJavac */);
}
// Lambda has no descriptor (overriding method from Object), don't bail out with NPE during analysis
public void testLambda_05a() {
	Map customOptions = getCompilerOptions();
	runNegativeTestWithLibs(
		new String[] {
			"ISAM.java",
			"import org.eclipse.jdt.annotation.*;\n" +
			"public interface ISAM {\n" +
			"	@NonNull String toString();\n" +
			"}\n",
			"X.java",
			"public class X {\n" +
			"	void test() {\n" +
			"		ISAM printer = () -> {\n" +
			"			System.out.print(13);\n" +
			"			return null;\n" +
			"		};\n" +
			"	}\n" +
			"}\n"
		}, 
		customOptions,
		"----------\n" +
		"1. ERROR in X.java (at line 3)\n" +
		"	ISAM printer = () -> {\n" +
		"	               ^^^^^\n" +
		"The target type of this expression must be a functional interface\n" +
		"----------\n",
		true /* skipJavac */);
}
// Test flows with ReferenceExpression regarding: 
// - definite assignment
// - unused local
public void testReferenceExpression1() {
	Map options = getCompilerOptions();
	options.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR);
	runNegativeTest(
		new String[] {
			 "I.java",
			 "public interface I {\n" +
			 "	public void bar();\n" +
			 "}\n",
			 "X.java",
			 "public class X {\n" +
			 "	public void moo() {}\n" +
			 "	public static void soo() {}\n" +
			 "	void testAssignment() {\n" +
			 "		X x;\n" +
			 "		I i = x::moo; // x is unassigned\n" +
			 "		i.bar();\n" +
			 "		I i2 = X::soo;\n" + // OK
			 "	}\n" +
			 "	void testStatic() {\n" +
			 "		X xs;\n" +
			 "		I is = xs::soo;\n" +
			 "	}\n" +
			 "	void testUse() {\n" +
			 "		X x1 = this, x2 = this; // x2 is not used, only x is\n" +
			 "		I i = x1::moo;\n" +
			 "		i.bar();\n" +
			 "	}\n" +
			 "}\n"
		},
		"----------\n" + 
		"1. ERROR in X.java (at line 6)\n" + 
		"	I i = x::moo; // x is unassigned\n" + 
		"	      ^\n" + 
		"The local variable x may not have been initialized\n" + 
		"----------\n" + 
		"2. ERROR in X.java (at line 12)\n" + 
		"	I is = xs::soo;\n" + 
		"	       ^^^^^^^\n" + 
		"The method soo() from the type X should be accessed in a static way \n" + 
		"----------\n" + 
		"3. ERROR in X.java (at line 15)\n" + 
		"	X x1 = this, x2 = this; // x2 is not used, only x is\n" + 
		"	             ^^\n" + 
		"The value of the local variable x2 is not used\n" + 
		"----------\n",
		null/*libs*/, true/*flush*/, options);
}
public void testReferenceExpression_null_1() {
	Map options = getCompilerOptions();
	options.put(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR);
	runNegativeTest(
		false /*skipJavac */,
		JavacTestOptions.Excuse.EclipseWarningConfiguredAsError,
		new String[] {
			 "I.java",
			 "public interface I {\n" +
			 "	public void foo();\n" +
			 "}\n",
			 "X.java",
			 "public class X {\n" +
			 "	public void bar() {}\n" +
			 "	void test() {\n" +
			 "		X x = null;\n" +
			 "		I i = x::bar;\n" +
			 "		i.foo();\n" +
			 "	}\n" +
			 "}\n"
		},
		"----------\n" + 
		"1. ERROR in X.java (at line 5)\n" + 
		"	I i = x::bar;\n" + 
		"	      ^\n" + 
		"Null pointer access: The variable x can only be null at this location\n" + 
		"----------\n",
		null/*libs*/, true/*flush*/, options);
}
public void testReferenceExpression_nullAnnotation_1() {
	runNegativeTestWithLibs(
		new String[] {
			 "I.java",
			 "import org.eclipse.jdt.annotation.*;\n" +
			 "public interface I {\n" +
			 "	public @NonNull String foo(@Nullable Object s);\n" +
			 "}\n",
			 "X.java",
			 "import org.eclipse.jdt.annotation.*;\n" +
			 "public class X {\n" +
			 "	public @Nullable String bar(@NonNull Object s) { return s.toString(); }\n" +
			 "	void test() {\n" +
			 "		I i = this::bar;\n" +
			 "		System.out.print(i.foo(null));\n" +
			 "	}\n" +
			 "}\n"
		},
		"----------\n" + 
		"1. ERROR in X.java (at line 5)\n" + 
		"	I i = this::bar;\n" + 
		"	      ^^^^^^^^^\n" + 
		"Null type mismatch at parameter 1: required '@NonNull Object' but provided '@Nullable Object' via method descriptor I.foo(Object)\n" + 
		"----------\n" + 
		"2. ERROR in X.java (at line 5)\n" + 
		"	I i = this::bar;\n" + 
		"	      ^^^^^^^^^\n" + 
		"Null type mismatch at method return type: Method descriptor I.foo(Object) promises '@NonNull String' but referenced method provides '@Nullable String'\n" + 
		"----------\n");
}
public void testReferenceExpression_nullAnnotation_2() {
	runNegativeTestWithLibs(
		true, /* skipJavac */
		new String[] {
			 "I.java",
			 "import org.eclipse.jdt.annotation.*;\n" +
			 "public interface I {\n" +
			 "	public @NonNull String foo(@Nullable Object s);\n" +
			 "}\n",
			 "X.java",
			 "public class X {\n" +
			 "	public String bar(Object s) { return s.toString(); }\n" +
			 "	void test() {\n" +
			 "		I i = this::bar;\n" +
			 "		System.out.print(i.foo(null));\n" +
			 "	}\n" +
			 "}\n"
		},
		"----------\n" + 
		"1. WARNING in X.java (at line 4)\n" + 
		"	I i = this::bar;\n" + 
		"	      ^^^^^^^^^\n" + 
		"Null type safety at method return type: Method descriptor I.foo(Object) promises \'@NonNull String\' but referenced method provides \'String\'\n" + 
		"----------\n");
}
public void testReferenceExpression_nullAnnotation_3() {
	runNegativeTestWithLibs(
		new String[] {
			 "I.java",
			 "import org.eclipse.jdt.annotation.*;\n" +
			 "public interface I {\n" +
			 "	public @NonNull String foo(Object s);\n" +
			 "}\n",
			 "X.java",
			 "import org.eclipse.jdt.annotation.*;\n" +
			 "public class X {\n" +
			 "	public @NonNull String bar(@NonNull Object s) { return \"\"; }\n" +
			 "	void test() {\n" +
			 "		I i = this::bar;\n" +
			 "		System.out.print(i.foo(null));\n" +
			 "	}\n" +
			 "	Zork zork;\n" + // make warning visible by forcing an error
			 "}\n"
		},
		"----------\n" + 
		"1. WARNING in X.java (at line 5)\n" + 
		"	I i = this::bar;\n" + 
		"	      ^^^^^^^^^\n" + 
		"Null type safety: parameter 1 provided via method descriptor I.foo(Object) needs unchecked conversion to conform to '@NonNull Object'\n" + 
		"----------\n" +
		"2. ERROR in X.java (at line 8)\n" + 
		"	Zork zork;\n" + 
		"	^^^^\n" + 
		"Zork cannot be resolved to a type\n" + 
		"----------\n");
}
}
