Example #1
-1
  /**
   * Called after the creation of any module. Used as a workaround for filling tokens that are in no
   * way available in the code-completion through the regular inspection.
   *
   * <p>The django objects class is the reason why this happens... It's structure for the creation
   * on a model class follows no real patterns for the creation of the 'objects' attribute in the
   * class, and thus, we have no real generic way of discovering it (actually, even by looking at
   * the class definition this is very obscure), so, the solution found is creating the objects by
   * decorating the module with that info.
   */
  private AbstractModule decorateModule(AbstractModule n, IPythonNature nature) {
    if (n instanceof SourceModule && "django.db.models.base".equals(n.getName())) {
      SourceModule sourceModule = (SourceModule) n;
      SimpleNode ast = sourceModule.getAst();
      for (SimpleNode node : ((Module) ast).body) {
        if (node instanceof ClassDef && "Model".equals(NodeUtils.getRepresentationString(node))) {
          Object[][] metaclassAttrs =
              new Object[][] {
                {"objects", NodeUtils.makeAttribute("django.db.models.manager.Manager()")},
                {"DoesNotExist", new Name("Exception", Name.Load, false)},
                {"MultipleObjectsReturned", new Name("Exception", Name.Load, false)},
              };

          ClassDef classDef = (ClassDef) node;
          stmtType[] newBody = new stmtType[classDef.body.length + metaclassAttrs.length];
          System.arraycopy(classDef.body, 0, newBody, metaclassAttrs.length, classDef.body.length);

          int i = 0;
          for (Object[] objAndType : metaclassAttrs) {
            // Note that the line/col is important so that we correctly acknowledge it inside the
            // "class Model" scope.
            Name name = new Name((String) objAndType[0], Name.Store, false);
            name.beginColumn = classDef.beginColumn + 4;
            name.beginLine = classDef.beginLine + 1;
            newBody[i] = new Assign(new exprType[] {name}, (exprType) objAndType[1]);
            newBody[i].beginColumn = classDef.beginColumn + 4;
            newBody[i].beginLine = classDef.beginLine + 1;

            i += 1;
          }

          classDef.body = newBody;
          break;
        }
      }
    }
    return n;
  }