Exemplo n.º 1
0
  public static void generateImplementation(IndentWriter writer, IXMLElement klass)
      throws IOException {
    String superClass = ModelAccessor.getSuperClass(klass);
    String name = XMLUtil.getAttribute(klass, "name");

    if (ModelAccessor.isPredefinedClass(name)) {
      writer.write("// SKIPPING IMPLEMENTATION FOR BUILT-IN CLASS " + name + "\n\n");
      return;
    }

    ModelAccessor.setCurrentObjectType(name);

    String longname = XMLUtil.qualifiedName(klass);

    boolean extendsBuiltIn = ModelAccessor.isPredefinedClass(superClass);

    String superCppClass = ModelAccessor.getCppClass(superClass);

    writer.write("\n");
    SharedWriter.generateFileLocation(writer, klass);
    writer.write(
        longname + "::" + name + "(const PlanDatabaseId& planDatabase, const LabelStr& name)\n");
    if (extendsBuiltIn)
      writer.write(" : " + superCppClass + "(planDatabase, \"" + name + "\", name, true)");
    else writer.write(" : " + superCppClass + "(planDatabase, \"" + name + "\", name)");
    writer.write(" {\n");
    writer.write("}\n");

    writer.write(
        longname
            + "::"
            + name
            + "(const PlanDatabaseId& planDatabase, const LabelStr& type, const LabelStr& name)\n");
    if (extendsBuiltIn) writer.write(" : " + superCppClass + "(planDatabase, type, name, true)");
    else writer.write(" : " + superCppClass + "(planDatabase, type, name)");
    writer.write(" {\n");
    writer.write("}\n");

    writer.write(longname + "::" + name + "(const ObjectId& parent, const LabelStr& name)\n");
    if (extendsBuiltIn)
      writer.write(" : " + superCppClass + "(parent, \"" + name + "\", name, true)");
    else writer.write(" : " + superCppClass + "(parent, \"" + name + "\", name)");
    writer.write(" {}\n");

    writer.write(
        longname
            + "::"
            + name
            + "(const ObjectId& parent, const LabelStr& type, const LabelStr& name)\n");
    if (extendsBuiltIn) writer.write(" : " + superCppClass + "(parent, type, name, true)");
    else writer.write(" : " + superCppClass + "(parent, type, name)");
    writer.write(" {}\n");

    Vector classVariables = klass.getChildrenNamed("var");
    SharedWriter.defineHandleDefaults(writer, klass, classVariables);

    generateChildren(writer, klass);
    ModelAccessor.resetCurrentObjectType();
  }
