Attribute enterAttributeValue(Type expected,
JCExpression tree,
Env<AttrContext> env) {
//first, try completing the attribution value sym - if a completion
//error is thrown, we should recover gracefully, and display an
//ordinary resolution diagnostic.
try {
expected.tsym.complete();
} catch(CompletionFailure e) {
log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym);
return new Attribute.Error(expected);
}
if (expected.isPrimitive() || types.isSameType(expected, syms.stringType)) {
Type result = attr.attribExpr(tree, env, expected);
if (result.isErroneous())
return new Attribute.Error(expected);
if (result.constValue() == null) {
log.error(tree.pos(), "attribute.value.must.be.constant");
return new Attribute.Error(expected);
}
result = cfolder.coerce(result, expected);
return new Attribute.Constant(expected, result.constValue());
}
if (expected.tsym == syms.classType.tsym) {
Type result = attr.attribExpr(tree, env, expected);
if (result.isErroneous())
return new Attribute.Error(expected);
if (TreeInfo.name(tree) != names._class) {
log.error(tree.pos(), "annotation.value.must.be.class.literal");
return new Attribute.Error(expected);
}
return new Attribute.Class(types,
(((JCFieldAccess) tree).selected).type);
}
if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
if (tree.getTag() != JCTree.ANNOTATION) {
log.error(tree.pos(), "annotation.value.must.be.annotation");
expected = syms.errorType;
}
return enterAnnotation((JCAnnotation)tree, expected, env);
}
if (expected.tag == TypeTags.ARRAY) { // should really be isArray()
if (tree.getTag() != JCTree.NEWARRAY) {
tree = make.at(tree.pos).
NewArray(null, List.< JCExpression >nil(), List.of(tree));
}
JCNewArray na = (JCNewArray)tree;
if (na.elemtype != null) {
log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
return new Attribute.Error(expected);
}
ListBuffer< Attribute > buf = new ListBuffer< Attribute >();
for (List< JCExpression > l = na.elems; l.nonEmpty(); l=l.tail) {
buf.append(enterAttributeValue(types.elemtype(expected),
l.head,
env));
}
na.type = expected;
return new Attribute.
Array(expected, buf.toArray(new Attribute[buf.length()]));
}
if (expected.tag == TypeTags.CLASS &&
(expected.tsym.flags() & Flags.ENUM) != 0) {
attr.attribExpr(tree, env, expected);
Symbol sym = TreeInfo.symbol(tree);
if (sym == null ||
TreeInfo.nonstaticSelect(tree) ||
sym.kind != Kinds.VAR ||
(sym.flags() & Flags.ENUM) == 0) {
log.error(tree.pos(), "enum.annotation.must.be.enum.constant");
return new Attribute.Error(expected);
}
VarSymbol enumerator = (VarSymbol) sym;
return new Attribute.Enum(expected, enumerator);
}
if (!expected.isErroneous())
log.error(tree.pos(), "annotation.value.not.allowable.type");
return new Attribute.Error(attr.attribExpr(tree, env, expected));
}
|