visitReturn()

in lib/generator.js [3042:3182]


  visitReturn(ast, level, env) {
    assert.equal(ast.type, 'return');
    if(env.yieldErrDeal) {
      this.emit(`_err = <- _yieldErr\n`, level);
    }
    if (!ast.expr && !env.finallyBlock) {
      if (env.hasThrow && env.runtimeBody) {
        this.emit(`return _err\n`, level);
      } else {
        this.emit(`return\n`, level);
      }
      return;
    }

    if(_name(env.returnType) === 'void') {
      if (env.hasThrow && env.runtimeBody) {
        this.emit(`return _err\n`, level);
      } else {
        this.emit(`return\n`, level);
      }
      return;
    }

    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 === 'group' || _isBinaryOp(ast.expr.type)) {
      this.emit(`_result = `, level);
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
      if(!env.finallyBlock) {
        if (env.hasThrow) {
          this.emit(`return _result , _err`, level);
        } else {
          this.emit(`return _result`, level);
        }
        this.emit(`\n`);
        env.hasReturn = false;
      }
      return;
    }

    // if (env.returnType.idType === 'module') {
    //   this.emit(`_result = ${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(`_result = ${_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(`_result = ${_initValue(returnType)}\n`, level);
    // } else if (env.returnType.type === 'map') {
    //   this.emit(`_result = make(`, level);
    //   this.visitPointerType(env.returnType, level, env);
    //   this.emit(`)\n`);
    // } else if (env.returnType.type === 'array') {
    //   this.emit(`_result = 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(`return _result, _err\n`, level + 1);
        this.emit(`}\n`, level);
      }
      if (!ast.needCast) {
        this.emit(`_result = _body\n`, level);
      } else {
        if (env.hasThrow) {
          this.emit(`_err = dara.Convert(_body, &_result)\n`, level);
        } else {
          this.emit(`dara.Convert(_body, &_result)\n`, level);
        }
      }
    } else if (ast.expr.type === 'template_string') {
      this.emit(`_result = `, 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.Convert(`, level);
      } else {
        this.emit(`dara.Convert(`, level);
      }
      
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`, &_result)\n`);
      this.emit('\n');
    } else if (ast.expr.items) {
      this.emit('_result = ', level);
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit('\n');
    } else if (ast.expr.type === 'construct') {
      this.emit(`_result, _err = `, level);
      this.visitConstruct(ast.expr, level, env);
      this.emit(`\n`);
    } else if (ast.expr.type === 'map_access') {
      this.emit(`_result = `, level);
      this.visitMapAccess(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
    } else if (DSL.util.isBasicType(ast.expr.type)) {
      this.emit(`_result = `, level);
      this.visitExpr(ast.expr, level, env, { pointer: true });
      this.emit(`\n`);
    }
    if(!env.finallyBlock) {
      if (env.hasThrow) {
        this.emit(`return _result, _err\n`, level);
      } else {
        this.emit(`return _result\n`, level);
      }
      env.hasReturn = false;
    }
  }