toToken method

Token toToken()

converts the current String into Token which can be used to generate code

Implementation

Token toToken() {
  String type = clearClassAccess();

  // we assume that [] and pointers will not exist at the same time in a steam type
  Iterable<RegExpMatch> pointerMatches = RegExp(r"(\*|&)").allMatches(type);
  Iterable<RegExpMatch> arrayMatches =
      RegExp(r"(?:\[(.*?)\])").allMatches(type);

  type = type.clearPointerOrConst().trim();

  String typeDart;
  String typeFfiDart;
  String typeFfiC;
  String typeAnnotation;
  String fieldAccessor = "{0}";
  String caller = "{0}";
  TokenType tokenType;
  switch (type) {
    // primitives
    case "void":
      typeDart = "void";
      typeFfiDart = typeDart;
      typeFfiC = "Void";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "bool":
      typeDart = "bool";
      typeFfiDart = typeDart;
      typeFfiC = "Bool";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "size_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Size";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "unsigned char":
    case "uint8":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UnsignedChar";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "signed char":
    case "int8":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "SignedChar";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "short":
    case "int16":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Short";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "unsigned short":
    case "uint16":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UnsignedShort";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "int":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Int";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "unsigned int":
    case "uint32":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UnsignedInt";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "long long":
    case "intp":
    case "int64":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "LongLong";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "unsigned long long":
    case "uintp":
    case "uint64":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UnsignedLongLong";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "uint32_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UInt32";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "uint16_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UInt16";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "int32":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Int";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "int32_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Int32";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    // case "uint":
    case "int64_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Int64";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "uint64_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UInt64";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "int16_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Int16";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "int8_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Int8";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "uint8_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "UInt8";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "char":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "Char";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "intptr_t":
      typeDart = "int";
      typeFfiDart = typeDart;
      typeFfiC = "IntPtr";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "double":
      typeDart = "double";
      typeFfiDart = typeDart;
      typeFfiC = "Double";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;
    case "float":
      typeDart = "double";
      typeFfiDart = typeDart;
      typeFfiC = "Float";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.primitive;

    // enums
    case "EFailureType":
    case "PlayerAcceptState_t":
    case "ESteamIPType":
    case "EUniverse":
    case "EResult":
    case "EVoiceResult":
    case "EDenyReason":
    case "EBeginAuthSessionResult":
    case "EAuthSessionResponse":
    case "EUserHasLicenseForAppResult":
    case "EAccountType":
    case "EChatEntryType":
    case "EChatRoomEnterResponse":
    case "EChatSteamIDInstanceFlags":
    case "ENotificationPosition":
    case "EBroadcastUploadResult":
    case "EMarketNotAllowedReasonFlags":
    case "EDurationControlProgress":
    case "EDurationControlNotification":
    case "EDurationControlOnlineState":
    case "EGameSearchErrorCode_t":
    case "EPlayerResult_t":
    case "ESteamIPv6ConnectivityProtocol":
    case "ESteamIPv6ConnectivityState":
    case "EFriendRelationship":
    case "EPersonaState":
    case "EFriendFlags":
    case "EUserRestriction":
    case "EOverlayToStoreFlag":
    case "EActivateGameOverlayToWebPageMode":
    case "EPersonaChange":
    case "ESteamAPICallFailure":
    case "EGamepadTextInputMode":
    case "EGamepadTextInputLineMode":
    case "EFloatingGamepadTextInputMode":
    case "ETextFilteringContext":
    case "ECheckFileSignature":
    case "EMatchMakingServerResponse":
    case "ELobbyType":
    case "ELobbyComparison":
    case "ELobbyDistanceFilter":
    case "EChatMemberStateChange":
    case "ESteamPartyBeaconLocationType":
    case "ESteamPartyBeaconLocationData":
    case "ERemoteStoragePlatform":
    case "ERemoteStoragePublishedFileVisibility":
    case "EWorkshopFileType":
    case "EWorkshopVote":
    case "EWorkshopFileAction":
    case "EWorkshopEnumerationType":
    case "EWorkshopVideoProvider":
    case "EUGCReadAction":
    case "ERemoteStorageLocalFileChange":
    case "ERemoteStorageFilePathType":
    case "ELeaderboardDataRequest":
    case "ELeaderboardSortMethod":
    case "ELeaderboardDisplayType":
    case "ELeaderboardUploadScoreMethod":
    case "ERegisterActivationCodeResult":
    case "EP2PSessionError":
    case "EP2PSend":
    case "ESNetSocketState":
    case "ESNetSocketConnectionType":
    case "EVRScreenshotType":
    case "AudioPlayback_Status":
    case "EHTTPMethod":
    case "EHTTPStatusCode":
    case "EInputSourceMode":
    case "EInputActionOrigin":
    case "EXboxOrigin":
    case "ESteamControllerPad":
    case "EControllerHapticLocation":
    case "EControllerHapticType":
    case "ESteamInputType":
    case "ESteamInputConfigurationEnableType":
    case "ESteamInputLEDFlag":
    case "ESteamInputGlyphSize":
    case "ESteamInputGlyphStyle":
    case "ESteamInputActionEventType":
    case "EControllerActionOrigin":
    case "ESteamControllerLEDFlag":
    case "EUGCMatchingUGCType":
    case "EUserUGCList":
    case "EUserUGCListSortOrder":
    case "EUGCQuery":
    case "EItemUpdateStatus":
    case "EItemState":
    case "EItemStatistic":
    case "EItemPreviewType":
    case "ESteamItemFlags":
    case "EParentalFeature":
    case "ESteamDeviceFormFactor":
    case "ESteamNetworkingAvailability":
    case "ESteamNetworkingIdentityType":
    case "ESteamNetworkingFakeIPType":
    case "ESteamNetworkingConnectionState":
    case "ESteamNetConnectionEnd":
    case "ESteamNetworkingConfigScope":
    case "ESteamNetworkingConfigDataType":
    case "ESteamNetworkingConfigValue":
    case "ESteamNetworkingGetConfigValueResult":
    case "ESteamNetworkingSocketsDebugOutputType":
    case "EServerMode":
    case "EHTMLMouseButton":
    case "EMouseCursor":
    case "EHTMLKeyModifiers":
    case "ECommunityProfileItemType":
    case "ECommunityProfileItemProperty":
    case "EUGCContentDescriptorID":
    case "ETimelineGame":
    case "ETimelineGameMode":
    case "ESteamAPIInitResult":
    case "EBetaBranchFlags":
    case "ETimelineEventClipPriority":
      typeDart = type.clearSteamNaming();
      typeFfiDart = "${typeDart}AliasDart";
      typeFfiC = "${typeDart}AliasC";
      typeAnnotation = "Int32()";

      if (pointerMatches.isEmpty && arrayMatches.isEmpty) {
        fieldAccessor = "$typeDart.fromValue({0})";
        caller = "{0}.value";
      }

      tokenType = TokenType.enums;

    // typedefs
    case "HSteamPipe":
    case "HSteamUser":
    case "HServerQuery":
    case "SteamItemDef_t":
    case "SteamInventoryResult_t":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "Int";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.typedefs;
    case "FriendsGroupID_t":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "Short";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.typedefs;
    case "AppId_t":
    case "DepotId_t":
    case "RTime32":
    case "AccountID_t":
    case "HAuthTicket":
    case "SNetSocket_t":
    case "SNetListenSocket_t":
    case "ScreenshotHandle":
    case "HTTPRequestHandle":
    case "HTTPCookieContainerHandle":
    case "HHTMLBrowser":
    case "RemotePlaySessionID_t":
    case "HSteamNetConnection":
    case "HSteamListenSocket":
    case "HSteamNetPollGroup":
    case "SteamNetworkingPOPID":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "UnsignedInt";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.typedefs;
    case "CSteamID":
    case "CGameID":
    case "SteamAPICall_t":
    case "PartyBeaconID_t":
    case "UGCHandle_t":
    case "PublishedFileUpdateHandle_t":
    case "PublishedFileId_t":
    case "UGCFileWriteStreamHandle_t":
    case "SteamLeaderboard_t":
    case "SteamLeaderboardEntries_t":
    case "InputHandle_t":
    case "InputActionSetHandle_t":
    case "InputDigitalActionHandle_t":
    case "InputAnalogActionHandle_t":
    case "ControllerHandle_t":
    case "ControllerActionSetHandle_t":
    case "ControllerDigitalActionHandle_t":
    case "ControllerAnalogActionHandle_t":
    case "UGCQueryHandle_t":
    case "UGCUpdateHandle_t":
    case "SteamItemInstanceID_t":
    case "SteamInventoryUpdateHandle_t":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "UnsignedLongLong";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.typedefs;
    case "SteamNetworkingMicroseconds":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "LongLong";
      typeAnnotation = "$typeFfiC()";
      tokenType = TokenType.typedefs;
    case "HServerListRequest":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "Pointer<Void>";
      typeAnnotation = "";
      tokenType = TokenType.typedefs;
    case "SteamNetworkingErrMsg":
    case "SteamErrMsg":
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = "Utf8";
      typeAnnotation = "";
      tokenType = TokenType.typedefs;

    //functions
    // TODO pointers gets lost so we can not distinguish SteamNetworkingMessage_t vs SteamNetworkingMessage_t *
    case "void ()(SteamNetworkingMessage_t )":
      typeDart =
          "Pointer<NativeFunction<Pointer<Void> Function(Pointer<SteamNetworkingMessage>)>>";
      typeFfiDart = typeDart;
      typeFfiC = typeDart;
      typeAnnotation = "";
      tokenType = TokenType.function;

    // structs or interfaces
    default:
      typeDart = type.clearSteamNaming();
      typeFfiDart = typeDart;
      typeFfiC = typeDart;
      typeAnnotation = "";
      tokenType = TokenType.structOrInterface;
  }

  if (tokenType != TokenType.function) {
    if (pointerMatches.isNotEmpty) {
      String prefix = pointerMatches.map((m) => "Pointer<").join();
      String postfix = pointerMatches.map((m) => ">").join();

      if (typeFfiC == "Char") {
        typeFfiC = "Utf8";
      }

      typeFfiC = "$prefix$typeFfiC$postfix";
      typeDart = typeFfiC;
      typeFfiDart = typeFfiC;
      typeAnnotation = "";
    } else if (arrayMatches.isNotEmpty) {
      String prefix = arrayMatches.map((m) => "Array<").join();
      String postfix = arrayMatches.map((e) => ">").join();
      String arrayDimensions = arrayMatches.map((m) => m.group(1)!).join(",");

      typeFfiC = "$prefix$typeFfiC$postfix";
      typeDart = typeFfiC;
      typeFfiDart = typeFfiC;
      typeAnnotation = "$typeFfiC($arrayDimensions)";
    }
  }

  Token token = Token(
    typeDart: typeDart,
    typeFfiDart: typeFfiDart,
    typeFfiC: typeFfiC,
    typeAnnotation: typeAnnotation,
    fieldAccessor: fieldAccessor,
    caller: caller,
    tokenType: tokenType,
  );

  return token;
}