下面列出了javax.lang.model.element.ElementKind#CLASS 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@TriggerPatterns({
@TriggerPattern(value="$mods$ java.util.logging.Logger $LOG;"), //NOI18N
@TriggerPattern(value="$mods$ java.util.logging.Logger $LOG = $init;") //NOI18N
})
public static ErrorDescription checkLoggerDeclaration(HintContext ctx) {
Element e = ctx.getInfo().getTrees().getElement(ctx.getPath());
if (e != null && e.getEnclosingElement().getKind() == ElementKind.CLASS &&
(!e.getModifiers().contains(Modifier.STATIC) || !e.getModifiers().contains(Modifier.FINAL)) &&
ctx.getInfo().getElementUtilities().outermostTypeElement(e) == e.getEnclosingElement()
) {
return ErrorDescriptionFactory.forName(
ctx,
ctx.getPath(),
NbBundle.getMessage(LoggerNotStaticFinal.class, "MSG_LoggerNotStaticFinal_checkLoggerDeclaration", e), //NOI18N
new LoggerNotStaticFinalFix(NbBundle.getMessage(LoggerNotStaticFinal.class, "MSG_LoggerNotStaticFinal_checkLoggerDeclaration_fix", e), TreePathHandle.create(e, ctx.getInfo())).toEditorFix() //NOI18N
);
} else {
return null;
}
}
public static String isDeclaredAsJavaBean(TypeElement clazz) {
if (ElementKind.CLASS != clazz.getKind()) {
return PaletteUtils.getBundleString("MSG_notAClass"); // NOI18N
}
Set<javax.lang.model.element.Modifier> mods = clazz.getModifiers();
if (mods.contains(javax.lang.model.element.Modifier.ABSTRACT)) {
return PaletteUtils.getBundleString("MSG_abstractClass"); // NOI18N
}
if (!mods.contains(javax.lang.model.element.Modifier.PUBLIC)) {
return PaletteUtils.getBundleString("MSG_notPublic"); // NOI18N
}
for (Element member : clazz.getEnclosedElements()) {
mods = member.getModifiers();
if (ElementKind.CONSTRUCTOR == member.getKind() &&
mods.contains(javax.lang.model.element.Modifier.PUBLIC) &&
((ExecutableElement) member).getParameters().isEmpty()) {
return null;
}
}
return PaletteUtils.getBundleString("MSG_noPublicConstructor"); // NOI18N
}
private boolean isMethodOfStarlarkExposedConfigurationFragment(
ExecutableElement methodElement) {
if (methodElement.getEnclosingElement().getKind() != ElementKind.CLASS) {
return false;
}
Element classElement = methodElement.getEnclosingElement();
// If configurationFragmentType is null, then BuildConfiguration.Fragment isn't even included
// in the current build, so the class clearly does not depend on it.
if (configurationFragmentType == null
|| !typeUtils.isAssignable(classElement.asType(), configurationFragmentType.asType())) {
return false;
}
return true;
}
/**
* Must be run under MDR transaction!
*/
public javax.lang.model.element.Element getJavaClass() {
TreePath path = null;
// try {
// path = getCompletionTreePath(getController(), endOffset, COMPLETION_QUERY_TYPE);
// } catch (IOException ex) {
// Exceptions.printStackTrace(ex);
// }
javax.lang.model.element.Element el = null;
try {
getController().toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
while ((el == null || !(ElementKind.CLASS == el.getKind() || ElementKind.INTERFACE == el.getKind())) && path != null) {
path.getCompilationUnit().getTypeDecls();
el = getController().getTrees().getElement(path);
path = path.getParentPath();
}
return el;
}
private static Element handlePossibleAnonymousInnerClass(CompilationInfo info, final Element el) {
Element encl = el.getEnclosingElement();
Element doubleEncl = encl != null ? encl.getEnclosingElement() : null;
if ( doubleEncl != null
&& !doubleEncl.getKind().isClass()
&& !doubleEncl.getKind().isInterface()
&& doubleEncl.getKind() != ElementKind.PACKAGE
&& encl.getKind() == ElementKind.CLASS) {
TreePath enclTreePath = info.getTrees().getPath(encl);
Tree enclTree = enclTreePath != null ? enclTreePath.getLeaf() : null;
if (enclTree != null && TreeUtilities.CLASS_TREE_KINDS.contains(enclTree.getKind()) && enclTreePath.getParentPath().getLeaf().getKind() == Tree.Kind.NEW_CLASS) {
NewClassTree nct = (NewClassTree) enclTreePath.getParentPath().getLeaf();
if (nct.getClassBody() != null) {
Element parentElement = info.getTrees().getElement(new TreePath(enclTreePath, nct.getIdentifier()));
if (parentElement == null || parentElement.getKind().isInterface()) {
return parentElement;
} else {
//annonymous innerclass extending a class. Find out which constructor is used:
TreePath superConstructorCall = new FindSuperConstructorCall().scan(enclTreePath, null);
if (superConstructorCall != null) {
return info.getTrees().getElement(superConstructorCall);
}
}
}
}
return null;//prevent jumps to incorrect positions
} else {
if (encl != null) {
return encl;
} else {
return el;
}
}
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!roundEnv.processingOver() && !fileCreated) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(GenerateLambda.class);
for (Element element : elements) {
if (element.getKind() == ElementKind.CLASS) {
GenerateLambda generateSignatureContainerAnnotation = element.getAnnotation(GenerateLambda.class);
generateCode(PACKAGE, INTERFACE_NAME, generateSignatureContainerAnnotation);
return true;
}
break;
}
}
return true;
}
private void processAddToFixPatch(RoundEnvironment roundEnv) throws IllegalArgumentException {
for (Element element : roundEnv.getElementsAnnotatedWith(AddToFixPatch.class)) {
if (element.getKind() != ElementKind.CLASS) {
throw new IllegalArgumentException(String.format("Only java class can be annotated with @%s",
AddToFixPatch.class.getSimpleName()));
}
TypeElement element1 = (TypeElement) element;
fieldSet.add(element1.getQualifiedName().toString());
}
}
FileObject doCreateFromTemplate(CompilationUnitTree cut) throws IOException {
ElementKind kind;
if ("package-info.java".equals(cut.getSourceFile().getName())) {
kind = ElementKind.PACKAGE;
} else if (cut.getTypeDecls().isEmpty()) {
kind = null;
} else {
switch (cut.getTypeDecls().get(0).getKind()) {
case CLASS:
kind = ElementKind.CLASS;
break;
case INTERFACE:
kind = ElementKind.INTERFACE;
break;
case ANNOTATION_TYPE:
kind = ElementKind.ANNOTATION_TYPE;
break;
case ENUM:
kind = ElementKind.ENUM;
break;
default:
Logger.getLogger(WorkingCopy.class.getName()).log(Level.SEVERE, "Cannot resolve template for {0}", cut.getTypeDecls().get(0).getKind());
kind = null;
}
}
FileObject template = FileUtil.getConfigFile(template(kind));
return doCreateFromTemplate(template, cut.getSourceFile());
}
protected ErrorDescription[] apply(TypeElement subject, ProblemContext ctx) {
ArrayList<ErrorDescription> errors = new ArrayList<ErrorDescription>();
AnnotationMirror annEntity = Utilities.findAnnotation(subject, ANNOTATION_WEBSERVICE);
if (subject.getKind() == ElementKind.CLASS && Utilities.getAnnotationAttrValue
(annEntity, ANNOTATION_ATTRIBUTE_SEI) != null) {
for (String aName : new String[]{
ANNOTATION_WEBMETHOD,
ANNOTATION_WEBPARAM,
ANNOTATION_WEBRESULT,
ANNOTATION_ONEWAY,
ANNOTATION_SOAPMESSAGEHANDLERS,
ANNOTATION_INITPARAM,
ANNOTATION_SOAPBINDING,
ANNOTATION_SOAPMESSAGEHANDLER}) {
AnnotationMirror wrongAnnon = Utilities.findAnnotation(subject, aName);
if (wrongAnnon != null) {
String label = NbBundle.getMessage(InvalidJSRAnnotations.class, "MSG_Invalid_JSR181Annotation");
Tree problemTree = ctx.getCompilationInfo().getTrees().getTree(subject, wrongAnnon);
Fix removeHC = new RemoveAnnotation(ctx.getFileObject(), subject, wrongAnnon);
ctx.setElementToAnnotate(problemTree);
errors.add(createProblem(subject, ctx, label, removeHC));
ctx.setElementToAnnotate(null);
}
}
}
return errors.isEmpty() ? null : errors.toArray(new ErrorDescription[errors.size()]);
}
/**
* Whether the given node represents static {@link Iterable} field where can be used operators.
* @param ccontext compilation context
* @param element element to examine
* @return {@code true} if the object is static {@link Iterable} field, {@code false} otherwise
* @since 1.26
*/
public static boolean isIterableElement(CompilationContext ccontext, Element element) {
if (element.getKind() == ElementKind.CLASS) {
return isSubtypeOf(ccontext, element.asType(), "java.lang.Iterable"); //NOI18N
} else if (element.getKind() == ElementKind.METHOD) {
TypeMirror returnType = ELTypeUtilities.getReturnType(ccontext, (ExecutableElement) element);
if (returnType.getKind() == TypeKind.ARRAY
|| isSubtypeOf(ccontext, returnType, "java.lang.Iterable")) { //NOI18N
return true;
}
} else if (element.getKind() == ElementKind.INTERFACE) {
return isSubtypeOf(ccontext, element.asType(), "java.lang.Iterable"); //NOI18N
}
return false;
}
/**
* Register a service.
* If the class does not have an appropriate signature, an error will be printed and the registration skipped.
* @param clazz the service implementation type (an error will be reported if not a {@link TypeElement})
* @param annotation the (top-level) annotation registering the service, for diagnostic purposes
* @param type the type to which the implementation must be assignable
* @param path a path under which to register, or "" if inapplicable
* @param position a position at which to register, or {@link Integer#MAX_VALUE} to skip
* @param supersedes possibly empty list of implementation to supersede
* @since 8.8
*/
protected final void register(
Element el, Class<? extends Annotation> annotation,
TypeMirror type, String path, int position, String... supersedes
) {
if (el.getKind() != ElementKind.CLASS) {
processingEnv.getMessager().printMessage(Kind.ERROR, annotation.getName() + " is not applicable to a " + el.getKind(), el);
return;
}
if (el.getEnclosingElement().getKind() == ElementKind.CLASS && !el.getModifiers().contains(Modifier.STATIC)) {
processingEnv.getMessager().printMessage(Kind.ERROR, "Inner class needs to be static to be annotated with @ServiceProvider", el);
return;
}
TypeElement clazz = (TypeElement) el;
String impl = processingEnv.getElementUtils().getBinaryName(clazz).toString();
String xface = processingEnv.getElementUtils().getBinaryName((TypeElement) processingEnv.getTypeUtils().asElement(type)).toString();
if (!processingEnv.getTypeUtils().isAssignable(clazz.asType(), type)) {
AnnotationMirror ann = findAnnotationMirror(clazz, annotation);
processingEnv.getMessager().printMessage(Kind.ERROR, impl + " is not assignable to " + xface,
clazz, ann, findAnnotationValue(ann, "service"));
return;
}
String rsrc = (path.length() > 0 ? "META-INF/namedservices/" + path + "/" : "META-INF/services/") + xface;
Boolean verify = verifiedClasses.get(clazz);
if (verify == null) {
verify = verifyServiceProviderSignature(clazz, annotation);
verifiedClasses.put(clazz, verify);
}
if (!verify) {
return;
}
registerImpl(clazz, impl, rsrc, position, supersedes);
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!roundEnv.processingOver() && !fileCreated) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(GenerateLambda.class);
for (Element element : elements) {
if (element.getKind() == ElementKind.CLASS) {
GenerateLambda generateSignatureContainerAnnotation = element.getAnnotation(GenerateLambda.class);
generateCode(PACKAGE, INTERFACE_NAME, generateSignatureContainerAnnotation);
return true;
}
break;
}
}
return true;
}
public List<Fix> run(final CompilationInfo info, String diagnosticKey, final int offset, TreePath treePath, Data<Object> data) {
TreePath path = deepTreePath(info, offset);
if (path == null) {
return null;
}
Map<Tree, Object> holder = data == null ? null : (Map)data.getData();
Object saved = null;
if (holder != null) {
saved = holder.get(path.getLeaf());
}
if (Boolean.TRUE == saved) {
return null;
}
Element e = info.getTrees().getElement(path);
final Tree leaf = path.getLeaf();
boolean isUsableElement = e != null && (e.getKind().isClass() || e.getKind().isInterface());
boolean containsDefaultMethod = saved == Boolean.FALSE;
boolean completingAnonymous = e != null && e.getKind() == ElementKind.CONSTRUCTOR &&
leaf.getKind() == Tree.Kind.NEW_CLASS;
TypeElement tel = findTypeElement(info, path);
if (!Utilities.isValidElement(tel)) {
return null;
}
List<Fix> fixes = new ArrayList<>();
if (TreeUtilities.CLASS_TREE_KINDS.contains(leaf.getKind()) || leaf.getKind().toString().equals(RECORD)) {
CompilationUnitTree cut = info.getCompilationUnit();
// do not offer for class declarations without body
long start = info.getTrees().getSourcePositions().getStartPosition(cut, leaf);
long end = info.getTrees().getSourcePositions().getEndPosition(cut, leaf);
for (Diagnostic d : info.getDiagnostics()) {
long position = d.getPosition();
if (d.getCode().equals(PREMATURE_EOF_CODE) && position > start && position < end) {
return null;
}
}
}
if (completingAnonymous) {
//if the parent of path.getLeaf is an error, the situation probably is like:
//new Runnable {}
//(missing '()' for constructor)
//do not propose the hint in this case:
final boolean[] parentError = new boolean[] {false};
new ErrorAwareTreePathScanner() {
@Override
public Object visitNewClass(NewClassTree nct, Object o) {
if (leaf == nct) {
parentError[0] = getCurrentPath().getParentPath().getLeaf().getKind() == Kind.ERRONEOUS;
}
return super.visitNewClass(nct, o);
}
}.scan(path.getParentPath(), null);
if (parentError[0]) {
// ignore
return null;
}
fixes.add(new ImplementAbstractMethodsFix(info, path, tel, containsDefaultMethod));
}
boolean someAbstract = false;
X: if (isUsableElement) {
for (ExecutableElement ee : ElementFilter.methodsIn(e.getEnclosedElements())) {
if (ee.getModifiers().contains(Modifier.ABSTRACT)) {
// make class abstract. In case of enums, suggest to implement the
// abstract methods on all enum values.
if (e.getKind() == ElementKind.ENUM) {
// cannot make enum abstract, but can generate abstract methods skeleton
// to all enum members
fixes.add(new ImplementOnEnumValues2(info, tel, containsDefaultMethod));
// avoid other possible fixes:
break X;
} else if (e.getKind().isClass()) {
someAbstract = true;
break;
}
}
}
// offer to fix all abstract methods
if (!someAbstract) {
fixes.add(new ImplementAbstractMethodsFix(info, path, tel, containsDefaultMethod));
}
if (e.getKind() == ElementKind.CLASS && e.getSimpleName() != null && !e.getSimpleName().contentEquals("")) {
fixes.add(new MakeAbstractFix(info, path, e.getSimpleName().toString()).toEditorFix());
}
}
if (e != null && e.getKind() == ElementKind.ENUM_CONSTANT) {
fixes.add(new ImplementAbstractMethodsFix(info, path, tel, containsDefaultMethod));
}
return fixes;
}
static boolean isClass(Element element) {
return element.getKind() == ElementKind.CLASS;
}
Encoding(TypeElement type) {
this.typeEncoding = type;
if (type.getKind() != ElementKind.CLASS || type.getNestingKind() != NestingKind.TOP_LEVEL) {
reporter.withElement(type).error("Encoding type '%s' should be top-level class", type.getSimpleName());
}
this.$$package = processing().getElementUtils().getPackageOf(type).getQualifiedName().toString();
this.name = type.getSimpleName().toString();
CharSequence source = SourceExtraction.extract(processing(), type);
if (source.length() == 0) {
reporter.withElement(type)
.error("No source code can be extracted for @Encoding class. Unsupported compilation mode");
}
this.imports = SourceExtraction.importsFrom(source);
this.sourceMapper = new SourceMapper(source);
this.typesReader = new TypeExtractor(types, type);
this.encodingSelfType = typesReader.get(type.asType());
addTypeParameters(type);
for (Element e : type.getEnclosedElements()) {
processMember(e);
}
if (postValidate()) {
provideSyntheticElements();
}
this.allElements = Iterables.concat(
Arrays.asList(
Iterables.filter(
Arrays.asList(
impl,
from,
toString,
hashCode,
equals,
build,
isInit),
Predicates.notNull()),
fields,
expose,
copy,
helpers,
builderFields,
builderHelpers,
builderInits));
this.linkage = new Linkage();
this.generatedImports = generatedImports();
}
@Override
public Collection<ErrorDescription> check(final JPAProblemContext ctx, final HintContext hc, final AttributeWrapper attrib) {
// Not applicable for embeddable classes, which do not have relationships.
if (ctx.isEmbeddable()) {
return null;
}
final Element typeElement = ctx.getCompilationInfo().getTypes().asElement(attrib.getType());
final ArrayList<ErrorDescription> ret = new ArrayList<>();
if (typeElement != null && typeElement.getKind() == ElementKind.CLASS) {
try {
MetadataModel<EntityMappingsMetadata> model = ModelUtils.getModel(hc.getInfo().getFileObject());
model.runReadAction(new MetadataModelAction<EntityMappingsMetadata, Void>() {
@Override
public Void run(EntityMappingsMetadata metadata) {
Entity entity = ModelUtils.getEntity(ctx.getMetaData(), ((TypeElement) typeElement));
if (entity != null) {
//not appliable to derived ids, it's already attribute and relationship
//if id and have one-one and many-one
List<? extends AnnotationMirror> anns = attrib.getJavaElement().getAnnotationMirrors();
if (anns != null) {
boolean id = false;
boolean rel = false;
for (AnnotationMirror ann : anns) {
ann.getAnnotationType().asElement().toString();
if (ann.getAnnotationType().asElement().toString().equals("javax.persistence.Id")) {//NOI18N
id = true;//NOI18N
} else if (ann.getAnnotationType().asElement().toString().equals("javax.persistence.ManyToOne") || ann.getAnnotationType().asElement().toString().equals("javax.persistence.OneToOne")) {//NOI18N
rel = true;//NOI18N
}
if (id && rel) {
return null;//in future more strict verification may be done
}
}
}
//other cases
ElementHandle<TypeElement> classHandle = ElementHandle.create(ctx.getJavaClass());
ElementHandle<Element> elemHandle = ElementHandle.create(attrib.getJavaElement());
String remoteClassName = ((TypeElement) typeElement).getQualifiedName().toString();
Fix fix1 = new CreateUnidirOneToOneRelationship(ctx.getFileObject(),
classHandle, elemHandle);
Fix fix2 = new CreateOneToOneRelationshipHint(ctx.getFileObject(),
classHandle,
ctx.getAccessType(),
attrib.getName(),
remoteClassName);
Fix fix3 = new CreateUnidirManyToOneRelationship(ctx.getFileObject(),
classHandle,
elemHandle);
Fix fix4 = new CreateManyToOneRelationshipHint(ctx.getFileObject(),
classHandle,
ctx.getAccessType(),
attrib.getName(),
remoteClassName);
Tree elementTree = ctx.getCompilationInfo().getTrees().getTree(attrib.getJavaElement());
Utilities.TextSpan underlineSpan = Utilities.getUnderlineSpan(
ctx.getCompilationInfo(), elementTree);
ErrorDescription error = ErrorDescriptionFactory.forSpan(
hc,
underlineSpan.getStartOffset(),
underlineSpan.getEndOffset(),
NbBundle.getMessage(RelationshipForEntityTypeAttrDefined.class, "MSG_EntityRelationNotDefined"),
fix1, fix2, fix3, fix4);
ret.add(error);
}
return null;
}
});
} catch (IOException ex) {
}
}
return ret;
}
private void process(Element e, PaletteItemRegistration pir) throws LayerGenerationException {
LayerBuilder builder = layer(e);
TypeMirror activeEditorDrop = type(ActiveEditorDrop.class);
LayerBuilder.File f = builder.file(pir.paletteid() + "/" + pir.category() + "/" + pir.itemid() + ".xml");
StringBuilder paletteFile = new StringBuilder();
paletteFile.append("<!DOCTYPE editor_palette_item PUBLIC '-//NetBeans//Editor Palette Item 1.1//EN' 'http://www.netbeans.org/dtds/editor-palette-item-1_1.dtd'>\n");
paletteFile.append("<editor_palette_item version=\"1.1\">\n");
if (pir.body().isEmpty()) {
// body empty we need a activeEditorDrop
if (e.getKind() == ElementKind.CLASS && isAssignable(e.asType(), activeEditorDrop)) {
String className = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
paletteFile.append(" <class name=\"").append(className).append("\"/>\n");
} else {
throw new LayerGenerationException("Class annotated with @PaletteItemRegistration has to implements ActiveEditorDrop", e);
}
} else {
// body not empty put info
paletteFile.append("<body> <![CDATA[");
paletteFile.append(pir.body());
paletteFile.append("]]> </body>\n");
}
// icon shoud be in classpath
if (!pir.icon16().isEmpty()) {
builder.validateResource(pir.icon16(), e, pir, "icon16", true);
paletteFile.append("<icon16 urlvalue=\"").append(pir.icon16()).append("\" />\n");
} else {
throw new LayerGenerationException("Icon 16 must be set ", e);
}
if (!pir.icon32().isEmpty()) {
builder.validateResource(pir.icon32(), e, pir, "icon32", true);
paletteFile.append("<icon32 urlvalue=\"").append(pir.icon32()).append("\" />\n");
} else {
throw new LayerGenerationException("Icon 32 must be set ", e);
}
paletteFile.append("<inline-description>");
paletteFile.append("<display-name>");
paletteFile.append(pir.name());
paletteFile.append("</display-name>");
paletteFile.append("<tooltip> <![CDATA[ ");
paletteFile.append(pir.tooltip());
paletteFile.append("]]></tooltip>");
paletteFile.append("</inline-description>");
paletteFile.append("</editor_palette_item>");
f.contents(paletteFile.toString());
f.write();
}
@Override
public Number visitMemberSelect(MemberSelectTree node, Void p) {
Element e = info.getTrees().getElement(getCurrentPath());
if (e != null && (e.getKind() != ElementKind.CLASS || ((TypeElement) e).asType().getKind() != TypeKind.ERROR)) {
//check correct dependency:
checkDependency(info, e, canShowUI);
if (isStaticElement(e) && !inImport) {
rewrite(node, make.QualIdent(e));
return null;
}
}
MemberSelectTree nue = node;
String selectedName = node.getIdentifier().toString();
if (selectedName.startsWith("$") && parameterNames.get(selectedName) != null) {
nue = make.MemberSelect(node.getExpression(), parameterNames.get(selectedName));
}
if (nue.getExpression().getKind() == Kind.IDENTIFIER) {
String name = ((IdentifierTree) nue.getExpression()).getName().toString();
if (name.startsWith("$") && parameters.get(name) == null) {
Element implicitThisClass = implicitThis.get(name);
if (implicitThisClass != null) {
TreePath findClass = getCurrentPath();
OUTER: while (findClass != null) {
if (TreeUtilities.CLASS_TREE_KINDS.contains(findClass.getLeaf().getKind())) {
Element clazz = info.getTrees().getElement(findClass);
if (implicitThisClass.equals(clazz)) {
//this.<...>, the this may be implicit:
rewrite(node, make.Identifier(nue.getIdentifier()));
return null;
}
if (clazz.getKind().isClass() || clazz.getKind().isInterface()) {
for (Element currentClassElement : info.getElements().getAllMembers((TypeElement) clazz)) {
if (currentClassElement.getSimpleName().equals(node.getIdentifier())) {
//there may be a resolution conflict, let the member select be qualified
//TODO: no conflicts between fields and methods of the same name
//but we current still qualify the name
break OUTER;
}
}
}
}
findClass = findClass.getParentPath();
}
//let visitIdent handle this
} else {
//XXX: unbound variable, use identifier instead of member select - may cause problems?
rewrite(node, make.Identifier(nue.getIdentifier()));
return null;
}
}
}
if (nue != node) {
rewrite(node, nue);
}
return super.visitMemberSelect(node, p);
}
private void checkForErrors(Element element, Class annotationClass) {
if(element.getEnclosingElement().getKind()!= ElementKind.CLASS) {
throw new IllegalArgumentException("Annotation can only apply to class fields and methods.");
}
final Set<Modifier> modifiers = element.getModifiers();
switch(element.getKind()){
case METHOD:
List<? extends VariableElement> parameters = ((ExecutableElement) element).getParameters();
if(modifiers.contains(Modifier.PRIVATE)
|| modifiers.contains(Modifier.STATIC)) {
throw new IllegalArgumentException("Annotated methods must not be private or static");
} else if (parameters.size() > 2
|| (parameters.size() < 1 && (annotationClass==ReceiveMessages.class || annotationClass==ReceiveData.class))) {
throw new IllegalArgumentException("Incorrect number of parameters for method.");
} else if (parameters.size()==2
&& (annotationClass==ReceiveMessages.class || annotationClass==ReceiveData.class)
&& !parameters.get(1).asType().toString().equals(String.class.getName())) {
throw new IllegalArgumentException("The second parameter must be a String (represents the source node ID)");
} else if(annotationClass==LocalNode.class
&& !parameters.get(0).asType().toString().equals(NODE_CLASS)) {
throw new IllegalArgumentException("@LocalNode annotated method must have a parameter that is a "+NODE_CLASS);
} else if(annotationClass==RemoteNodes.class
&& !parameters.get(0).asType().toString().equals("java.util.List<com.google.android.gms.wearable.Node>")) {
throw new IllegalArgumentException("@RemoteNode annotated method must have a parameter that is a List<Node>");
}
break;
case FIELD:
if(modifiers.contains(Modifier.PRIVATE)
|| modifiers.contains(Modifier.STATIC)
|| modifiers.contains(Modifier.FINAL)) {
throw new IllegalArgumentException("Annotated fields must not be private, static, nor final");
} else if(annotationClass==LocalNode.class && !element.asType().toString().equalsIgnoreCase(NODE_CLASS)) {
throw new IllegalArgumentException("@LocalNode annotated field must be a "+NODE_CLASS);
} else if(annotationClass==RemoteNodes.class
&& !element.asType().toString().equalsIgnoreCase("java.util.List<com.google.android.gms.wearable.Node>")) {
throw new IllegalArgumentException("@RemoteNodes annotated field must be a List<Node>");
}
break;
default:
throw new IllegalArgumentException("Delivery must be made to a method or field");
}
}
/**
* @param info
* @param t1
* @param t3
* @return true iff the first type (or its containing class in the case of inner classes)
* is a subtype of the second.
* @see Types#isSubtype(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror)
*/
private static boolean isSubTypeOrInnerOfSubType(CompilationInfo info, Element t1, Element t2) {
boolean isSubtype = info.getTypes().isSubtype(t1.asType(), t2.asType());
boolean isInnerClass = t1.getEnclosingElement().getKind() == ElementKind.CLASS;
return isSubtype || (isInnerClass && info.getTypes().isSubtype(t1.getEnclosingElement().asType(), t2.asType()));
}