@Override
 public String visitCapturedType(CapturedType t, Locale locale) {
   if (!allCaptured.contains(t)) {
     allCaptured = allCaptured.append(t);
   }
   return super.visitCapturedType(t, locale);
 }
 /** Add a name usage to the simplifier's internal cache */
 protected void addUsage(Symbol sym) {
   Name n = sym.getSimpleName();
   List<Symbol> conflicts = nameClashes.get(n);
   if (conflicts == null) {
     conflicts = List.nil();
   }
   if (!conflicts.contains(sym)) nameClashes.put(n, conflicts.append(sym));
 }
Example #3
0
 public List<A> intersect(List<A> that) {
   ListBuffer<A> buf = ListBuffer.lb();
   for (A el : this) {
     if (that.contains(el)) {
       buf.append(el);
     }
   }
   return buf.toList();
 }
Example #4
0
 public Annotations appendUniqueTypes(List<Attribute.TypeCompound> l) {
   if (l.isEmpty()) {; // no-op
   } else if (type_attributes.isEmpty()) {
     type_attributes = l;
   } else {
     // TODO: in case we expect a large number of annotations, this
     // might be inefficient.
     for (Attribute.TypeCompound tc : l) {
       if (!type_attributes.contains(tc)) type_attributes = type_attributes.append(tc);
     }
   }
   return this;
 }
 // This is a bit of a hack, but if we got passed a list of resources
 // without any accompaning source files we'll not be able to determine
 // the module to which the resource files belong. So to try to fix that
 // we see if a module file exists in the source folders and add it to
 // the list of source files
 private List<JavaFileObject> addModuleDescriptors(
     List<JavaFileObject> sourceFiles, List<JavaFileObject> resourceFiles) {
   List<JavaFileObject> result = sourceFiles;
   JavacFileManager dfm = (JavacFileManager) fileManager;
   for (JavaFileObject fo : resourceFiles) {
     String resName =
         JarUtils.toPlatformIndependentPath(
             dfm.getLocation(CeylonLocation.RESOURCE_PATH), fo.getName());
     JavaFileObject moduleFile = findModuleDescriptorForFile(new File(resName));
     if (moduleFile != null && !result.contains(moduleFile)) {
       result = result.append(moduleFile);
     }
   }
   return result;
 }
