/* * 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.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.List; import org.codehaus.groovy.ast.AnnotatedNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.FieldNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.expr.ClassExpression; import org.codehaus.groovy.ast.stmt.ReturnStatement; import org.codehaus.jdt.groovy.model.GroovyCompilationUnit; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.ILocalVariable; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.groovy.tests.builder.BuilderTestSuite; import org.eclipse.jdt.core.tests.util.Util; import org.junit.Before; import org.junit.Test; public final class ASTTransformsTests extends BuilderTestSuite { @Before public void setUp() throws Exception { IPath projectPath = env.addProject("Project"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); env.addGroovyJars(projectPath); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); } @Test public void testDelegateAnnotationFromOtherField() throws Exception { createUnit("Other", "class Other {\n" + " @Delegate Date me\n" + " int compareTo(arg0) { }\n" + "}"); GroovyCompilationUnit unit = createUnit("ThisUnit", "Other"); env.fullBuild(); expectingNoProblems(); FieldNode field = getMeField(unit); assertAnnotation("groovy.lang.Delegate", field); } @Test public void testDelegateAnnotationFromOtherMethod() throws Exception { createUnit("Other", "class Other {\n" + " @Delegate Date me\n" + " @Newify int compareTo(arg0) { }\n" + "}"); GroovyCompilationUnit unit = createUnit("ThisUnit", "Other"); env.fullBuild(); expectingNoProblems(); MethodNode method = getMethod(unit,"compareTo"); assertAnnotation("groovy.lang.Newify", method); } @Test public void testSingletonAnnotationFromOtherClass() throws Exception { createUnit("Other", "@Singleton class Other { }"); GroovyCompilationUnit unit = createUnit("ThisUnit", "Other"); env.fullBuild(); expectingNoProblems(); ClassNode clazz = getClassFromScript(unit); assertAnnotation("groovy.lang.Singleton", clazz); } @Test public void testImmutableAnnotation1() throws Exception { GroovyCompilationUnit unit = createUnit("Thiz", "import groovy.transform.Immutable\n @Immutable class Thiz { String foo }"); env.fullBuild(); expectingNoProblems(); IType type = unit.getType("Thiz"); boolean foundConstructor = false; IMethod[] methods = type.getMethods(); for (IMethod method : methods) { if (method.isConstructor()) { if (foundConstructor) { fail("Should have found exactly one constructor"); } foundConstructor = true; ILocalVariable[] parameters = method.getParameters(); assertEquals("Should have exactly one argument to constructor.", 1, parameters.length); assertEquals("Should be type string", "QString;", parameters[0].getTypeSignature()); } } if (!foundConstructor) { fail("Should have found exactly one constructor"); } } @Test public void testImmutableAnnotation1a() throws Exception { GroovyCompilationUnit unit = createUnit("Thiz", "@groovy.transform.Immutable class Thiz { String foo }"); env.fullBuild(); expectingNoProblems(); IType type = unit.getType("Thiz"); boolean foundConstructor = false; IMethod[] methods = type.getMethods(); for (IMethod method : methods) { if (method.isConstructor()) { if (foundConstructor) { fail("Should have found exactly one constructor"); } foundConstructor = true; ILocalVariable[] parameters = method.getParameters(); assertEquals("Should have exactly one argument to constructor.", 1, parameters.length); assertEquals("Should be type string", "QString;", parameters[0].getTypeSignature()); } } if (!foundConstructor) { fail("Should have found exactly one constructor"); } } @Test public void testImmutableAnnotation2() throws Exception { GroovyCompilationUnit unit = createUnit("Thiz", "import groovy.transform.Immutable\n @Immutable class Thiz { }"); env.fullBuild(); expectingNoProblems(); IType type = unit.getType("Thiz"); int constructorCount = 0; IMethod[] methods = type.getMethods(); for (IMethod method : methods) { if (method.isConstructor()) { constructorCount++; } } assertEquals("Should have found no constructors", 0, constructorCount); } @Test public void testImmutableAnnotation3() throws Exception { createUnit("p", "Immutable", "package p\n@interface Immutable { }"); GroovyCompilationUnit unit = createUnit("Thiz", "import p.Immutable\n@Immutable class Thiz { String foo }"); env.fullBuild(); expectingNoProblems(); IType type = unit.getType("Thiz"); IMethod[] methods = type.getMethods(); int constructorCount = 0; for (IMethod method : methods) { if (method.isConstructor()) { constructorCount++; } } assertEquals("Should have found no constructors", 0, constructorCount); } //-------------------------------------------------------------------------- private void assertAnnotation(String aName, AnnotatedNode node) { assertEquals("Expecting @" + aName + " but no annotations found.", 1, node.getAnnotations().size()); assertEquals(aName, node.getAnnotations().get(0).getClassNode().getName()); } private FieldNode getMeField(GroovyCompilationUnit unit) { ClassNode clazz = getClassFromScript(unit); clazz.getFields(); // force lazy initialization return clazz.getField("me"); } private MethodNode getMethod(GroovyCompilationUnit unit,String name) { ClassNode clazz = getClassFromScript(unit); clazz.getFields(); // force lazy initialization List<MethodNode> ms = clazz.getMethods(); for (MethodNode m: ms) { if (m.getName().equals(name)) { return m; } } return null; } private ClassNode getClassFromScript(GroovyCompilationUnit unit) { return ((ClassExpression) ((ReturnStatement) unit.getModuleNode().getStatementBlock().getStatements().get(0)).getExpression()).getType(); } private GroovyCompilationUnit createUnit(String name, String contents) { IPath path = env.addGroovyClass(ResourcesPlugin.getWorkspace().getRoot().getProject("Project").getFolder("src").getFullPath(), name, contents); return (GroovyCompilationUnit) JavaCore.createCompilationUnitFrom(env.getWorkspace().getRoot().getFile(path)); } private GroovyCompilationUnit createUnit(String pkg, String name, String contents) { IPath pkgPath = env.addPackage(ResourcesPlugin.getWorkspace().getRoot().getProject("Project").getFolder("src").getFullPath(), pkg); IPath path = env.addGroovyClass(pkgPath, name, contents); return (GroovyCompilationUnit) JavaCore.createCompilationUnitFrom(env.getWorkspace().getRoot().getFile(path)); } }