如何确保Xtend活动注释处理器生成的java输出中包含所需的导入?

时间:2016-05-03 12:28:36

标签: java eclipse annotations xtend

我正在构建一个活动注释来摆脱我的Xtend源文件中的一些样板。

以下是我的AbstractFieldProcessor的源代码片段。

package dynamic

import java.lang.annotation.ElementType
import java.lang.annotation.Target
import org.eclipse.xtend.lib.macro.AbstractFieldProcessor
import org.eclipse.xtend.lib.macro.Active
import org.eclipse.xtend.lib.macro.TransformationContext
import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration


@Target(ElementType.FIELD)
@Active(DynamicCarmenFieldProcessor)
annotation DynamicCarmenField 
{
    String xpath
    String prefix;
    String suffix;
}

class DynamicCarmenFieldProcessor extends AbstractFieldProcessor {



    override doTransform(MutableFieldDeclaration field, extension TransformationContext context) 
    {   



        if (!field.type.toString.equals("WebElement"))
            field.addError("Only Type WebElement is supported by @Dynamic")

        if (field.initializer != null)
            field.addError("Initialisers are not supported by @Dynamic ")

        var annotations = field.getAnnotations()

        var xpath = ""; 
        var suffix = "";
        var prefix = "";

        for(annotation:annotations)
        {
            if(annotation.annotationTypeDeclaration.simpleName == "DynamicCarmenField")
            {

                xpath  = annotation.getStringValue("xpath")
                suffix = annotation.getStringValue("suffix")    
                prefix = annotation.getStringValue("prefix")            
            }           
        }

        val xpa = xpath
        val suf = suffix
        val pre = prefix


        field.declaringType.addMethod('click' + field.simpleName.toFirstUpper)
        [

            body = 
            '''
                WebElement webElement = driver.findElement(By.xpath("«xpa»"));
                String dependentOnId = webElement.getAttribute("id");
                String «field.simpleName»Id ="«pre»"+ dependentOnId +"«suf»";
                «field.simpleName» = driver.findElement(By.id(«field.simpleName»Id));
                «field.simpleName».click();
            '''
        ]


        field.declaringType.addMethod('set'+ field.simpleName.toFirstUpper +'Input' )
        [


            var stringType = context.findTypeGlobally("String")
            addParameter("values",context.newTypeReference(stringType))
            body=
            '''
                this.click«field.simpleName.toFirstUpper»();
                «field.simpleName»Input.sendKeys(values);
            '''
        ]

    }







}

此代码没问题。现在我尝试在下面的TestFile中使用它,我收到一条错误消息。我已经确定问题是因为生成的Java代码不包含所有导入。

package dynamic

import org.openqa.selenium.WebDriver
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.FindBy


class DynamicCarmenFieldExample
{
    WebDriver driver
    @DynamicCarmenField(xpath="//table[@datatable='1' and @summary!='Question Administration']" , prefix="1", suffix="_Sequence")
    WebElement answerSequenceField
    @FindBy(id="1_Sequence")
    WebElement answerSequenceFieldInput




}

以下是生成的Java代码。

import dynamic.DynamicCarmenField;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

@SuppressWarnings("all")
public class DynamicCarmenFieldExample {
  private WebDriver driver;

  @DynamicCarmenField(xpath = "//table[@datatable=\'1\' and @summary!=\'Question Administration\']", prefix = "1", suffix = "_Sequence")
  private WebElement answerSequenceField;

  @FindBy(id = "1_Sequence")
  private WebElement answerSequenceFieldInput;

  public void clickAnswerSequenceField() {
    WebElement webElement = driver.findElement(By.xpath("//table[@datatable='1' and @summary!='Question Administration']"));
    String dependentOnId = webElement.getAttribute("id");
    String answerSequenceFieldId ="1"+ dependentOnId +"_Sequence";
    answerSequenceField = driver.findElement(By.id(answerSequenceFieldId));
    answerSequenceField.click();
  }

  public void setAnswerSequenceFieldInput(final String values) {
    this.clickAnswerSequenceField();
    answerSequenceFieldInput.sendKeys(values);
  }
}

问题在于代码

import org.openqa.selenium.By
生成的Java中缺少

。代码未检测到它需要包含在生成的java文件中。我知道我可以通过在Xtend源中使用它导入包 来解决这个问题,但我希望我的活动注释能够正确地进行导入。这可能吗?

1 个答案:

答案 0 :(得分:1)

您可以在模板表达式中使用TypeReferenceProvider.newTypeReference()

WebElement webElement = driver.findElement(«By.newTypeReference».xpath("«xpa»"));

其他类型是自动导入的,因为它们可能是由处理类型引用的(例如,来自字段,方法返回类型或参数类型等)。

示例Xtend代码:

package test

import org.eclipse.xtend.lib.macro.Active
import org.eclipse.xtend.lib.macro.AbstractClassProcessor
import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration
import org.eclipse.xtend.lib.macro.TransformationContext
import java.util.Date

@Active(MyAnnotationProcessor)
annotation MyAnnotation
{
}

class MyAnnotationProcessor extends AbstractClassProcessor
{
    override doTransform(MutableClassDeclaration annotatedClass, extension TransformationContext context)
    {
        annotatedClass.addMethod("generatedMethod") [
            body = '''«Date.newTypeReference» date = new Date();'''
        ]
    }
}

引用的类型将在生成的Java代码中导入:

package test;

import java.util.Date;
import test.MyAnnotation;

@MyAnnotation
@SuppressWarnings("all")
public class MyAnnotationTest {
  public void generatedMethod() {
    Date date = new Date();
  }
}