Exemplo n.º 2
0
  public static void defineConstructor(IndentWriter writer, IXMLElement constructor)
      throws IOException {
    assert (DebugMsg.debugMsg("ClassWriter", "Begin ClassWriter::defineConstructor"));
    IXMLElement klass = constructor.getParent();
    SharedWriter.generateFileLocation(writer, klass);

    if (klass == null) {
      throw new RuntimeException("missing class for constructor");
    }

    String longname = XMLUtil.nameOf(klass);
    writer.write("void " + longname + "::");
    generateSignature(writer, constructor);
    writer.write(" {\n");
    writer.indent();

    // If the constructor has a call to the super class, invoke it.
    assert (DebugMsg.debugMsg(
        "ClassWriter", "ClassWriter::defineConstructor -  getting children named 'super'"));
    Vector superCalls = constructor.getChildrenNamed("super");
    assert (DebugMsg.debugMsg(
        "ClassWriter",
        "ClassWriter::defineConstructor -  " + superCalls.size() + " children named retrieved"));
    if (!superCalls.isEmpty()) {
      assert (DebugMsg.debugMsg("ClassWriter", "ClassWriter::defineConstructor -  calling super"));

      if (superCalls.size() > 1) writer.write("!ERROR: AT MOST ONE CALL TO SUPER ALLOWED\n");

      IXMLElement superCall = (IXMLElement) superCalls.elementAt(0);
      String superClass = ModelAccessor.getParentClassName(klass);
      String superCppClass = ModelAccessor.getCppClass(superClass);
      writer.write(superCppClass + "::constructor(");
      String comma = "";
      Enumeration arguments = superCall.enumerateChildren();
      while (arguments.hasMoreElements()) {
        IXMLElement argument = (IXMLElement) arguments.nextElement();
        String value = ModelAccessor.getValue(argument);
        if (argument.getName().equals("value")
            && XMLUtil.getAttribute(argument, "type").equals("string"))
          writer.write(comma + "\"" + value + "\"");
        else writer.write(comma + value);
        comma = ", ";
      }
      writer.write(");\n");
    }

    Set allocatedMemberVariables = new HashSet(); // Store names as we go for reference

    /* Now capture names of constructor arguments */
    Set constructorArguments = new HashSet(); // Store for names of constructor arguments
    {
      Vector args = constructor.getChildrenNamed("arg");
      assert (DebugMsg.debugMsg(
          "ClassWriter",
          "ClassWriter::defineConstructor -  getting " + args.size() + " arguments"));
      for (int i = 0; i < args.size(); i++) {
        IXMLElement arg = (IXMLElement) args.elementAt(i);
        String argName = XMLUtil.getAttribute(arg, "name");
        constructorArguments.add(argName);
      }
    }

    Vector constructorAssignments = constructor.getChildrenNamed("assign");
    Vector classVariables = klass.getChildrenNamed("var");

    // Use the set below  to track when an assignment is being made more than once for same variable
    Set assignmentsMade = new HashSet();

    for (int i = 0; i < constructorAssignments.size(); i++) {
      IXMLElement element = (IXMLElement) constructorAssignments.elementAt(i);
      String target = XMLUtil.getAttribute(element, "name");

      if (assignmentsMade.contains(target)) {
        writer.write("!ERROR: Duplicate assignment for " + target + "\n");
      } else {
        assignmentsMade.add(target);
        // String type = getVariableType(classVariables, target);
        // trust in the parser, for it will assign the correct types
        String type = XMLUtil.getAttribute(element, "type");
        IXMLElement sourceElement = element.getChildAtIndex(0);

        if (sourceElement.getName().equals("new")) { // Handle object allocation
          assert (DebugMsg.debugMsg(
              "ClassWriter", "ClassWriter::defineConstructor -  allocating object for " + target));
          String sourceType = XMLUtil.typeOf(sourceElement);
          writer.write(target + " = addVariable(");
          writer.write(
              sourceType
                  + "Domain((new "
                  + sourceType
                  + "(m_id, \""
                  + target
                  + "\"))->getId(), \""
                  + sourceType
                  + "\")");
          writer.write(", " + makeObjectVariableNameString(target) + ");\n");
          writer.write(
              "Id<"
                  + type
                  + ">(singleton("
                  + target
                  + "))->constructor("
                  + buildArguments(
                      classVariables, constructorArguments, allocatedMemberVariables, sourceElement)
                  + ");\n"); // Invoke initialization
          writer.write(
              "Id<"
                  + type
                  + ">(singleton("
                  + target
                  + "))->handleDefaults();\n"); // Default variable setup
        } else { // Handle variable allocation
          String value = ModelAccessor.getValue(sourceElement);

          if (sourceElement.getName().equals("id") && type.equals(NddlXmlStrings.x_string))
            value = XMLUtil.escapeQuotes(value);
          else if (sourceElement.getName().equals(NddlXmlStrings.x_symbol)
              || XMLUtil.getAttribute(sourceElement, "type").equals(NddlXmlStrings.x_string))
            value = "LabelStr(\"" + XMLUtil.escapeQuotes(value) + "\")";
          else if (ModelAccessor.isNumericPrimitive(type)
              && !type.equals(NddlXmlStrings.x_boolean)) {
            // Set both bounds to singleton value
            value = value + ", " + value;
          }

          writer.write(target + " = addVariable(");

          if (allocatedMemberVariables.contains(
              value)) // If we are assigning one member to another, we obtain the base domain for it
          writer.write(value + "->baseDomain()");
          else writer.write(ModelAccessor.getDomain(type) + "(" + value + ", \"" + type + "\")");

          writer.write(", " + makeObjectVariableNameString(target) + ");\n");
        }
        // Add member to the set
        allocatedMemberVariables.add(target);
      }
    }

    writer.unindent();
    writer.write("}\n");
    assert (DebugMsg.debugMsg("ClassWriter", "End ClassWriter::defineConstructor"));
  }