/*
* Copyright 2009-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eclipse.jdt.core.groovy.tests.search;
import static org.eclipse.jdt.core.tests.util.GroovyUtils.isAtLeastGroovy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.util.Set;
import org.codehaus.groovy.ast.MethodNode;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.groovy.tests.ReconcilerUtils;
import org.eclipse.jdt.core.tests.util.GroovyUtils;
import org.junit.Ignore;
import org.junit.Test;
public final class GenericInferencingTests extends InferencingTestSuite {
@Test
public void testEnum1() {
String contents =
"Blah<Some> farb\n" +
"farb.something().AA.other\n" +
"enum Some {\n" +
" AA(List)\n" +
" public final Class<List<String>> other\n" +
" public Some(Class<List<String>> other) {\n" +
" this.other = other\n" +
" }\n" +
"}\n" +
"class Blah<K> {\n" +
" K something() {\n" +
" }\n" +
"}";
int start = contents.indexOf("other");
int end = start + "other".length();
assertType(contents, start, end, "java.lang.Class<java.util.List<java.lang.String>>");
}
@Test
public void testList1() {
assertType("new LinkedList<String>()", "java.util.LinkedList<java.lang.String>");
}
@Test
public void testList2() {
String contents ="def x = new LinkedList<String>()\nx";
int start = contents.lastIndexOf("x");
int end = start + "x".length();
assertType(contents, start, end, "java.util.LinkedList<java.lang.String>");
}
@Test
public void testList3() {
String contents ="def x = [ '' ]\nx";
int start = contents.lastIndexOf("x");
int end = start + "x".length();
assertType(contents, start, end, "java.util.List<java.lang.String>");
}
@Test
public void testList4() {
String contents ="def x = [ 1 ]\nx";
int start = contents.lastIndexOf("x");
int end = start + "x".length();
assertType(contents, start, end, "java.util.List<java.lang.Integer>");
}
@Test
public void testList5() {
String contents = "[ 1 ].get(0)";
String toFind = "get";
int start = contents.indexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testList6() {
String contents = "[ 1 ].iterator()";
String toFind = "iterator";
int start = contents.indexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Iterator<java.lang.Integer>");
}
@Test
public void testList7() {
String contents = "[ 1 ].iterator().next()";
String toFind = "next";
int start = contents.indexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testList8() {
String contents ="def x = []\nx";
int start = contents.lastIndexOf("x");
int end = start + "x".length();
assertType(contents, start, end, "java.util.List<java.lang.Object>");
}
@Test
public void testList9() {
String contents = "def x = [] << ''; x";
int start = contents.lastIndexOf("x");
int end = start + "x".length();
assertType(contents, start, end, GroovyUtils.GROOVY_LEVEL < 24 ? "java.util.Collection<java.lang.String>" : "java.util.List<java.lang.String>");
}
@Test // GRECLIPSE-1040
public void testList10() {
String contents = "def x = new LinkedList()\nx";
String toFind = "x";
int start = contents.indexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.LinkedList");
}
@Test // GRECLIPSE-1040
public void testSet1() {
String contents = "def x = new HashSet()\nx";
String toFind = "x";
int start = contents.indexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.HashSet");
}
@Test
public void testMap1() {
String contents = "new HashMap<String,Integer>()";
assertType(contents, "java.util.HashMap<java.lang.String,java.lang.Integer>");
}
@Test
public void testMap2() {
String contents = "def x = new HashMap<String,Integer>()\nx";
String toFind = "x";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.HashMap<java.lang.String,java.lang.Integer>");
}
@Test
public void testMap3() {
String contents = "Map<String,Integer> x\nx.entrySet().iterator().next().value";
String toFind = "entrySet";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Set<java.util.Map$Entry<java.lang.String,java.lang.Integer>>");
}
@Test
public void testMap4() {
String contents = "def x = new HashMap<String,Integer>()\nx.entrySet().iterator().next().key";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.String");
}
@Test
public void testMap5() {
String contents = "def x = new HashMap<String,Integer>()\nx.entrySet().iterator().next().value";
String toFind = "value";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testMap6() {
String contents = "Map<String,Integer> x\nx.entrySet().iterator().next().value";
String toFind = "value";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testMap7() {
String contents = "[ 1:1 ]";
assertType(contents, "java.util.Map<java.lang.Integer,java.lang.Integer>");
}
@Test
public void testMap8() {
String contents = "[ 1:1 ].entrySet()";
String toFind = "entrySet";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Set<java.util.Map$Entry<java.lang.Integer,java.lang.Integer>>");
}
@Test
public void testMap9() {
String contents = "Map<Integer, Integer> x() { }\ndef f = x()\nf";
String toFind = "f";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.lang.Integer,java.lang.Integer>");
}
@Test // GRECLIPSE-1040
public void testMap10() {
String contents = "new HashMap()";
assertType(contents, "java.util.HashMap");
}
@Test
public void testMapOfList() {
String contents = "Map<String,List<Integer>> x\nx.entrySet().iterator().next().value";
String toFind = "value";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.Integer>");
}
@Test
public void testMapOfList2() {
String contents = "Map<String,List<Integer>> x\nx.entrySet().iterator().next().value.iterator().next()";
String toFind = "next";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testMapOfList3() {
String contents = "def x = [1: [1]]\nx.entrySet().iterator().next().key";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
// not working yet since our approach to determining the type of a map only looks at the static types of the
// first elements. It does not try to infer the type of these elements.
@Test
public void testMapOfList4() {
String contents = "def x = [1: [1]]\nx.entrySet().iterator().next().value.iterator().next()";
String toFind = "next";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testMapOfList5() {
String contents = "def x = [1: [1]]\nx.entrySet().iterator().next().value.iterator().next()";
String toFind = "next";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testMapOfList6() {
String contents = "Map<String, Map<Integer, List<Date>>> map\n" +
"def x = map.get('foo').get(5).get(2)\n" +
"x";
String toFind = "x";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Date");
}
@Test // GRECLIPSE-941
public void testMapOfList7() {
String contents = "Map<String, Map<Integer, List<Date>>> map\n" +
"def x = map['foo'][5][2]\n" +
"x";
String toFind = "x";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Date");
}
@Test
public void testForLoop1() {
String contents = "def x = 1..4\nfor (a in x) { \na }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop2() {
String contents = "for (a in 1..4) { \na }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop2a() {
String contents = "for (a in 1..4) { }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop3() {
String contents = "for (a in [1, 2].iterator()) { \na }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop4() {
String contents = "for (a in (1..4).iterator()) { \na }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop5() {
String contents = "for (a in [1 : 1]) { \na.key }";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop6() {
String contents = "for (a in [1 : 1]) { \na.value }";
String toFind = "value";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testForLoop7() {
String contents = "InputStream x\nfor (a in x) { \na }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Byte");
}
@Test
public void testForLoop8() {
String contents = "DataInputStream x\nfor (a in x) { \na }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Byte");
}
@Test
public void testForLoop9() {
String contents = "class X {\n" +
" List<String> images\n" +
"}\n" +
"def sample = new X()\n" + "for (img in sample.images) {\n" +
" img\n" +
"}";
String toFind = "img";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.String");
}
@Test
public void testForLoop11() {
String contents =
"class X {\n" +
" public void m() {\n" +
" List<String> ls = new ArrayList<String>();\n" +
" for (foo in ls) {\n" +
" foo\n" +
" }\n" +
" }\n" +
"}\n";
String toFind = "foo";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.String");
}
@Test
public void testClosure1() {
String contents = "def fn = { int a, int b -> a + b }";
assertType(contents, 4, 6, "groovy.lang.Closure<java.lang.Integer>");
}
@Test
public void testClosure2() {
String contents = "def fn = 'abc'.&length";
assertType(contents, 4, 6, "groovy.lang.Closure<java.lang.Integer>");
}
@Test
public void testClosure3() {
String contents = "def fn = Collections.&emptyList";
assertType(contents, 4, 6, "groovy.lang.Closure<java.util.List<T>>");
}
@Test
public void testClosure4() {
String contents = "def fn = (String.&trim) >> (Class.&forName)";
assertType(contents, 4, 6, GroovyUtils.GROOVY_LEVEL > 23 ? "groovy.lang.Closure<java.lang.Class<?>>" : "groovy.lang.Closure<java.lang.Class<? extends java.lang.Object>>");
}
@Test
public void testDGM() {
String contents = "String[] strings = ['1', '2']; strings.iterator()";
String toFind = "iterator";
int start = contents.lastIndexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.util.Iterator<java.lang.String>");
MethodNode dgm = assertDeclaration(contents, start, end, "org.codehaus.groovy.runtime.DefaultGroovyMethods", "iterator", DeclarationKind.METHOD);
assertEquals("First parameter type should be resolved from object expression", "java.lang.String[]", printTypeName(dgm.getParameters()[0].getType()));
}
@Test // all testing for GRECLIPSE-833
public void testDGMClosure1() {
String contents = "[''].each { it }";
String toFind = "it";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.String");
}
@Test
public void testDGMClosure2() {
String contents = "[''].reverseEach { val -> val }";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.String");
}
@Test
public void testDGMClosure3() {
assumeTrue(isAtLeastGroovy(21));
String contents = "(1..4).find { it }";
String toFind = "it";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure4() {
String contents = "['a':1].unique { it.key }";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.String");
}
@Test
public void testDGMClosure5() {
String contents = "['a':1].collect { it.value }";
String toFind = "value";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test // Integer is explicit, so should use that as a type
public void testDGMClosure7() {
String contents = "[''].reverseEach { Integer val -> val }";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test // Integer is explicit, so should use that as a type
public void testDGMClosure8() {
String contents = "[''].reverseEach { Integer it -> it }";
String toFind = "it";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure9() {
String contents = "[new Date()].eachWithIndex { val, i -> val }";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Date");
}
@Test
public void testDGMClosure10() {
String contents = "[''].eachWithIndex { val, i -> i }";
String toFind = "i";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure11() {
String contents = "[1:new Date()].eachWithIndex { key, val, i -> val }";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Date");
}
@Test
public void testDGMClosure12() {
String contents = "[1:new Date()].eachWithIndex { key, val, i -> key }";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure13() {
String contents = "[1:new Date()].eachWithIndex { key, val, i -> i }";
String toFind = "i";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure14() {
String contents = "[1:new Date()].each { key, val -> key }";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure15() {
String contents = "[1:new Date()].each { key, val -> val }";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Date");
}
@Test
public void testDGMClosure16() {
String contents = "[1:new Date()].collect { key, val -> key }";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure17() {
String contents = "[1:new Date()].collect { key, val -> val }";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Date");
}
@Test
public void testDGMClosure18() {
String contents = "[1].inject { a, b -> a }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure19() {
String contents = "[1].inject { a, b -> b }";
String toFind = "b";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure20() {
String contents = "[1].unique { a, b -> b }";
String toFind = "b";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure21() {
String contents = "[1].unique { a, b -> a }";
String toFind = "a";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testDGMClosure22() {
String contents = "[1f: 1d].collectEntries { key, value -> [value, key] } ";
String toFind = "value";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Double");
}
@Test
public void testDGMClosure23() {
String contents = "[1f: 1d].collectEntries { key, value -> [value, key] } ";
String toFind = "key";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Float");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics1() {
String contents =
"class MyMap extends HashMap<String,Class> { }\n" +
"MyMap m\n" +
"m.get()";
String toFind = "get";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Class");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics2() {
String contents =
"class MyMap extends HashMap<String,Class> { }\n" +
"MyMap m\n" +
"m.entrySet()";
String toFind = "entrySet";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Set<java.util.Map$Entry<java.lang.String,java.lang.Class>>");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics3() {
String contents =
"import java.lang.ref.WeakReference\n" +
"class MyMap<K,V> extends HashMap<K,WeakReference<V>>{ }\n" +
"MyMap<String,Class> m\n" +
"m.entrySet()";
String toFind = "entrySet";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Set<java.util.Map$Entry<java.lang.String,java.lang.ref.WeakReference<java.lang.Class>>>");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics4() {
String contents =
"import java.lang.ref.WeakReference\n" +
"class MyMap<K,V> extends HashMap<K,WeakReference<V>>{ }\n" +
"class MySubMap extends MyMap<String,Class>{ }\n" +
"MySubMap m\n" +
"m.entrySet()";
String toFind = "entrySet";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Set<java.util.Map$Entry<java.lang.String,java.lang.ref.WeakReference<java.lang.Class>>>");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics5() {
String contents =
"import java.lang.ref.WeakReference\n" +
"class MyMap<K,V> extends HashMap<K,WeakReference<V>>{ }\n" +
"class MySubMap<L> extends MyMap<String,Class>{ \n" +
" Map<L,Class> val\n" +
"}\n" +
"MySubMap<Integer> m\n" +
"m.val";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.lang.Integer,java.lang.Class>");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics6() {
String contents =
"import java.lang.ref.WeakReference\n" +
"class MyMap<K,V> extends HashMap<K,WeakReference<List<K>>>{ }\n" +
"class MySubMap extends MyMap<String,Class>{ }\n" +
"MySubMap m\n" +
"m.entrySet()";
String toFind = "entrySet";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Set<java.util.Map$Entry<java.lang.String,java.lang.ref.WeakReference<java.util.List<java.lang.String>>>>");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics7() {
String contents =
"class MyMap<K,V> extends HashMap<V,K>{ }\n" +
"MyMap<Integer,Class> m\n" +
"m.get";
String toFind = "get";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
// GRECLIPSE-997
@Test
public void testNestedGenerics8() {
String contents =
"class MyMap<K,V> extends HashMap<K,V>{\n" +
"Map<V,Class<K>> val}\n" +
"MyMap<Integer,Class> m\n" +
"m.val";
String toFind = "val";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.lang.Class,java.lang.Class<java.lang.Integer>>");
}
// GRECLIPSE-1131
@Test
public void testEachOnNonIterables1() {
String contents = "1.each { it }";
String toFind = "it";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
// GRECLIPSE-1131
@Test
public void testEachOnNonIterables2() {
String contents = "each { it }";
String toFind = "it";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "Search");
}
// GRECLIPSE-1131
@Test
public void testEachOnNonIterables3() {
String contents = "1.reverseEach { it }";
String toFind = "it";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.lang.Integer");
}
@Test
public void testInferringGetClass1() {
String contents = "''.getClass()", toFind = "getClass";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Class<? extends java.lang.String>");
}
@Test
public void testInferringGetClass2() {
String contents = "[''].getClass()", toFind = "getClass";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Class<? extends java.util.List<java.lang.String>>");
}
@Test
public void testInferringGetClass3() {
String contents = "[a:''].getClass()", toFind = "getClass";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Class<? extends java.util.Map<java.lang.String,java.lang.String>>");
}
@Test
public void testInferringList1() {
String contents = "def x = 9\ndef xxx = [x]\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.Integer>");
}
@Test
public void testInferringList2() {
String contents = "def x = 9\ndef xxx = [x, '']\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.Integer>");
}
@Test
public void testInferringList3() {
String contents = "def x = 9\ndef xxx = [x+9*8, '']\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.Integer>");
}
@Test
public void testInferringRange1() {
String contents = "def x = 9\ndef xxx = x..x\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "groovy.lang.Range<java.lang.Integer>");
}
@Test
public void testInferringRange2() {
String contents = "def x = 9\ndef xxx = (x*1)..x\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "groovy.lang.Range<java.lang.Integer>");
}
@Test
public void testInferringMap1() {
String contents = "def x = 9\ndef y = false\ndef xxx = [(x):y]\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.lang.Integer,java.lang.Boolean>");
}
@Test
public void testInferringMap2() {
String contents = "def x = 9\ndef y = false\ndef xxx = [(x+x):!y]\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.lang.Integer,java.lang.Boolean>");
}
@Test
public void testInferringMap3() {
String contents = "def x = 9\ndef y = false\ndef xxx = [(x+x):!y, a:'a', b:'b']\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.lang.Integer,java.lang.Boolean>");
}
@Test
public void testInferringMap4() {
String contents = "def x = 9\ndef y = false\ndef xxx = [[(x+x):!y, a:'a', b:'b']]\nxxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.util.Map<java.lang.Integer,java.lang.Boolean>>");
}
@Test
public void testInferringMap5() {
String contents = "def x = [ ['a':11, 'b':12] : ['a':21, 'b':22] ]\n" +
"def xxx = x\n" +
"xxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.Map<java.util.Map<java.lang.String,java.lang.Integer>,java.util.Map<java.lang.String,java.lang.Integer>>");
}
@Test
public void testInferringMap6() {
String contents = "def x = [ ['a':11, 'b':12], ['a':21, 'b':22] ]\n" +
"def xxx = x*.a\n" +
"xxx";
String toFind = "xxx";
int start = contents.lastIndexOf(toFind);
int end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.Integer>");
}
@Test // GRECLIPSE-1696: Generic method type inference with @CompileStatic
public void testMethod1() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"import groovy.transform.CompileStatic\n" +
"class A {\n" +
" public <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" @CompileStatic\n" +
" static void main(String[] args) {\n" +
" A a = new A()\n" +
" def val = a.myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Generic method type inference without @CompileStatic
@Test
public void testMethod2() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"class A {\n" +
" public <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" static void main(String[] args) {\n" +
" A a = new A()\n" +
" def val = a.myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Generic method without object type inference with @CompileStatic
@Test
public void testMethod3() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"import groovy.transform.CompileStatic\n" +
"class A {\n" +
" public <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" @CompileStatic\n" +
" def m() {\n" +
" def val = myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Generic method type without object inference without @CompileStatic
@Test
public void testMethod4() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"class A {\n" +
" public <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" def m() {\n" +
" def val = myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// GRECLIPSE-1129
// Static generic method type inference with @CompileStatic
@Test
public void testStaticMethod1() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"class A {\n" +
" static <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" @groovy.transform.CompileStatic\n" +
" static void main(String[] args) {\n" +
" def val = A.myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Static generic method type inference without @CompileStatic
@Test
public void testStaticMethod2() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"class A {\n" +
" static <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" static void main(String[] args) {\n" +
" def val = A.myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Static generic method without class type inference with @CompileStatic
@Test
public void testStaticMethod3() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"class A {\n" +
" static <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" @groovy.transform.CompileStatic\n" +
" def m() {\n" +
" def val = myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Static generic method without class type inference without @CompileStatic
@Test
public void testStaticMethod4() {
assumeTrue(isAtLeastGroovy(20));
String contents =
"class A {\n" +
" static <T> T myMethod(Class<T> claz) {\n" +
" return null\n" +
" }\n" +
" def m() {\n" +
" def val = myMethod(String.class)\n" +
" val.trim()\n" +
" }\n" +
"}";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "java.lang.String");
}
// Test according GRECLIPSE-1129 description
@Test
public void testStaticMethod5() {
assumeTrue(isAtLeastGroovy(23));
String contents =
"class A {}\n" +
"class B extends A {}\n" +
"static <T extends A> T loadSomething(T t) {\n" +
" return t\n" +
"}\n" +
"def val = loadSomething(new B())";
int start = contents.lastIndexOf("val");
int end = start + "val".length();
assertType(contents, start, end, "B");
}
// Additional test according comment to PR #75
// Actually type should not be inferred for fields with type def
@Test
public void testStaticMethod6() {
String contents =
"class A {}\n" +
"class B extends A {}\n" +
"class C {\n" +
" static <T extends A> T loadSomething(T t) {\n" +
" return t\n" +
" }\n" +
" def col = loadSomething(new B())\n" +
" def m() { col }" +
"}";
int start = contents.lastIndexOf("col");
int end = start + "col".length();
assertType(contents, start, end, "java.lang.Object");
}
@Test
public void testStaticMethod7() {
// Collections: public static final <T> List<T> singletonList(T)
String contents = "List<String> list = Collections.singletonList('')";
String toFind = "singletonList";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.String>");
MethodNode m = assertDeclaration(contents, start, end, "java.util.Collections", toFind, DeclarationKind.METHOD);
assertEquals("Parameter type should be resolved", "java.lang.String", printTypeName(m.getParameters()[0].getType()));
}
@Test @Ignore
public void testStaticMethod8() { // no help from parameters
// Collections: public static final <T> List<T> emptyList()
String contents = "List<String> list = Collections.emptyList()";
String toFind = "emptyList";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.String>");
}
@Test
public void testStaticMethod9() {
// Collections: public static final <T> List<T> emptyList()
String contents = "def list = Collections.<String>emptyList()";
String toFind = "list";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.util.List<java.lang.String>");
}
@Test
public void testStaticMethod10() {
// Collection: public boolean removeAll(Collection<?>)
String contents = "List<String> list = ['1','2']; list.removeAll(['1'])";
String toFind = "removeAll";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Boolean");
MethodNode m = assertDeclaration(contents, start, end, "java.util.Collection<java.lang.String>", toFind, DeclarationKind.METHOD);
assertEquals("Parameter type should be resolved", "java.util.Collection<?>", printTypeName(m.getParameters()[0].getType()));
}
@Test
public void testStaticMethod11() {
// Collection: public boolean addAll(Collection<? extends E>)
String contents = "List<String> list = ['1','2']; list.addAll(['3'])";
String toFind = "addAll";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Boolean");
MethodNode m = assertDeclaration(contents, start, end, "java.util.Collection<java.lang.String>", toFind, DeclarationKind.METHOD);
assertEquals("Parameter type should be resolved", "java.util.Collection<? extends java.lang.String>", printTypeName(m.getParameters()[0].getType()));
}
@Test
public void testStaticMethodOverloads1() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence> T b(T seq) { seq }\n" +
"}\n" +
"def result = A.b([])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Object"); // should not satisfy bounds of T
}
@Test
public void testStaticMethodOverloads2() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence> T b(T seq) { seq }\n" +
"}\n" +
"def result = A.b('')";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.String"); // should satisfy bounds of T
}
@Test
public void testStaticMethodOverloads3() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence & Serializable> T b(T seq) { seq }\n" +
"}\n" +
"def result = A.b([])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Object"); // should not satisfy bounds of T
}
@Test
public void testStaticMethodOverloads4() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence & Iterable> T b(T seq) { seq }\n" +
"}\n" +
"def result = A.b('')";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Object"); // should not satisfy bounds of T
}
@Test
public void testStaticMethodOverloads5() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence & Serializable> T b(T seq) { seq }\n" +
"}\n" +
"def result = A.b('')";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.String"); // should satisfy bounds of T
}
@Test
public void testStaticMethodOverloads6() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence> T b(T[] seq) { seq }\n" +
"}\n" +
"def result = A.b(new Object[0])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Object"); // should not satisfy bounds of T
}
@Test
public void testStaticMethodOverloads7() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence> T b(T[] seq) { seq }\n" +
"}\n" +
"def result = A.b(new String[0])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.String"); // should satisfy bounds of T
}
@Test
public void testStaticMethodOverloads8() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence & Serializable> T b(T[] seq) { seq }\n" +
"}\n" +
"def result = A.b(new Object[0])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Object"); // should not satisfy bounds of T
}
@Test
public void testStaticMethodOverloads9() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence & Iterable> T b(T[] seq) { seq }\n" +
"}\n" +
"def result = A.b(new String[0])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.Object"); // should not satisfy bounds of T
}
@Test
public void testStaticMethodOverloads10() {
String contents =
"class A {\n" +
" static Object b(Object obj) { obj }\n" +
" static <T extends CharSequence & Serializable> T b(T[] seq) { seq }\n" +
"}\n" +
"def result = A.b(new String[0])";
String toFind = "result";
int start = contents.indexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.String"); // should satisfy bounds of T
}
@Test
public void testStaticMethodOverloads11() {
String contents =
"class Preconditions {\n" +
" static <T> T checkNotNull(T ref) { null }\n" +
" static <T> T checkNotNull(T ref, Object errorMessage) { null }\n" +
" static <T> T checkNotNull(T ref, String errorMessageTemplate, Object arg1) { null }\n" +
" static <T> T checkNotNull(T ref, String errorMessageTemplate, Object arg1, Object arg2) { null }\n" +
" static <T> T checkNotNull(T ref, String errorMessageTemplate, Object... errorMessageArgs) { null }\n" +
"}\n" +
"String s = Preconditions.checkNotNull('blah', 'Should not be null')";
String toFind = "checkNotNull";
int start = contents.lastIndexOf(toFind), end = start + toFind.length();
assertType(contents, start, end, "java.lang.String"); // return type should be resolved
MethodNode m = assertDeclaration(contents, start, end, "Preconditions", toFind, DeclarationKind.METHOD);
assertEquals("Parameter type should be resolved", "java.lang.String", printTypeName(m.getParameters()[0].getType()));
assertEquals("Second overload should be selected", "java.lang.Object", printTypeName(m.getParameters()[1].getType()));
}
@Test @Ignore
public void testJira1718() throws Exception {
// the type checking script
IPath robotPath = env.addPackage(project.getFolder("src").getFullPath(), "p2");
env.addGroovyClass(robotPath, "Renderer",
"package p2\n" +
"interface Renderer<T> {\n" +
"Class<T> getTargetType()\n" +
"void render(T object, String context)\n" +
"}\n");
env.addGroovyClass(robotPath, "AbstractRenderer",
"package p2\n" +
"abstract class AbstractRenderer<T> implements Renderer<T> {\n" +
"private Class<T> targetType\n" +
"public Class<T> getTargetType() {\n" +
"return null\n" +
"}\n" +
"public void render(T object, String context) {\n" +
"}\n" +
"}\n");
env.addGroovyClass(robotPath, "DefaultRenderer",
"package p2\n" +
"class DefaultRenderer<T> implements Renderer<T> {\n" +
"Class<T> targetType\n" +
"DefaultRenderer(Class<T> targetType) {\n" +
"this.targetType = targetType\n" +
"}\n" +
"public Class<T> getTargetType() {\n" +
"return null\n" +
"}\n" +
"public void render(T object, String context) {\n" +
"}\n" +
"}");
env.addGroovyClass(robotPath, "RendererRegistry",
"package p2\n" +
"interface RendererRegistry {\n" +
"public <T> Renderer<T> findRenderer(String contentType, T object)\n" +
"}\n");
env.addGroovyClass(robotPath, "DefaultRendererRegistry",
"package p2\n" +
"class DefaultRendererRegistry implements RendererRegistry {\n" +
"def <T> Renderer<T> findRenderer(String contentType, T object) {\n" +
"return null\n" +
"}\n" +
"}\n");
IPath path = env.addGroovyClass(robotPath, "LinkingRenderer",
"package p2\n" +
"import groovy.transform.CompileStatic\n" +
"@CompileStatic\n" +
"class LinkingRenderer<T> extends AbstractRenderer<T> {\n" +
"public void render(T object, String context) {\n" +
"DefaultRendererRegistry registry = new DefaultRendererRegistry()\n" +
"Renderer htmlRenderer = registry.findRenderer(\"HTML\", object)\n" +
"if (htmlRenderer == null) {\n" +
"htmlRenderer = new DefaultRenderer(targetType)\n" +
"}\n" +
"htmlRenderer.render(object, context)\n" +
"}\n" +
"}\n");
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
Set<IProblem> problems = ReconcilerUtils.reconcile(JavaCore.createCompilationUnitFrom(file));
assertTrue(problems.isEmpty());
}
}