Example #6
0
 @Override
 public String visitCapturedType(CapturedType t, Locale locale) {
   if (seenCaptured.contains(t))
     return localize(locale, "compiler.misc.type.captureof.1", capturedVarId(t, locale));
   else {
     try {
       seenCaptured = seenCaptured.prepend(t);
       return localize(
           locale,
           "compiler.misc.type.captureof",
           capturedVarId(t, locale),
           visit(t.wildcard, locale));
     } finally {
       seenCaptured = seenCaptured.tail;
     }
   }
 }
 public String simplify(Symbol s) {
   String name = s.getQualifiedName().toString();
   if (!s.type.isCompound()) {
     List<Symbol> conflicts = nameClashes.get(s.getSimpleName());
     if (conflicts == null || (conflicts.size() == 1 && conflicts.contains(s))) {
       List<Name> l = List.nil();
       Symbol s2 = s;
       while (s2.type.getEnclosingType().tag == CLASS && s2.owner.kind == Kinds.TYP) {
         l = l.prepend(s2.getSimpleName());
         s2 = s2.owner;
       }
       l = l.prepend(s2.getSimpleName());
       StringBuilder buf = new StringBuilder();
       String sep = "";
       for (Name n2 : l) {
         buf.append(sep);
         buf.append(n2);
         sep = ".";
       }
       name = buf.toString();
     }
   }
   return name;
 }
  public void generateMethods(
      JavacNode typeNode,
      JavacNode source,
      List<String> excludes,
      List<String> includes,
      Boolean callSuper,
      boolean whineIfExists,
      FieldAccess fieldAccess) {
    boolean notAClass = true;
    if (typeNode.get() instanceof JCClassDecl) {
      long flags = ((JCClassDecl) typeNode.get()).mods.flags;
      notAClass = (flags & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
    }

    if (notAClass) {
      source.addError("@EqualsAndHashCode is only supported on a class.");
      return;
    }

    boolean isDirectDescendantOfObject = true;
    boolean implicitCallSuper = callSuper == null;
    if (callSuper == null) {
      try {
        callSuper =
            ((Boolean) EqualsAndHashCode.class.getMethod("callSuper").getDefaultValue())
                .booleanValue();
      } catch (Exception ignore) {
        throw new InternalError(
            "Lombok bug - this cannot happen - can't find callSuper field in EqualsAndHashCode annotation.");
      }
    }

    JCTree extending = Javac.getExtendsClause((JCClassDecl) typeNode.get());
    if (extending != null) {
      String p = extending.toString();
      isDirectDescendantOfObject = p.equals("Object") || p.equals("java.lang.Object");
    }

    if (isDirectDescendantOfObject && callSuper) {
      source.addError(
          "Generating equals/hashCode with a supercall to java.lang.Object is pointless.");
      return;
    }

    if (!isDirectDescendantOfObject && !callSuper && implicitCallSuper) {
      source.addWarning(
          "Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.");
    }

    ListBuffer<JavacNode> nodesForEquality = new ListBuffer<JavacNode>();
    if (includes != null) {
      for (JavacNode child : typeNode.down()) {
        if (child.getKind() != Kind.FIELD) continue;
        JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
        if (includes.contains(fieldDecl.name.toString())) nodesForEquality.append(child);
      }
    } else {
      for (JavacNode child : typeNode.down()) {
        if (child.getKind() != Kind.FIELD) continue;
        JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
        // Skip static fields.
        if ((fieldDecl.mods.flags & Flags.STATIC) != 0) continue;
        // Skip transient fields.
        if ((fieldDecl.mods.flags & Flags.TRANSIENT) != 0) continue;
        // Skip excluded fields.
        if (excludes != null && excludes.contains(fieldDecl.name.toString())) continue;
        // Skip fields that start with $
        if (fieldDecl.name.toString().startsWith("$")) continue;
        nodesForEquality.append(child);
      }
    }

    boolean isFinal = (((JCClassDecl) typeNode.get()).mods.flags & Flags.FINAL) != 0;
    boolean needsCanEqual = !isFinal || !isDirectDescendantOfObject;
    MemberExistsResult equalsExists = methodExists("equals", typeNode, 1);
    MemberExistsResult hashCodeExists = methodExists("hashCode", typeNode, 0);
    MemberExistsResult canEqualExists = methodExists("canEqual", typeNode, 1);
    switch (Collections.max(Arrays.asList(equalsExists, hashCodeExists, canEqualExists))) {
      case EXISTS_BY_LOMBOK:
        return;
      case EXISTS_BY_USER:
        if (whineIfExists) {
          String msg =
              String.format(
                  "Not generating equals%s: A method with one of those names already exists. (Either all or none of these methods will be generated).",
                  needsCanEqual ? ", hashCode and canEquals" : " and hashCode");
          source.addWarning(msg);
        } else if (equalsExists == MemberExistsResult.NOT_EXISTS
            || hashCodeExists == MemberExistsResult.NOT_EXISTS) {
          // This means equals OR hashCode exists and not both (or neither, but canEqual is there).
          // Even though we should suppress the message about not generating these, this is such a
          // weird and surprising situation we should ALWAYS generate a warning.
          // The user code couldn't possibly (barring really weird subclassing shenanigans) be in a
          // shippable state anyway; the implementations of these 3 methods are
          // all inter-related and should be written by the same entity.
          String msg =
              String.format(
                  "Not generating %s: One of equals, hashCode, and canEqual exists. "
                      + "You should either write all of these or none of these (in the latter case, lombok generates them).",
                  equalsExists == MemberExistsResult.NOT_EXISTS
                          && hashCodeExists == MemberExistsResult.NOT_EXISTS
                      ? "equals and hashCode"
                      : equalsExists == MemberExistsResult.NOT_EXISTS ? "equals" : "hashCode");
          source.addWarning(msg);
        }
        return;
      case NOT_EXISTS:
      default:
        // fallthrough
    }

    JCMethodDecl equalsMethod =
        createEquals(
            typeNode,
            nodesForEquality.toList(),
            callSuper,
            fieldAccess,
            needsCanEqual,
            source.get());
    injectMethod(typeNode, equalsMethod);

    if (needsCanEqual) {
      JCMethodDecl canEqualMethod = createCanEqual(typeNode, source.get());
      injectMethod(typeNode, canEqualMethod);
    }

    JCMethodDecl hashCodeMethod =
        createHashCode(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, source.get());
    injectMethod(typeNode, hashCodeMethod);
  }