@Override protected boolean matchArgument(ExpressionTree tree, VisitorState state) { Type type = ASTHelpers.getType(tree); if (!type.isReference()) { return false; } ClassTree classTree = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class); if (classTree == null) { return false; } Type classType = ASTHelpers.getType(classTree); if (classType == null) { return false; } if (inEqualsOrCompareTo(classType, type, state)) { return false; } if (ASTHelpers.isSubtype(type, state.getSymtab().enumSym.type, state)) { return false; } if (ASTHelpers.isSubtype(type, state.getSymtab().classType, state)) { return false; } if (!implementsEquals(type, state)) { return false; } return true; }
public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) { BoundKind bkind; Type bound; if (extendsBound == null && superBound == null) { bkind = BoundKind.UNBOUND; bound = syms.objectType; } else if (superBound == null) { bkind = BoundKind.EXTENDS; bound = (Type) extendsBound; } else if (extendsBound == null) { bkind = BoundKind.SUPER; bound = (Type) superBound; } else { throw new IllegalArgumentException("Extends and super bounds cannot both be provided"); } switch (bound.getKind()) { case ARRAY: case DECLARED: case ERROR: case TYPEVAR: return new Type.WildcardType(bound, bkind, syms.boundClass); default: throw new IllegalArgumentException(bound.toString()); } }
public PrimitiveType unboxedType(TypeMirror t) { if (t.getKind() != TypeKind.DECLARED) throw new IllegalArgumentException(t.toString()); Type unboxed = types.unboxedType((Type) t); if (!unboxed.isPrimitive()) // only true primitives, not void throw new IllegalArgumentException(t.toString()); return unboxed; }
@Override public boolean test(Type arg1, Type arg2) { boolean hasStringOp = types.isSameType(arg1, syms.stringType) || types.isSameType(arg2, syms.stringType); boolean hasVoidOp = arg1.hasTag(TypeTag.VOID) || arg2.hasTag(TypeTag.VOID); return hasStringOp && !hasVoidOp; }
private List<TypeSymbol> resolveInterfaces( final JavacNode annotationNode, final Class<? extends java.lang.annotation.Annotation> annotationType, final List<Object> listenerInterfaces) { List<TypeSymbol> resolvedInterfaces = new ArrayList<TypeSymbol>(); for (Object listenerInterface : listenerInterfaces) { if (listenerInterface instanceof JCFieldAccess) { JCFieldAccess interfaze = (JCFieldAccess) listenerInterface; if ("class".equals(As.string(interfaze.name))) { Type interfaceType = CLASS.resolveMember(annotationNode, interfaze.selected); if (interfaceType == null) continue; if (interfaceType.isInterface()) { TypeSymbol interfaceSymbol = interfaceType.asElement(); if (interfaceSymbol != null) resolvedInterfaces.add(interfaceSymbol); } else { annotationNode.addWarning( String.format( "@%s works only with interfaces. %s was skipped", annotationType.getName(), listenerInterface)); } } } } return resolvedInterfaces; }
private boolean unique(TypeVar typevar) { int found = 0; for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) { if (t.toString().equals(typevar.toString())) { found++; } } if (found < 1) throw new AssertionError("Missing type variable in where clause " + typevar); return found == 1; }
/** * Perform unary promotion of a type; this routine implements JLS 5.6.1. If the input type is not * supported by unary promotion, it is returned unaltered. */ Type unaryPromotion(Type t) { Type unboxed = types.unboxedTypeOrType(t); switch (unboxed.getTag()) { case BYTE: case SHORT: case CHAR: return syms.intType; default: return unboxed; } }
public Element asElement(TypeMirror t) { switch (t.getKind()) { case DECLARED: case ERROR: case TYPEVAR: Type type = cast(Type.class, t); return type.asElement(); default: return null; } }
public Element asElement(TypeMirror t) { Type type = cast(Type.class, t); switch (type.tag) { case TypeTags.CLASS: case TypeTags.ERROR: case TypeTags.TYPEVAR: return type.asElement(); default: return null; } }
private int indexOf(Type type, WhereClauseKind kind) { int index = 1; for (Type t : whereClauses.get(kind).keySet()) { if (t.tsym == type.tsym) { return index; } if (kind != WhereClauseKind.TYPEVAR || t.toString().equals(type.toString())) { index++; } } return -1; }
private void addAllFireListenerMethods( final JavacType type, final TypeSymbol interfaze, final TypeSymbol superInterfaze) { for (Symbol member : superInterfaze.getEnclosedElements()) { if (member.getKind() != ElementKind.METHOD) continue; handler.addFireListenerMethod(type, interfaze, (MethodSymbol) member); } ClassType superInterfazeType = (ClassType) superInterfaze.type; if (superInterfazeType.interfaces_field != null) for (Type iface : superInterfazeType.interfaces_field) { addAllFireListenerMethods(type, interfaze, iface.asElement()); } }
/** * This routine applies following mappings: - if input type is primitive, apply numeric * promotion - if input type is either 'void', 'null' or 'String' leave it untouched - otherwise * return 'Object' */ private Type stringPromotion(Type t) { if (t.isPrimitive()) { return unaryPromotion(t); } else if (t.hasTag(TypeTag.VOID) || t.hasTag(TypeTag.BOT) || types.isSameType(t, syms.stringType)) { return t; } else if (t.hasTag(TypeTag.TYPEVAR)) { return stringPromotion(t.getUpperBound()); } else { return syms.objectType; } }
public DeclaredType getDeclaredType( DeclaredType enclosing, TypeElement typeElem, TypeMirror... typeArgs) { if (enclosing == null) return getDeclaredType(typeElem, typeArgs); ClassSymbol sym = (ClassSymbol) typeElem; Type outer = (Type) enclosing; if (outer.tsym != sym.owner.enclClass()) throw new IllegalArgumentException(enclosing.toString()); if (!outer.isParameterized()) return getDeclaredType(typeElem, typeArgs); return getDeclaredType0(outer, sym, typeArgs); }
/** {@inheritDoc} Overridden here to handle @Inherited. */ public <A extends Annotation> A getAnnotation(Class<A> annoType) { boolean inherited = annoType.isAnnotationPresent(Inherited.class); for (Type t = sym.type; t.tsym != env.symtab.objectType.tsym && !t.isErroneous(); t = env.jctypes.supertype(t)) { A result = getAnnotation(annoType, t.tsym); if (result != null || !inherited) { return result; } } return null; }
/** * Returns the upper bound of a type if it has one, or the type itself if not. Correctly handles * wildcards and capture variables. */ public static Type getUpperBound(Type type, Types types) { if (type.hasTag(TypeTag.WILDCARD)) { return types.wildUpperBound(type); } if (type.hasTag(TypeTag.TYPEVAR) && ((TypeVar) type).isCaptured()) { return types.cvarUpperBound(type); } if (type.getUpperBound() != null) { return type.getUpperBound(); } // concrete type, e.g. java.lang.String, or a case we haven't considered return type; }
/** Return true if the given type is 'void' or 'Void'. */ public static boolean isVoidType(Type type, VisitorState state) { if (type == null) { return false; } return type.getKind() == TypeKind.VOID || state.getTypes().isSameType(Suppliers.JAVA_LANG_VOID_TYPE.get(state), type); }
@Override public JCTree visitWrappedMethodDecl(final lombok.ast.WrappedMethodDecl node, final Void p) { MethodSymbol methodSymbol = (MethodSymbol) node.getWrappedObject(); Type mtype = methodSymbol.type; if (node.getReturnType() == null) { node.withReturnType(Type(fixLeadingDot(node, M(node).Type(mtype.getReturnType())))); } if (node.getThrownExceptions().isEmpty()) for (JCExpression expr : M(node).Types(mtype.getThrownTypes())) { node.withThrownException(Type(fixLeadingDot(node, expr))); } if (node.getArguments().isEmpty()) for (JCVariableDecl param : M(node).Params(mtype.getParameterTypes(), methodSymbol)) { node.withArgument(Arg(Type(fixLeadingDot(node, param.vartype)), As.string(param.name))); } if (node.getTypeParameters().isEmpty()) for (JCTypeParameter typaram : M(node).TypeParams(mtype.getTypeArguments())) { final lombok.ast.TypeParam typeParam = TypeParam(As.string(typaram.name)); for (JCExpression expr : typaram.bounds) { typeParam.withBound(Type(fixLeadingDot(node, expr))); } node.withTypeParameter(typeParam); } final JCModifiers mods = M(node) .Modifiers( methodSymbol.flags() & (~Flags.ABSTRACT), build(node.getAnnotations(), JCAnnotation.class)); final JCExpression restype = build(node.getReturnType()); final Name name = methodSymbol.name; final List<JCExpression> thrown = build(node.getThrownExceptions(), JCExpression.class); final List<JCTypeParameter> typarams = build(node.getTypeParameters(), JCTypeParameter.class); final List<JCVariableDecl> params = build(node.getArguments(), JCVariableDecl.class); JCBlock body = null; if (!node.noBody()) { body = M(node).Block(0, build(node.getStatements(), JCStatement.class)); } final JCMethodDecl method = M(node).MethodDef(mods, name, restype, typarams, params, thrown, body, null); return method; }
/** Retrieve the comparison kind associated with the given argument type pair. */ private ComparisonKind getKind(Type arg1, Type arg2) { boolean arg1Primitive = arg1.isPrimitive(); boolean arg2Primitive = arg2.isPrimitive(); if (arg1Primitive && arg2Primitive) { return ComparisonKind.NUMERIC_OR_BOOLEAN; } else if (arg1Primitive) { return unaryPromotion(arg2).isPrimitive() ? ComparisonKind.NUMERIC_OR_BOOLEAN : ComparisonKind.INVALID; } else if (arg2Primitive) { return unaryPromotion(arg1).isPrimitive() ? ComparisonKind.NUMERIC_OR_BOOLEAN : ComparisonKind.INVALID; } else { return arg1.isNullOrReference() && arg2.isNullOrReference() ? ComparisonKind.REFERENCE : ComparisonKind.INVALID; } }
/** * Perform binary promotion of a pair of types; this routine implements JLS 5.6.2. If the input * types are not supported by unary promotion, if such types are identical to a type C, then C is * returned, otherwise Object is returned. */ Type binaryPromotion(Type t1, Type t2) { Type unboxedT1 = types.unboxedTypeOrType(t1); Type unboxedT2 = types.unboxedTypeOrType(t2); if (unboxedT1.isNumeric() && unboxedT2.isNumeric()) { if (unboxedT1.hasTag(TypeTag.DOUBLE) || unboxedT2.hasTag(TypeTag.DOUBLE)) { return syms.doubleType; } else if (unboxedT1.hasTag(TypeTag.FLOAT) || unboxedT2.hasTag(TypeTag.FLOAT)) { return syms.floatType; } else if (unboxedT1.hasTag(TypeTag.LONG) || unboxedT2.hasTag(TypeTag.LONG)) { return syms.longType; } else { return syms.intType; } } else if (types.isSameType(unboxedT1, unboxedT2)) { return unboxedT1; } else { return syms.objectType; } }
protected void printType(String label, Type type, Details details) { if (type == null) printNull(label); else { switch (details) { case SUMMARY: printString(label, toString(type)); break; case FULL: indent(); out.print(label); out.println( ": " + info(type.getClass(), type.getTag(), type.getKind()) + " " + hashString(type)); indent(+1); printSymbol("tsym", type.tsym, Details.SUMMARY); printObject("constValue", type.constValue(), Details.SUMMARY); printObject("annotations", type.getAnnotationMirrors(), Details.SUMMARY); type.accept(typeVisitor, null); indent(-1); } } }
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 || types.isSameType(expected, syms.annotationType)) { 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)); }
@Override public boolean test(Type type) { return type.isNullOrReference(); }