use of com.sun.tools.javac.code.Symbol.ClassSymbol in project lombok by rzwitserloot.
the class HandleWither method createWitherForField.
public void createWitherForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean strictMode, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
JavacNode typeNode = fieldNode.up();
boolean makeAbstract = typeNode != null && typeNode.getKind() == Kind.TYPE && (((JCClassDecl) typeNode.get()).mods.flags & Flags.ABSTRACT) != 0;
if (fieldNode.getKind() != Kind.FIELD) {
fieldNode.addError("@Wither is only supported on a class or a field.");
return;
}
JCVariableDecl fieldDecl = (JCVariableDecl) fieldNode.get();
String methodName = toWitherName(fieldNode);
if (methodName == null) {
fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
return;
}
if ((fieldDecl.mods.flags & Flags.STATIC) != 0) {
if (strictMode) {
fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
}
return;
}
if ((fieldDecl.mods.flags & Flags.FINAL) != 0 && fieldDecl.init != null) {
if (strictMode) {
fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
}
return;
}
if (fieldDecl.name.toString().startsWith("$")) {
if (strictMode) {
fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
}
return;
}
for (String altName : toAllWitherNames(fieldNode)) {
switch(methodExists(altName, fieldNode, false, 1)) {
case EXISTS_BY_LOMBOK:
return;
case EXISTS_BY_USER:
if (strictMode) {
String altNameExpl = "";
if (!altName.equals(methodName))
altNameExpl = String.format(" (%s)", altName);
fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", methodName, altNameExpl));
}
return;
default:
case NOT_EXISTS:
}
}
long access = toJavacModifier(level);
JCMethodDecl createdWither = createWither(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, onParam, makeAbstract);
ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
Type returnType = sym == null ? null : sym.type;
injectMethod(typeNode, createdWither, List.<Type>of(getMirrorForFieldType(fieldNode)), returnType);
}
use of com.sun.tools.javac.code.Symbol.ClassSymbol in project bazel by bazelbuild.
the class ImplicitDependencyExtractor method accumulate.
/**
* Collects the implicit dependencies of the given set of ClassSymbol roots. As we're interested
* in differentiating between symbols that were just resolved vs. symbols that were fully
* completed by the compiler, we start the analysis by finding all the implicit dependencies
* reachable from the given set of roots. For completeness, we then walk the symbol table
* associated with the given context and collect the jar files of the remaining class symbols
* found there.
*
* @param context compilation context
* @param roots root classes in the implicit dependency collection
*/
public void accumulate(Context context, Set<ClassSymbol> roots) {
Symtab symtab = Symtab.instance(context);
if (symtab.classes == null) {
return;
}
// Collect transitive references for root types
for (ClassSymbol root : roots) {
root.type.accept(typeVisitor, null);
}
Set<String> platformJars = getPlatformJars(fileManager);
// Collect all other partially resolved types
for (ClassSymbol cs : symtab.classes.values()) {
// When recording we want to differentiate between jar references through completed symbols
// and incomplete symbols
boolean completed = cs.isCompleted();
if (cs.classfile != null) {
collectJarOf(cs.classfile, platformJars, completed);
} else if (cs.sourcefile != null) {
collectJarOf(cs.sourcefile, platformJars, completed);
}
}
}
use of com.sun.tools.javac.code.Symbol.ClassSymbol in project error-prone by google.
the class EqualsIncompatibleType method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree invocationTree, final VisitorState state) {
if (!STATIC_EQUALS_INVOCATION_MATCHER.matches(invocationTree, state) && !INSTANCE_EQUALS_INVOCATION_MATCHER.matches(invocationTree, state)) {
return Description.NO_MATCH;
}
// This is the type of the object on which the java.lang.Object.equals() method
// is called, either directly or indirectly via a static utility method. In the latter,
// it is the type of the first argument to the static method.
Type receiverType;
// This is the type of the argument to the java.lang.Object.equals() method.
// In case a static utility method is used, it is the type of the second argument
// to this method.
Type argumentType;
if (STATIC_EQUALS_INVOCATION_MATCHER.matches(invocationTree, state)) {
receiverType = ASTHelpers.getType(invocationTree.getArguments().get(0));
argumentType = ASTHelpers.getType(invocationTree.getArguments().get(1));
} else {
receiverType = ASTHelpers.getReceiverType(invocationTree);
argumentType = ASTHelpers.getType(invocationTree.getArguments().get(0));
}
if (receiverType == null || argumentType == null) {
return Description.NO_MATCH;
}
// 1.7: java.lang.Object can be cast to primitives (implicitly through the boxed primitive type)
if (ASTHelpers.isCastable(argumentType, receiverType, state)) {
return Description.NO_MATCH;
}
// Otherwise, we explore the superclasses of the receiver type as well as the interfaces it
// implements and we collect all overrides of java.lang.Object.equals(). If one of those
// overrides is inherited by the argument, then we don't flag the equality test.
final Types types = state.getTypes();
Predicate<MethodSymbol> equalsPredicate = new Predicate<MethodSymbol>() {
@Override
public boolean apply(MethodSymbol methodSymbol) {
return !methodSymbol.isStatic() && ((methodSymbol.flags() & Flags.SYNTHETIC) == 0) && types.isSameType(methodSymbol.getReturnType(), state.getSymtab().booleanType) && methodSymbol.getParameters().size() == 1 && types.isSameType(methodSymbol.getParameters().get(0).type, state.getSymtab().objectType);
}
};
Name equalsName = state.getName("equals");
Set<MethodSymbol> overridesOfEquals = ASTHelpers.findMatchingMethods(equalsName, equalsPredicate, receiverType, types);
ClassSymbol argumentClass = (ClassSymbol) argumentType.tsym;
for (MethodSymbol method : overridesOfEquals) {
ClassSymbol methodClass = method.enclClass();
if (argumentClass.isSubClass(methodClass, types) && !methodClass.equals(state.getSymtab().objectType.tsym) && !methodClass.equals(state.getSymtab().enumSym)) {
// with the receiver that implements an override of java.lang.Object.equals().
return Description.NO_MATCH;
}
}
// assertFalse(objOfReceiverType.equals(objOfArgumentType))
if (ASSERT_FALSE_MATCHER.matches(state.getPath().getParentPath().getLeaf(), state)) {
return Description.NO_MATCH;
}
// When we reach this point, we know that the two following facts hold:
// (1) The types of the receiver and the argument to the eventual invocation of
// java.lang.Object.equals() are incompatible.
// (2) No common superclass (other than java.lang.Object) or interface of the receiver and the
// argument defines an override of java.lang.Object.equals().
// This equality test almost certainly evaluates to false, which is very unlikely to be the
// programmer's intent. Hence, this is reported as an error. There is no sensible fix to suggest
// in this situation.
Description.Builder description = buildDescription(invocationTree);
description.setMessage("Calling " + ASTHelpers.getSymbol(invocationTree).getSimpleName() + " on incompatible types " + receiverType + " and " + argumentType);
return description.build();
}
use of com.sun.tools.javac.code.Symbol.ClassSymbol in project error-prone by google.
the class AmbiguousMethodReference method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol origin = getSymbol(tree);
Types types = state.getTypes();
Iterable<Symbol> members = types.membersClosure(getType(tree), /*skipInterface=*/
false).getSymbols();
// collect declared and inherited methods, grouped by reference descriptor
Map<String, List<MethodSymbol>> methods = stream(members.spliterator(), false).filter(MethodSymbol.class::isInstance).map(MethodSymbol.class::cast).filter(m -> m.isConstructor() || m.owner.equals(origin)).collect(groupingBy(m -> methodReferenceDescriptor(types, m), toCollection(ArrayList::new)));
// look for groups of ambiguous method references
for (Tree member : tree.getMembers()) {
if (!(member instanceof MethodTree)) {
continue;
}
MethodSymbol msym = getSymbol((MethodTree) member);
if (isSuppressed(msym)) {
continue;
}
List<MethodSymbol> clash = methods.remove(methodReferenceDescriptor(types, msym));
if (clash == null) {
continue;
}
clash.remove(msym);
// ignore overridden inherited methods and hidden interface methods
clash.removeIf(m -> types.isSubSignature(msym.type, m.type));
if (clash.isEmpty()) {
continue;
}
String message = String.format("This method's reference is ambiguous, its name and functional interface type" + " are the same as: %s", clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining(", ")));
state.reportMatch(buildDescription(member).setMessage(message).build());
}
return NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol.ClassSymbol in project error-prone by google.
the class FindIdentifiers method isVisible.
private static boolean isVisible(VarSymbol var, final TreePath path) {
switch(var.getKind()) {
case ENUM_CONSTANT:
case FIELD:
// TODO(eaftan): Switch collector to ImmutableList.toImmutableList() when released
List<ClassSymbol> enclosingClasses = StreamSupport.stream(path.spliterator(), false).filter(tree -> tree instanceof ClassTree).map(ClassTree.class::cast).map(ASTHelpers::getSymbol).collect(Collectors.toCollection(ArrayList::new));
if (!var.isStatic()) {
// Instance fields are not visible if we are in a static context...
if (inStaticContext(path)) {
return false;
}
// the enclosing static nested class (JLS 8.5.1).
if (lowerThan(path, (curr, unused) -> curr instanceof ClassTree && ASTHelpers.getSymbol((ClassTree) curr).isStatic(), (curr, unused) -> curr instanceof ClassTree && ASTHelpers.getSymbol((ClassTree) curr).equals(var.owner))) {
return false;
}
}
// fields (JLS 6.6.1).
if (enclosingClasses.contains(ASTHelpers.enclosingClass(var))) {
return true;
}
PackageSymbol enclosingPackage = ((JCCompilationUnit) path.getCompilationUnit()).packge;
Set<Modifier> modifiers = var.getModifiers();
// (JLS 6.6.1).
if (Objects.equals(enclosingPackage, ASTHelpers.enclosingPackage(var))) {
return !modifiers.contains(Modifier.PRIVATE);
}
// in the enclosing class or a superclass).
return modifiers.contains(Modifier.PUBLIC) || modifiers.contains(Modifier.PROTECTED);
case PARAMETER:
case LOCAL_VARIABLE:
// final or effectively final (JLS 8.1.3).
if (lowerThan(path, (curr, parent) -> curr.getKind() == Kind.LAMBDA_EXPRESSION || (curr.getKind() == Kind.NEW_CLASS && ((NewClassTree) curr).getClassBody() != null) || (curr.getKind() == Kind.CLASS && parent.getKind() == Kind.BLOCK), (curr, unused) -> Objects.equals(var.owner, ASTHelpers.getSymbol(curr)))) {
if ((var.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) == 0) {
return false;
}
}
return true;
case EXCEPTION_PARAMETER:
case RESOURCE_VARIABLE:
return true;
default:
throw new IllegalArgumentException("Unexpected variable type: " + var.getKind());
}
}
Aggregations