This is really trying my patience. Converting a C# class to F# using regex. Not the cleanest or sanest approach, but really with the patterns in the code I'm targeting it shouldn't be a very big deal
I welcome any and all input or suggestions besides do it with a real code parser/generator (I've done lots of work in this area and realize the benefits, but I'm working on something that isn't as robust but gets the job done)
vim
:set magic? returns:
magic
I started out with the following code
namespace PracticeManagement.Foundation.DataModels
{
public class BillingStageDataAccess
{
public static IEnumerable<BillingStageDataModel> LoadRejectedGrid(string payerId, Connector cn)
{
return Pm.Dal.BillingStages.loadRejectedGrid(payerId, SessionVariables.Instance.CurrentFacility.FacilityID, cn)
.Select(r => new BillingStageDataModel(r));
}
public static IEnumerable<BillingStageDataModel> LoadPendingGrid(string payerId, Connector cn)
{
return Pm.Dal.BillingStages.loadPendingGrid(payerId, SessionVariables.Instance.CurrentFacility.FacilityID, cn)
.Select(r=> new BillingStageDataModel(r));
}
public static IEnumerable<BillingStageDataModel> LoadReviewGrid(string payerId, Connector cn)
{
return Pm.Dal.BillingStages.loadReviewGrid(payerId, SessionVariables.Instance.CurrentFacility.FacilityID, cn)
.Select(r => new BillingStageDataModel(r));
}
public static IEnumerable<BillingStageDataModel> LoadPatientBilling(bool? includeThirdParty, Connector cn)
{
return Pm.Dal.BillingStages.loadPatientBilling(SessionVariables.Instance.CurrentFacility.FacilityID, includeThirdParty, cn).Select(bsm => new BillingStageDataModel(new Pm.Schema.BillingStageRecord(bsm.Age.ToString(), 0m, 0m, bsm.DOS ?? DateTime.Now, null, 0, bsm.FirstStatement ?? DateTime.Now, bsm.NofStatements ?? 0, bsm.PatientName, bsm.ThirdPartyPayerId ?? 0, null, null, bsm.Appointmentid ?? 0, null, null)) { PrimaryGuarantorType= bsm.AppointmentPrimaryGuarantorType });
}
public static IEnumerable<BillingStageDataModel> LoadCompleted(Connector cn)
{
return Pm.Dal.BillingStages.loadCompleted(SessionVariables.Instance.CurrentFacility.FacilityID, cn).Select(bsm => new BillingStageDataModel(new Pm.Schema.BillingStageRecord(null,bsm.ClaimAmount ?? 0, 0, bsm.DOS ?? DateTime.Now, bsm.Claimdate ?? DateTime.Now, bsm.Daysfilled ?? 0, null, 0,bsm.PatientName, 0, bsm.Claimstatus, null, bsm.Appointmentid ?? 0,null,null)));
}
public static IEnumerable<BillingStageDataModel> LoadPrepGrid(int facilityId, Connector cn)
{
return Pm.Dal.BillingStages.loadPrepClaimGrid(facilityId, cn).Select(r => new BillingStageDataModel(r));
}
}
}
Stage 1
- use
dd to delete the namespace and class lines
- add
module name =
- highlight that block pasted into an F# file.
- then apply the regex to remove lines that only open or close blocks
:'<,'>s:^\s*[{}]\s*$:
regex irritation
* doesn't need an escape but in other places + does
- that leaves a bunch of empty lines unfortunately
Stage 2
- re-highlight with
gv
- then eliminate the
public static T with
:'<,'>s:public static [\w<>]\+:let
regex irritation
Stage 3
- re-highlight with
gv
- fix indention with
<< followed by . as needed
- re-highlight with
gv
- eliminate returns with
:'<,'>s/return /
- re-highlight with
gv
- add
= on the end of the let lines with :'<,'>s:let .*:\0 =
- re-highlight with
gv
- Fix casing to my preference for module methods (camel-case) with
:'<,'>s:let \(\u\w\+\):let \l\1 or closer to regular regex :'<,'>s:let \([A-Z]\w\+\):let \l\1
regex inconsistencies and irritations
- had to escape
( and ) for capturing groups
- had to escape
+ (:'<,'>s:let \(\u\w+\):let \l\1 did not work)
- didn't have to escape any of the following
.*
Stage 4 (work in progress)
fix up the method declarations a little more
- re-highlight with
gv
- regex:
:'<,'>s/\(let \w\+\)(\?\(\w\+\)\(?\)\? \(\w\+\)[,)]/\1(\3\4:\2)/
- switch the order of type and name
- move
? (Nullable to the front for replacement with the word `Nullable` in F#)
- add : of the first argument on method declaration lines with
which leaves me with the following to convert so far
module BillingStages =
let loadRejectedGrid(payerId:string) Connector cn) =
Pm.Dal.BillingStages.loadRejectedGrid(payerId, SessionVariables.Instance.CurrentFacility.FacilityID, cn)
.Select(r => new BillingStageDataModel(r));
let loadPendingGrid(payerId:string) Connector cn) =
Pm.Dal.BillingStages.loadPendingGrid(payerId, SessionVariables.Instance.CurrentFacility.FacilityID, cn)
.Select(r=> new BillingStageDataModel(r));
let loadReviewGrid(payerId:string) Connector cn) =
Pm.Dal.BillingStages.loadReviewGrid(payerId, SessionVariables.Instance.CurrentFacility.FacilityID, cn)
.Select(r => new BillingStageDataModel(r));
let loadPatientBilling(?includeThirdParty:bool) Connector cn) =
Pm.Dal.BillingStages.loadPatientBilling(SessionVariables.Instance.CurrentFacility.FacilityID, includeThirdParty, cn).Select(bsm => new BillingStageDataModel(new Pm.Schema.BillingStageRecord(bsm.Age.ToString(), 0m, 0m, bsm.DOS ?? DateTime.Now, null, 0, bsm.FirstStatement ?? DateTime.Now, bsm.NofStatements ?? 0, bsm.PatientName, bsm.ThirdPartyPayerId ?? 0, null, null, bsm.Appointmentid ?? 0, null, null)) { PrimaryGuarantorType= bsm.AppointmentPrimaryGuarantorType });
let loadCompleted(cn:Connector) =
Pm.Dal.BillingStages.loadCompleted(SessionVariables.Instance.CurrentFacility.FacilityID, cn).Select(bsm => new BillingStageDataModel(new Pm.Schema.BillingStageRecord(null,bsm.ClaimAmount ?? 0, 0, bsm.DOS ?? DateTime.Now, bsm.Claimdate ?? DateTime.Now, bsm.Daysfilled ?? 0, null, 0,bsm.PatientName, 0, bsm.Claimstatus, null, bsm.Appointmentid ?? 0,null,null)));
let loadPrepGrid(facilityId:int) Connector cn) =
Pm.Dal.BillingStages.loadPrepClaimGrid(facilityId, cn).Select(r => new BillingStageDataModel(r));