use of javax.lang.model.element.Element in project immutables by immutables.
the class SourceOrdering method getAllAccessorsProvider.
/**
* While we have {@link SourceOrdering}, there's still a problem: We have inheritance hierarchy
* and
* we want to have all defined or inherited accessors returned as members of target type, like
* {@link Elements#getAllMembers(TypeElement)}, but we need to have them properly and stably
* sorted.
* This implementation doesn't try to correctly resolve order for accessors inherited from
* different supertypes(interfaces), just something that stable and reasonable wrt source ordering
* without handling complex cases.
* @param elements the elements utility
* @param types the types utility
* @param type the type to traverse
* @return provider of all accessors in source order and mapping
*/
public static AccessorProvider getAllAccessorsProvider(final Elements elements, final Types types, final TypeElement type) {
class CollectedOrdering extends Ordering<Element> {
class Intratype {
Ordering<String> ordering;
int rank;
}
final Map<String, Intratype> accessorOrderings = Maps.newLinkedHashMap();
final List<TypeElement> linearizedTypes = Lists.newArrayList();
final Predicate<String> accessorNotYetInOrderings = Predicates.not(Predicates.in(accessorOrderings.keySet()));
final ArrayListMultimap<String, TypeElement> accessorMapping = ArrayListMultimap.create();
CollectedOrdering() {
traverse(type);
traverseObjectForInterface();
}
private void traverseObjectForInterface() {
if (type.getKind() == ElementKind.INTERFACE) {
traverse(elements.getTypeElement(Object.class.getName()));
}
}
void traverse(@Nullable TypeElement element) {
if (element == null || isJavaLangObject(element)) {
return;
}
collectEnclosing(element);
traverse(asTypeElement(element.getSuperclass()));
for (TypeMirror implementedInterface : element.getInterfaces()) {
traverse(asTypeElement(implementedInterface));
}
}
@Nullable
TypeElement asTypeElement(TypeMirror type) {
if (type.getKind() == TypeKind.DECLARED) {
return (TypeElement) ((DeclaredType) type).asElement();
}
return null;
}
void collectEnclosing(TypeElement type) {
FluentIterable<String> accessorsInType = FluentIterable.from(SourceOrdering.getEnclosedElements(type)).filter(IsParameterlessNonstaticNonobject.PREDICATE).transform(ToSimpleName.FUNCTION);
for (String accessor : accessorsInType) {
accessorMapping.put(accessor, type);
}
List<String> accessors = accessorsInType.filter(accessorNotYetInOrderings).toList();
Intratype intratype = new Intratype();
intratype.rank = linearizedTypes.size();
intratype.ordering = Ordering.explicit(accessors);
for (String name : accessors) {
accessorOrderings.put(name, intratype);
}
linearizedTypes.add(type);
}
@Override
public int compare(Element left, Element right) {
String leftKey = ToSimpleName.FUNCTION.apply(left);
String rightKey = ToSimpleName.FUNCTION.apply(right);
Intratype leftIntratype = accessorOrderings.get(leftKey);
Intratype rightIntratype = accessorOrderings.get(rightKey);
if (leftIntratype == null || rightIntratype == null) {
// FIXME figure out why it happens (null)
return Boolean.compare(leftIntratype == null, rightIntratype == null);
}
return leftIntratype == rightIntratype ? leftIntratype.ordering.compare(leftKey, rightKey) : Integer.compare(leftIntratype.rank, rightIntratype.rank);
}
}
final CollectedOrdering ordering = new CollectedOrdering();
final ImmutableList<ExecutableElement> sortedList = ordering.immutableSortedCopy(disambiguateMethods(ElementFilter.methodsIn(elements.getAllMembers(type))));
return new AccessorProvider() {
ImmutableListMultimap<String, TypeElement> accessorMapping = ImmutableListMultimap.copyOf(ordering.accessorMapping);
@Override
public ImmutableListMultimap<String, TypeElement> accessorMapping() {
return accessorMapping;
}
@Override
public ImmutableList<ExecutableElement> get() {
return sortedList;
}
};
}
use of javax.lang.model.element.Element in project immutables by immutables.
the class Metaservices method validated.
@Nullable
private TypeElement validated(Element element) {
Element enclosingElement = element.getEnclosingElement();
if (element.getKind() == ElementKind.CLASS && element.getModifiers().contains(Modifier.PUBLIC) && !element.getModifiers().contains(Modifier.ABSTRACT) && enclosingElement != null && enclosingElement.getKind() == ElementKind.PACKAGE && !((PackageElement) enclosingElement).isUnnamed()) {
return (TypeElement) element;
}
processing().getMessager().printMessage(Diagnostic.Kind.ERROR, "Element annotated with @Metainf.Service annotation should be public top-level non-abstract class in a package", element);
return null;
}
use of javax.lang.model.element.Element in project jOOQ by jOOQ.
the class SQLDialectChecker method createSourceVisitor.
@Override
protected SourceVisitor<Void, Void> createSourceVisitor() {
return new SourceVisitor<Void, Void>(getChecker()) {
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
try {
ExecutableElement elementFromUse = elementFromUse(node);
Support support = elementFromUse.getAnnotation(Support.class);
// all jOOQ API method calls will type check.
if (support != null && support.value().length > 0) {
Element enclosing = elementFromDeclaration(enclosingMethod(getPath(root, node)));
EnumSet<SQLDialect> supported = EnumSet.copyOf(asList(support.value()));
EnumSet<SQLDialect> allowed = EnumSet.noneOf(SQLDialect.class);
EnumSet<SQLDialect> required = EnumSet.noneOf(SQLDialect.class);
boolean evaluateRequire = true;
while (enclosing != null) {
Allow allow = enclosing.getAnnotation(Allow.class);
if (allow != null)
allowed.addAll(asList(allow.value()));
if (evaluateRequire) {
Require require = enclosing.getAnnotation(Require.class);
if (require != null) {
evaluateRequire = false;
required.clear();
required.addAll(asList(require.value()));
}
}
enclosing = enclosing.getEnclosingElement();
}
if (allowed.isEmpty())
error(node, "No jOOQ API usage is allowed at current scope. Use @Allow.");
if (required.isEmpty())
error(node, "No jOOQ API usage is allowed at current scope due to conflicting @Require specification.");
boolean allowedFail = true;
allowedLoop: for (SQLDialect a : allowed) {
for (SQLDialect s : supported) {
if (a.supports(s)) {
allowedFail = false;
break allowedLoop;
}
}
}
if (allowedFail)
error(node, "The allowed dialects in scope " + allowed + " do not include any of the supported dialects: " + supported);
boolean requiredFail = false;
requiredLoop: for (SQLDialect r : required) {
for (SQLDialect s : supported) if (r.supports(s))
continue requiredLoop;
requiredFail = true;
break requiredLoop;
}
if (requiredFail)
error(node, "Not all of the required dialects " + required + " from the current scope are supported " + supported);
}
} catch (final Exception e) {
print(new Printer() {
@Override
public void print(PrintWriter t) {
e.printStackTrace(t);
}
});
}
return super.visitMethodInvocation(node, p);
}
};
}
use of javax.lang.model.element.Element in project jOOQ by jOOQ.
the class PlainSQLChecker method createSourceVisitor.
@Override
protected SourceVisitor<Void, Void> createSourceVisitor() {
return new SourceVisitor<Void, Void>(getChecker()) {
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
try {
ExecutableElement elementFromUse = elementFromUse(node);
PlainSQL plainSQL = elementFromUse.getAnnotation(PlainSQL.class);
// all jOOQ API method calls will type check.
if (plainSQL != null) {
Element enclosing = elementFromDeclaration(enclosingMethod(getPath(root, node)));
boolean allowed = false;
moveUpEnclosingLoop: while (enclosing != null) {
if (enclosing.getAnnotation(Allow.PlainSQL.class) != null) {
allowed = true;
break moveUpEnclosingLoop;
}
enclosing = enclosing.getEnclosingElement();
}
if (!allowed)
error(node, "Plain SQL usage not allowed at current scope. Use @Allow.PlainSQL.");
}
} catch (final Exception e) {
print(new Printer() {
@Override
public void print(PrintWriter t) {
e.printStackTrace(t);
}
});
}
return super.visitMethodInvocation(node, p);
}
};
}
use of javax.lang.model.element.Element in project immutables by immutables.
the class ImportRewriteDisabler method shouldDisableFor.
static boolean shouldDisableFor(ValueType type) {
Reporter reporter = type.constitution.protoclass().report();
for (String segment : DOT_SPLITTER.split(type.constitution.implementationPackage())) {
if (!segment.isEmpty() && Ascii.isUpperCase(segment.charAt(0))) {
reporter.warning(WARNING_START + " uppercase package names");
return true;
}
}
Element element = type.constitution.protoclass().sourceElement();
if (shouldDisableFor(reporter, element)) {
return true;
}
for (ValueAttribute attribute : type.attributes) {
if (Ascii.isUpperCase(attribute.names.get.charAt(0))) {
reporter.warning(WARNING_START + " uppercase attribute names");
return true;
}
if (attribute.containedTypeElement != null) {
if (shouldDisableFor(reporter, attribute.containedTypeElement)) {
return true;
}
}
}
for (ValueType nested : type.nested) {
if (shouldDisableFor(nested)) {
return true;
}
}
return false;
}
Aggregations