flatModel()

in lib/semantic.js [3274:3343]


  flatModel(root, modelBody, modelName, extendOn, type = 'model') {
    const keys = new Map();
    for (var i = 0; i < modelBody.nodes.length; i++) {
      const node = modelBody.nodes[i];
      const fieldName = node.fieldName.lexeme;

      if (keys.has(fieldName)) {
        this.error(`redefined field "${fieldName}" in model "${modelName}"`, node.fieldName);
      }
      keys.set(fieldName, true);
      const fieldValue = node.fieldValue;

      if (fieldValue.type === 'modelBody') {
        this.flatModel(root, fieldValue, `${modelName}.${node.fieldName.lexeme}`);
      } else if (fieldValue.type === 'fieldType') {
        // check the type
        if (fieldValue.fieldType.tag === Tag.ID) {
          const typeId = fieldValue.fieldType.lexeme;
          const type = this.getIdType(typeId);
          if (!type) {
            this.error(`the type "${typeId}" is undefined`, fieldValue.fieldType);
          }

          fieldValue.fieldType.idType = type;
        }

        if (fieldValue.fieldType === 'array') {
          const modelBody = this.arrayFieldFlat(node.fieldValue.fieldItemType);
          if (modelBody) {
            const submodel = `${modelName}.${fieldName}`;
            this.flatModel(root, modelBody, submodel);
            node.fieldValue.itemType = submodel;
          }
        }

        if (fieldValue.fieldType === 'map') {
          this.checkType(fieldValue.valueType);
        }

        if (fieldValue.fieldType === 'entry') {
          this.checkType(fieldValue.valueType);
        }

        if (fieldValue.fieldType.type === 'subModel_or_moduleModel') {
          this.checkType(fieldValue.fieldType);
        }

        if (typeof fieldValue.fieldType === 'string') {
          this.usedTypes.set(fieldValue.fieldType, true);
        }
      } else {
        throw new Error('unimplemented');
      }
    }

    const isException = type === 'exception';

    modelBody.extendFileds = this.getExtendFileds(extendOn, isException);
    this.models.set(modelName, {
      type: type,
      isException: isException,
      extendOn: extendOn,
      modelName: {
        tag: Tag.ID,
        lexeme: modelName
      },
      modelBody: modelBody,
      annotation: undefined
    });
  }