use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class ASTHelpers method enumValues.
/** @return all values of the given enum type, in declaration order. */
public static LinkedHashSet<String> enumValues(TypeSymbol enumType) {
if (enumType.getKind() != ElementKind.ENUM) {
throw new IllegalStateException();
}
Scope scope = enumType.members();
Deque<String> values = new ArrayDeque<>();
for (Symbol sym : scope.getSymbols()) {
if (sym instanceof VarSymbol) {
VarSymbol var = (VarSymbol) sym;
if ((var.flags() & Flags.ENUM) != 0) {
/**
* Javac gives us the members backwards, apparently. It's worth making an effort to
* preserve declaration order because it's useful for diagnostics (e.g. in
* {@link MissingCasesInEnumSwitch}).
*/
values.push(sym.name.toString());
}
}
}
return new LinkedHashSet<>(values);
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class FragmentInjection method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
// Only examine classes that extend PreferenceActivity.
Type preferenceActivityType = state.getTypeFromString("android.preference.PreferenceActivity");
if (!isSubtype(getType(tree), preferenceActivityType, state)) {
return NO_MATCH;
}
// Examine each method in the class. Complain if isValidFragment not implemented.
TypeSymbol preferenceActivityTypeSymbol = preferenceActivityType.tsym;
boolean methodNotImplemented = true;
try {
MethodSymbol isValidFragmentMethodSymbol = resolveExistingMethod(state, getSymbol(tree), state.getName("isValidFragment"), ImmutableList.<Type>of(state.getTypeFromString("java.lang.String")), ImmutableList.<Type>of());
methodNotImplemented = isValidFragmentMethodSymbol.owner.equals(preferenceActivityTypeSymbol);
} catch (FatalError e) {
// If isValidFragment method symbol is not found, then we must be compiling against an old SDK
// version (< 19) in which isValidFragment is not yet implemented, and neither this class nor
// any of its super classes have implemented it.
}
// isValidFragment, and this is not an abstract class, emit warning.
if (methodNotImplemented && not(hasModifier(Modifier.ABSTRACT)).matches(tree, state)) {
return buildDescription(tree).setMessage("Class extending PreferenceActivity does not implement isValidFragment.").build();
}
// Check the implementation of isValidFragment. Complain if it always returns true.
MethodTree isValidFragmentMethodTree = getMethod(OVERRIDES_IS_VALID_FRAGMENT, tree, state);
if (isValidFragmentMethodTree != null) {
if (isValidFragmentMethodTree.accept(ALWAYS_RETURNS_TRUE, null)) {
return buildDescription(isValidFragmentMethodTree).setMessage("isValidFragment unconditionally returns true.").build();
}
}
return NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class SelfEquals method fieldFix.
@Nullable
protected static Fix fieldFix(Tree toReplace, VisitorState state) {
TreePath path = state.getPath();
while (path != null && path.getLeaf().getKind() != Kind.CLASS && path.getLeaf().getKind() != Kind.BLOCK) {
path = path.getParentPath();
}
if (path == null) {
return null;
}
List<? extends JCTree> members;
// Must be block or class
if (path.getLeaf().getKind() == Kind.CLASS) {
members = ((JCClassDecl) path.getLeaf()).getMembers();
} else {
members = ((JCBlock) path.getLeaf()).getStatements();
}
for (JCTree jcTree : members) {
if (jcTree.getKind() == Kind.VARIABLE) {
JCVariableDecl declaration = (JCVariableDecl) jcTree;
TypeSymbol variableTypeSymbol = state.getTypes().erasure(ASTHelpers.getType(declaration)).tsym;
if (ASTHelpers.getSymbol(toReplace).isMemberOf(variableTypeSymbol, state.getTypes())) {
if (toReplace.getKind() == Kind.IDENTIFIER) {
return SuggestedFix.prefixWith(toReplace, declaration.getName() + ".");
} else {
return SuggestedFix.replace(((JCFieldAccess) toReplace).getExpression(), declaration.getName().toString());
}
}
}
}
return null;
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class UnnecessaryDefaultInEnumSwitch method matchSwitch.
@Override
public Description matchSwitch(SwitchTree tree, VisitorState state) {
TypeSymbol switchType = ((JCSwitch) tree).getExpression().type.tsym;
if (switchType.getKind() != ElementKind.ENUM) {
return NO_MATCH;
}
Optional<? extends CaseTree> maybeDefaultCase = tree.getCases().stream().filter(c -> c.getExpression() == null).findFirst();
if (!maybeDefaultCase.isPresent()) {
return NO_MATCH;
}
CaseTree defaultCase = maybeDefaultCase.get();
Set<String> handledCases = tree.getCases().stream().map(CaseTree::getExpression).filter(IdentifierTree.class::isInstance).map(p -> ((IdentifierTree) p).getName().toString()).collect(toImmutableSet());
if (!ASTHelpers.enumValues(switchType).equals(handledCases)) {
return NO_MATCH;
}
Fix fix;
List<? extends StatementTree> defaultStatements = defaultCase.getStatements();
if (trivialDefault(defaultStatements)) {
// deleting `default:` or `default: break;` is a no-op
fix = SuggestedFix.delete(defaultCase);
} else if (!canCompleteNormally(tree)) {
// if the switch statement cannot complete normally, then deleting the default
// and moving its statements to after the switch statement is a no-op
String defaultSource = state.getSourceCode().subSequence(((JCTree) defaultStatements.get(0)).getStartPosition(), state.getEndPosition(getLast(defaultStatements))).toString();
fix = SuggestedFix.builder().delete(defaultCase).postfixWith(tree, defaultSource).build();
} else {
return NO_MATCH;
}
return describeMatch(defaultCase, fix);
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project lombok by rzwitserloot.
the class JavacResolution method typeToJCTree0.
private static JCExpression typeToJCTree0(Type type, JavacAST ast, boolean allowCompound, boolean allowVoid) throws TypeNotConvertibleException {
// NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too.
// -- so we write our own take on that here.
JavacTreeMaker maker = ast.getTreeMaker();
if (CTC_BOT.equals(typeTag(type)))
return createJavaLangObject(ast);
if (CTC_VOID.equals(typeTag(type)))
return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast);
if (type.isPrimitive())
return primitiveToJCTree(type.getKind(), maker);
if (type.isErroneous())
throw new TypeNotConvertibleException("Type cannot be resolved");
TypeSymbol symbol = type.asElement();
List<Type> generics = type.getTypeArguments();
JCExpression replacement = null;
if (symbol == null)
throw new TypeNotConvertibleException("Null or compound type");
if (symbol.name.length() == 0) {
// Anonymous inner class
if (type instanceof ClassType) {
List<Type> ifaces = ((ClassType) type).interfaces_field;
Type supertype = ((ClassType) type).supertype_field;
if (ifaces != null && ifaces.length() == 1) {
return typeToJCTree(ifaces.get(0), ast, allowCompound, allowVoid);
}
if (supertype != null)
return typeToJCTree(supertype, ast, allowCompound, allowVoid);
}
throw new TypeNotConvertibleException("Anonymous inner class");
}
if (type instanceof CapturedType || type instanceof WildcardType) {
Type lower, upper;
if (type instanceof WildcardType) {
upper = ((WildcardType) type).getExtendsBound();
lower = ((WildcardType) type).getSuperBound();
} else {
lower = type.getLowerBound();
upper = type.getUpperBound();
}
if (allowCompound) {
if (lower == null || CTC_BOT.equals(typeTag(lower))) {
if (upper == null || upper.toString().equals("java.lang.Object")) {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
if (upper.getTypeArguments().contains(type)) {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
return maker.Wildcard(maker.TypeBoundKind(BoundKind.EXTENDS), typeToJCTree(upper, ast, false, false));
} else {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.SUPER), typeToJCTree(lower, ast, false, false));
}
}
if (upper != null) {
if (upper.getTypeArguments().contains(type)) {
return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
return typeToJCTree(upper, ast, allowCompound, allowVoid);
}
return createJavaLangObject(ast);
}
String qName;
if (symbol.isLocal()) {
qName = symbol.getSimpleName().toString();
} else if (symbol.type != null && symbol.type.getEnclosingType() != null && typeTag(symbol.type.getEnclosingType()).equals(typeTag("CLASS"))) {
replacement = typeToJCTree0(type.getEnclosingType(), ast, false, false);
qName = symbol.getSimpleName().toString();
} else {
qName = symbol.getQualifiedName().toString();
}
if (qName.isEmpty())
throw new TypeNotConvertibleException("unknown type");
if (qName.startsWith("<"))
throw new TypeNotConvertibleException(qName);
String[] baseNames = qName.split("\\.");
int i = 0;
if (replacement == null) {
replacement = maker.Ident(ast.toName(baseNames[0]));
i = 1;
}
for (; i < baseNames.length; i++) {
replacement = maker.Select(replacement, ast.toName(baseNames[i]));
}
return genericsToJCTreeNodes(generics, ast, replacement);
}
Aggregations