fieldValue()

in lib/parser.js [767:872]


  fieldValue() {
    // fieldValue = ( type | arrayType | modelBody | mapType )
    // attrs =  "(" attr { "," attr } ")"
    // attr = attrName "=" constant
    // type = "string" | "number" | "boolean"
    // mapType = "map" "[" type "]" type
    if (this.look.tag === '{') {
      return this.modelBody();
    }

    if (this.look.tag === '[') {
      const node = {
        type: 'fieldType',
        fieldType: 'array',
      };
      this.move();
      if (this.look.tag === '[') {
        node.fieldItemType = this.fieldValue();
      } else if (this.look.tag === Tag.TYPE || this.look.tag === Tag.ID) {
        const type = this.baseType();
        node.fieldItemType = type;
      } else if (this.look.tag === '{') {
        node.fieldItemType = this.modelBody();
      } else {
        this.error('expect type or model name');
      }

      this.match(']');
      return node;
    }

    if (this.look.tag === Tag.TYPE) {
      const type = this.look;
      this.move();

      if (type.lexeme === 'map') {
        this.match('[');
        const keyType = this.baseType();
        this.match(']');
        const valueType = this.baseType();
        return {
          type: 'fieldType',
          fieldType: type.lexeme,
          keyType: keyType,
          valueType: valueType
        };
      }

      if (type.lexeme === 'entry') {
        this.match('[');
        const valueType = this.baseType();
        this.match(']');
        return {
          type: 'fieldType',
          fieldType: type.lexeme,
          valueType: valueType
        };
      }

      if (type.lexeme === 'iterator' || type.lexeme === 'asyncIterator') {
        this.match('[');
        const valueType = this.baseType();
        this.match(']');
        return {
          type: 'fieldType',
          fieldType: type.lexeme,
          valueType: valueType,
        };
      }

      return {
        type: 'fieldType',
        fieldType: type.lexeme
      };
    }

    if (this.look.tag === Tag.ID) {
      const model = this.look;
      this.move();
      // for A.B
      if (this.look.tag === '.') {
        const path = [model];
        while (this.look.tag === '.') {
          this.move();
          const id = this.look;
          path.push(id);
          this.match(Tag.ID);
        }

        return {
          type: 'fieldType',
          fieldType: {
            type: 'subModel_or_moduleModel',
            path: path
          }
        };
      }

      return {
        type: 'fieldType',
        fieldType: model
      };
    }

    this.error('expect "{", "[", "string", "number", "map", ID');
  }