visitFuncDecl method

  1. @override
Uint8List visitFuncDecl(
  1. FuncDecl stmt
)
override

Implementation

@override
Uint8List visitFuncDecl(FuncDecl stmt) {
  // final savedCurFunc = _curFunc;
  final bytesBuilder = BytesBuilder();
  // TODO: generic param
  if (stmt.category != FunctionCategory.literal) {
    bytesBuilder.addByte(HTOpCode.funcDecl);
    final docs = stmt.documentation;
    if (docs.isNotEmpty && !config.removeDocumentation) {
      bytesBuilder.addByte(1); // bool: has doc
      bytesBuilder.add(_utf8String(docs));
    } else {
      bytesBuilder.addByte(0); // bool: has doc
    }
    // funcBytesBuilder.addByte(HTOpCode.funcDecl);
    bytesBuilder.add(_parseIdentifier(stmt.internalName));
    if (stmt.id != null) {
      bytesBuilder.addByte(1); // bool: hasId
      bytesBuilder.add(_parseIdentifier(stmt.id!.id));
    } else {
      bytesBuilder.addByte(0); // bool: hasId
    }
    if (stmt.classId != null) {
      bytesBuilder.addByte(1); // bool: hasClassId
      bytesBuilder.add(_parseIdentifier(stmt.classId!));
    } else {
      bytesBuilder.addByte(0); // bool: hasClassId
    }
    if (stmt.externalTypeId != null) {
      bytesBuilder.addByte(1); // bool: hasExternalTypedef
      bytesBuilder.add(_parseIdentifier(stmt.externalTypeId!));
    } else {
      bytesBuilder.addByte(0); // bool: hasExternalTypedef
    }
    bytesBuilder.addByte(stmt.category.index);
    bytesBuilder.addByte(stmt.isAsync ? 1 : 0);
    bytesBuilder.addByte(stmt.isField ? 1 : 0);
    bytesBuilder.addByte(stmt.isExternal ? 1 : 0);
    bytesBuilder.addByte(stmt.isStatic ? 1 : 0);
    bytesBuilder.addByte(stmt.isTopLevel ? 1 : 0);
    bytesBuilder.addByte(stmt.isConstValue ? 1 : 0);
  } else {
    bytesBuilder.addByte(HTOpCode.local);
    bytesBuilder.addByte(HTValueTypeCode.function);
    bytesBuilder.add(_parseIdentifier(stmt.internalName));
    if (stmt.externalTypeId != null) {
      bytesBuilder.addByte(1);
      bytesBuilder.add(_parseIdentifier(stmt.externalTypeId!));
    } else {
      bytesBuilder.addByte(0);
    }
    bytesBuilder.addByte(stmt.isAsync ? 1 : 0);
  }
  bytesBuilder.addByte(stmt.hasParamDecls ? 1 : 0);
  bytesBuilder.addByte(stmt.isVariadic ? 1 : 0);
  bytesBuilder.addByte(stmt.minArity);
  bytesBuilder.addByte(stmt.maxArity);
  bytesBuilder.addByte(stmt.paramDecls.length); // max 255
  for (var param in stmt.paramDecls) {
    final bytes = visitParamDecl(param);
    bytesBuilder.add(bytes);
  }
  if (stmt.returnType != null) {
    bytesBuilder.addByte(1); // bool: hasReturnType
    // use compileAst here because there are multiple types of typeExpr
    final bytes = compileAST(stmt.returnType!);
    bytesBuilder.add(bytes);
  } else {
    bytesBuilder.addByte(0); // bool: hasReturnType
  }
  if (stmt.category == FunctionCategory.constructor) {
    // referring to another constructor
    if (stmt.redirectingCtorCallExpr != null) {
      bytesBuilder.addByte(1); // bool: hasRefCtor
      final bytes =
          visitReferConstructCallExpr(stmt.redirectingCtorCallExpr!);
      bytesBuilder.add(bytes);
    } else {
      bytesBuilder.addByte(0); // bool: hasRefCtor
    }
  }
  // definition body
  if (stmt.definition != null) {
    bytesBuilder.addByte(1); // bool: has definition
    bytesBuilder.add(_uint16(stmt.definition!.line));
    bytesBuilder.add(_uint16(stmt.definition!.column));
    final body = compileAST(stmt.definition!);
    bytesBuilder.add(_uint16(body.length + 1)); // definition bytes length
    bytesBuilder.add(body);
    bytesBuilder.addByte(HTOpCode.endOfFunc);
  } else {
    bytesBuilder.addByte(0); // bool: has no definition
  }
  // if (stmt.category != FunctionCategory.literal && !stmt.isField) {
  //   bytesBuilder.addByte(HTOpCode.endOfStmt);
  // }
  return bytesBuilder.toBytes();
}