我如何确保所需的导入包含在 Xtend 活动注释处理器生成的 java 输出中?
How can I ensure that required imports are included in java output generated by Xtend active Annotation Processor?
我正在构建一个活动注释以从我的 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 源中使用它导入包 and 来解决这个问题,但我希望我的活动注释能够做到正确导入。这可能吗?
您可以在模板表达式中使用TypeReferenceProvider.newTypeReference()
:
WebElement webElement = driver.findElement(«By.newTypeReference».xpath("«xpa»"));
其他类型是自动导入的,因为它们可能被处理后的类型引用(例如from by field,by method return type or parameter type等)。
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();
}
}
我正在构建一个活动注释以从我的 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 源中使用它导入包 and 来解决这个问题,但我希望我的活动注释能够做到正确导入。这可能吗?
您可以在模板表达式中使用TypeReferenceProvider.newTypeReference()
:
WebElement webElement = driver.findElement(«By.newTypeReference».xpath("«xpa»"));
其他类型是自动导入的,因为它们可能被处理后的类型引用(例如from by field,by method return type or parameter type等)。
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();
}
}