visitYield()

in lib/generator.js [2910:3040]


  visitYield(ast, level, env) {
    assert.equal(ast.type, 'yield');
    // TODO
    if (ast.expr.type === 'null' || ast.expr.type === 'variable' ||
      ast.expr.type === 'property_access' || ast.expr.type === 'virtualVariable' || 
      ast.expr.type === 'decrement' ||  ast.expr.type === 'increment' || ast.expr.type === 'construct_model' ||
      ast.expr.type === 'group' || _isBinaryOp(ast.expr.type)) {
      this.emit(`_yield <- `, level);
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
      return;
    }

    var returnType = '';
    if (env.returnType.idType === 'module') {
      this.emit(`yield <- ${this.clientName[_name(env.returnType)].replace('*', '&')}{}\n`, level);
    } else if (_name(env.returnType) && !(DSL.util.isBasicType(_name(env.returnType)) && !_isFilterType(_name(env.returnType)))
      && env.returnType.idType !== 'typedef') {
      this.emit(`yield <- ${_initValue(_name(env.returnType))}\n`, level);
    } else if (env.returnType.path && env.returnType.type !== 'moduleTypedef') {
      for (let i = 0; i < env.returnType.path.length; i++) {
        const path = env.returnType.path[i];
        if (i === 0) {
          returnType += _name(path).toLowerCase();
        } else {
          returnType += '.' + _name(path);
        }
      }
      this.emit(`yield <- ${_initValue(returnType)}\n`, level);
    } else if (env.returnType.type === 'map') {
      this.emit(`yield <- make(`, level);
      this.visitPointerType(env.returnType, level, env);
      this.emit(`)\n`);
    } else if (env.returnType.type === 'array') {
      this.emit(`yield <- make(`, level);
      this.visitPointerType(env.returnType, level, env);
      this.emit(`, 0)\n`);
    } 

    if (ast.expr.type === 'call') {
      var argHasThrowFunc = this.visitFunctionNested(ast.expr, level, env);
      var hasThrow = false;
      hasThrow = ast.expr.hasThrow;
      if (hasThrow) {
        this.emit(`_body, _err := `, level);
      } else {
        this.emit(`_body := `, level);
      }
      this.visitExpr(ast.expr, level, env, { pointer: true }, argHasThrowFunc);
      this.emit(`\n`);
      if (hasThrow) {
        this.emit(`if _err != nil {\n`, level);
        this.emit(`_yieldErr <- _err\n`, level + 1);
        this.emit(`return\n`, level + 1);
        this.emit(`}\n`, level);
      }
      if (!ast.needCast) {
        this.emit(`yield <- _body\n`, level);
      } else {
        if (env.hasThrow) {
          this.emit(`_err := dara.ConvertChan(_body, _yield)\n`, level);
          this.emit(`if _err != nil {\n`, level);
          this.emit(`_yieldErr <- _err\n`, level + 1);
          this.emit(`return\n`, level + 1);
          this.emit(`}\n`, level);
        } else {
          this.emit(`dara.ConvertChan(_body, _yield)\n`, level);
        }
      }
    } else if (ast.expr.type === 'template_string') {
      this.emit(`yield <- `, level);
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
    } else if (ast.expr.fields) {
      // for (let i = 0; i < ast.expr.fields.length; i++) {
      //   const field = ast.expr.fields[i];
      //   if (field.expr.inferred && _name(field.expr.inferred) === 'readable') {
      //     this.emit(
      //       `_result.${_format(_name(field.fieldName))} = `,
      //       level
      //     );
      //     this.visitExpr(field.expr);
      //     this.emit(`\n`);
      //     delete ast.expr.fields[i];
      //   }
      // }
      if (env.hasThrow) {
        this.emit(`_err := dara.ConvertChan(`, level);
      } else {
        this.emit(`dara.ConvertChan(`, level);
      }
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`, _yield)\n`);
      if (env.hasThrow) {
        this.emit(`if _err != nil {\n`, level);
        this.emit(`_yieldErr <- _err\n`, level + 1);
        this.emit(`return\n`, level + 1);
        this.emit(`}\n`, level);
      }
    } else if (ast.expr.items) {
      if (env.hasThrow) {
        this.emit(`_err := dara.ConvertChan(`, level);
      } else {
        this.emit(`dara.ConvertChan(`, level);
      }
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`, _yield)\n`);
      if (env.hasThrow) {
        this.emit(`if _err != nil {\n`, level);
        this.emit(`_yieldErr <- _err\n`, level + 1);
        this.emit(`return\n`, level + 1);
        this.emit(`}\n`, level);
      }
    } else if (ast.expr.type === 'construct') {
      this.emit(`_result, _err := `, level);
      this.visitConstruct(ast.expr, level, env);
      this.emit(`\n`);
      this.emit(`if _err != nil {\n`, level);
      this.emit(`_yieldErr <- _err\n`, level + 1);
      this.emit(`return\n`, level + 1);
      this.emit(`}\n`, level);
    } else if (ast.expr.type === 'map_access') {
      this.emit(`yield <- `, level);
      this.visitMapAccess(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
    } else if (DSL.util.isBasicType(ast.expr.type)) {
      this.emit(`yield <- `, level);
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
    }
  }