/** * Copyright (c) 2014 Codetrails GmbH. * 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: * Andreas Sewe - Initial API and implementation */ package org.eclipse.recommenders.rcp.utils; import static org.eclipse.recommenders.testing.CodeBuilder.*; import static org.eclipse.recommenders.utils.names.VmTypeName.get; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.assertThat; import java.util.Collection; import java.util.LinkedList; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.recommenders.utils.names.ITypeName; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import com.google.common.collect.Lists; @RunWith(Parameterized.class) @SuppressWarnings("restriction") public class CompilerBindingsToTypeNameTest { private final CharSequence code; private final ITypeName expected; public CompilerBindingsToTypeNameTest(String description, CharSequence code, ITypeName expected) { this.code = code; this.expected = expected; } @Parameters(name = "{index}: {0}") public static Collection<Object[]> scenarios() { LinkedList<Object[]> scenarios = Lists.newLinkedList(); // Real-world scenarios scenarios.add(scenario("Primitive type", method("$int i = 0;"), get("I"))); scenarios.add(scenario("Reference type", method("$Object o = null;"), get("Ljava/lang/Object"))); scenarios.add(scenario("Array of primitives", method("$int[] is = null;"), get("[I"))); scenarios.add(scenario("Array of objects", method("$Object[] os = null;"), get("[Ljava/lang/Object"))); scenarios.add(scenario("Raw generic type", method("$Collection c = 0;"), get("Ljava/util/Collection"))); scenarios.add(scenario("Void type", classbody("$void method() {}"), get("V"))); // Synthetic scenarios scenarios.add(scenario("Type is type parameter of declaring class", classbody("Example<T>", "$T t = null;"), get("Ljava/lang/Object"))); scenarios.add(scenario("Type is upper-bounded type parameter of declaring class", classbody("Example<N extends Number>", "$N n = null"), get("Ljava/lang/Number"))); scenarios.add(scenario("Type is upper-bounded type parameter of declaring class (superfluous bound of Object)", classbody("Example<O extends Object>", "$O o = null;"), get("Ljava/lang/Object"))); scenarios.add(scenario("Method argument is upper-bounded type parameter of declaring class (multiple bounds)", classbody("Example<N extends Number & Comparable>", "$N n = null;"), get("Ljava/lang/Number"))); scenarios.add(scenario( "Type is upper-bounded type parameter of declaring class (bound is parameterized itself)", classbody("Example<L extends List<String>>", "$L l = null;"), get("Ljava/util/List"))); return scenarios; } private static Object[] scenario(String description, CharSequence code, ITypeName expected) { return new Object[] { description, code, expected }; } @Test public void test() throws Exception { TypeBinding binding = getBinding(code); ITypeName actual = CompilerBindings.toTypeName(binding).get(); assertThat(actual, is(equalTo(expected))); } private static TypeBinding getBinding(CharSequence code) throws Exception { return getBinding(CompilerBindingsTestUtils.getCompilerAstNode(code)); } private static TypeBinding getBinding(ASTNode node) { if (node instanceof SingleTypeReference) { return ((SingleTypeReference) node).resolvedType; } else { throw new IllegalArgumentException(node.toString()); } } }