Make Form._lines public and remove the accessor.
authorRobert Sesek <rsesek@bluestatic.org>
Mon, 23 Mar 2020 04:24:02 +0000 (00:24 -0400)
committerRobert Sesek <rsesek@bluestatic.org>
Mon, 23 Mar 2020 04:24:02 +0000 (00:24 -0400)
21 files changed:
src/core/Form.test.ts
src/core/Form.ts
src/core/Line.test.ts
src/core/TaxReturn.test.ts
src/core/Trace.test.ts
src/fed2019/Form1040.ts
src/fed2019/Form1099B.ts
src/fed2019/Form1099DIV.ts
src/fed2019/Form1099INT.ts
src/fed2019/Form1099R.ts
src/fed2019/Form1116.ts
src/fed2019/Form8606.ts
src/fed2019/Form8949.ts
src/fed2019/Form8959.ts
src/fed2019/Form8960.ts
src/fed2019/Form8995.ts
src/fed2019/Schedule1.ts
src/fed2019/Schedule2.ts
src/fed2019/Schedule3.ts
src/fed2019/ScheduleD.ts
src/fed2019/W2.ts

index 41677fdde74e6edc1319bb25bf87c93a725f1ea4..8098759d92cc423dbb05373410fbe00742d41fd2 100644 (file)
@@ -16,10 +16,10 @@ class TestTaxReturn extends TaxReturn {
 test('add and get line', () => {
   const l = new ComputedLine<number>(() => 42);
 
-  class TestForm extends Form<TestForm['_lines']> {
+  class TestForm extends Form<TestForm['lines']> {
     readonly name = 'Test Form';
 
-    protected readonly _lines = { '1': l };
+    readonly lines = { '1': l };
   };
 
   const f = new TestForm();
@@ -27,9 +27,9 @@ test('add and get line', () => {
 });
 
 test('get non-existent line', () => {
-  class TestForm extends Form<TestForm['_lines']> {
+  class TestForm extends Form<TestForm['lines']> {
     readonly name = 'Test';
-    protected readonly _lines = {};
+    readonly lines = {};
   };
 
   const f = new TestForm();
@@ -48,7 +48,7 @@ test('input', () => {
   class TestForm extends Form<any, TestInput> {
     readonly name = '1040';
 
-    protected readonly _lines = null;
+    readonly lines = null;
   };
 
   const f = new TestForm({ filingStatus: 'S', money: 100.0 });
@@ -56,10 +56,10 @@ test('input', () => {
 });
 
 test('get value', () => {
-  class TestForm extends Form<TestForm['_lines']> {
+  class TestForm extends Form<TestForm['lines']> {
     readonly name = 'Form';
 
-    protected readonly _lines = {
+    readonly lines = {
       line: new ComputedLine<number>(() => 42),
     };
   };
@@ -80,11 +80,11 @@ test('get value', () => {
 test('form types', () => {
   class FormA extends Form<any> {
     readonly name = 'A';
-    protected readonly _lines = {};
+    readonly lines = {};
   };
   class FormB extends Form<any> {
     readonly name = 'B';
-    protected readonly _lines = {};
+    readonly lines = {};
   };
 
   expect(isFormT(new FormA(), FormA)).toBe(true);
index b8c16e8401d0433c389c7461f039205c23e62d7e..c713f170ed3ececc344cf7c6eb0f21e59e9e9447 100644 (file)
@@ -13,23 +13,19 @@ export default abstract class Form<L extends { [key: string]: Line<any> },
                                    I = unknown> {
   abstract readonly name: string;
 
-  protected abstract readonly _lines: L;
+  abstract readonly lines: L;
 
   readonly supportsMultipleCopies: boolean = false;
 
   private readonly _input?: I;
 
-  // Avoid using this; prefer the getLine() helpers declared below. This
-  // is only exposed for propagating line type information.
-  get lines(): L { return this._lines; }
-
   constructor(input?: I) {
     this._input = input;
   }
 
   init() {
-    for (const id in this._lines) {
-      let l = this._lines[id];
+    for (const id in this.lines) {
+      let l = this.lines[id];
       l._id = id;
       l.form = this;
     }
@@ -40,9 +36,9 @@ export default abstract class Form<L extends { [key: string]: Line<any> },
   }
 
   getLine<K extends keyof L>(id: K): L[K] {
-    if (!(id in this._lines))
+    if (!(id in this.lines))
       throw new NotFoundError(`Form ${this.name} does not have line ${id}`);
-    return this._lines[id];
+    return this.lines[id];
   }
 
   getValue<K extends keyof L>(tr: TaxReturn, id: K): ReturnType<L[K]['value']> {
index 98b4171f720fe0d16171913472bcba038c4cdd78..27ec6a313f71f47dfa259f789607fe7498c5ff74 100644 (file)
@@ -39,9 +39,9 @@ test('computed line', () => {
 });
 
 test('reference line', () => {
-  class TestForm extends Form<TestForm['_lines']> {
+  class TestForm extends Form<TestForm['lines']> {
     readonly name = 'Form 1';
-    protected readonly _lines = {
+    readonly lines = {
       '6b': new ConstantLine(12.34),
       's': new ConstantLine('abc'),
     };
@@ -65,15 +65,15 @@ test('reference line', () => {
 });
 
 test('self reference line', () => {
-  class OtherForm extends Form<OtherForm['_lines']> {
+  class OtherForm extends Form<OtherForm['lines']> {
     readonly name = 'Form A';
-    protected readonly _lines = {
+    readonly lines = {
       '6c': new ConstantLine(55)
     };
   };
-  class TestForm extends Form<TestForm['_lines']> {
+  class TestForm extends Form<TestForm['lines']> {
     readonly name = 'Form 1';
-    protected readonly _lines = {
+    readonly lines = {
       'a': new ConstantLine(100.2),
       'b': new ReferenceLine(OtherForm, '6c'),
       'c': new ReferenceLine((TestForm as unknown) as FormClass<Form<any>>, 'b'),
@@ -97,9 +97,9 @@ test('input line', () => {
     key: string;
     key2?: string;
   }
-  class TestForm extends Form<TestForm['_lines'], Input> {
+  class TestForm extends Form<TestForm['lines'], Input> {
     readonly name = 'F1';
-    protected readonly _lines = {
+    readonly lines = {
       '1': new InputLine<Input>('key'),
       '2': new InputLine<Input>('key2'),
       '3': new InputLine<Input>('key2', undefined, 'FALLBACK')
@@ -119,16 +119,16 @@ test('input line', () => {
 });
 
 test('line stack', () => {
-  class FormZ extends Form<FormZ['_lines'], {'input': number}> {
+  class FormZ extends Form<FormZ['lines'], {'input': number}> {
     readonly name = 'Z';
-    protected readonly _lines = {
+    readonly lines = {
       '3': new InputLine<any, any>('input')
     }
   };
 
-  class FormZ2 extends Form<FormZ2['_lines']> {
+  class FormZ2 extends Form<FormZ2['lines']> {
     readonly name = 'Z-2';
-    protected readonly _lines = {
+    readonly lines = {
       '2c': new ComputedLine<number>((tr: TaxReturn): any => {
           return tr.getForm(FormZ).getLine('3').value(tr) * 0.2;
         })
@@ -144,10 +144,10 @@ test('line stack', () => {
 });
 
 test('accumulator line', () => {
-  class TestForm extends Form<TestForm['_lines']> {
+  class TestForm extends Form<TestForm['lines']> {
     readonly name = 'Form B';
     readonly supportsMultipleCopies = true;
-    protected readonly _lines = {
+    readonly lines = {
       g: new ConstantLine<number>(100.25)
     };
   };
index 497a8b4d3de1bbe26ba5598f47e1590e23eb409a..4da4fcb123260bd0b991d9ad4db93a253a2adc16 100644 (file)
@@ -61,7 +61,7 @@ test('get non-existent person', () => {
 test('single-copy forms', () => {
   class TestForm extends Form<null> {
     readonly name = 'Test Form';
-    protected readonly _lines = null;
+    readonly lines = null;
   };
 
   const tr = new TestTaxReturn();
@@ -76,7 +76,7 @@ test('multiple-copy forms', () => {
   class TestForm extends Form<null> {
     readonly name = 'Test Form';
     readonly supportsMultipleCopies = true;
-    protected readonly _lines = null;
+    readonly lines = null;
   };
 
   const tr = new TestTaxReturn();
@@ -99,7 +99,7 @@ test('multiple-copy forms', () => {
 test('get non-existent form', () => {
   class TestForm extends Form<null> {
     readonly name = 'Test Form';
-    protected readonly _lines = null;
+    readonly lines = null;
   }
   const tr = new TestTaxReturn();
   expect(() => tr.getForm(TestForm)).toThrow(NotFoundError);
@@ -107,14 +107,14 @@ test('get non-existent form', () => {
   expect(tr.findForms(TestForm)).toEqual([]);
 });
 
-class PerPersonForm extends Form<PerPersonForm['_lines']> {
+class PerPersonForm extends Form<PerPersonForm['lines']> {
   private _person?: Person;
 
   readonly name = 'Per Person';
 
   readonly supportsMultipleCopies = true;
 
-  protected readonly _lines = {};
+  readonly lines = {};
 
   constructor(person?: Person) {
     super(undefined);
index 3f49fdec4a9e551e6d0fbfb0a01e3367ac9327bf..1bdf55b3902aed4476bab29bd2046660a310be62 100644 (file)
@@ -19,10 +19,10 @@ interface Input {
   value: number;
 };
 
-class TestForm extends Form<TestForm['_lines'], Input> {
+class TestForm extends Form<TestForm['lines'], Input> {
   readonly name = 'TF';
 
-  readonly _lines = {
+  readonly lines = {
     'i1': new InputLine<Input>('name'),
     'i2': new InputLine<Input>('value'),
     'c1': new ComputedLine((tr): string => {
index ab6f59ee7911a142bb1431f3f6de4220c6ebe518..584a823de9926c028a7f771f1ca892320254d2ef 100644 (file)
@@ -30,10 +30,10 @@ export interface Form1040Input {
   filingStatus: FilingStatus;
 };
 
-export default class Form1040 extends Form<Form1040['_lines'], Form1040Input> {
+export default class Form1040 extends Form<Form1040['lines'], Form1040Input> {
   readonly name = '1040';
 
-  protected readonly _lines = {
+  readonly lines = {
     '1': new AccumulatorLine(W2, '1', 'Wages, salaries, tips, etc.'),
     '2a': new ComputedLine((tr): number => {
       const value = (new AccumulatorLine(Form1099INT, '8')).value(tr) +
@@ -247,10 +247,10 @@ export function computeTax(income: number, filingStatus: FilingStatus): number {
   return ((income - bracketStart) * bracket[1]) + bracket[2];
 };
 
-export class QDCGTaxWorksheet extends Form<QDCGTaxWorksheet['_lines']> {
+export class QDCGTaxWorksheet extends Form<QDCGTaxWorksheet['lines']> {
   readonly name = 'QDCG Tax Worksheet';
 
-  protected readonly _lines = {
+  readonly lines = {
     '1': new ReferenceLine(Form1040, '11b', 'Taxable income'),
     '2': new ReferenceLine(Form1040, '3a', 'Qualified dividends'),
     '3': new ComputedLine((tr): number => {
index 816cfef9d0c3d5432112dbeb10587efeeed71186..67a41a39152602100de6c343aca883ad8b9022ff 100644 (file)
@@ -36,14 +36,14 @@ export interface Form1099BInput {
 
 class Input<T extends keyof Form1099BInput> extends InputLine<Form1099BInput, T> {};
 
-export default class Form1099B extends Form<Form1099B['_lines'], Form1099BInput> {
+export default class Form1099B extends Form<Form1099B['lines'], Form1099BInput> {
   readonly name = '1099-B';
 
   readonly supportsMultipleCopies = true;
 
   person() { return this.getInput('payee'); }
 
-  protected readonly _lines = {
+  readonly lines = {
     'payer': new Input('payer'),
     'recipient': new Input('payee'),
     'shortTermBasisReported': new Input('shortTermBasisReported'),
index f9561a1dd47db2394852b20da62eade97e8e1fe3..dc004767f76a7a0958bfd5ad2c59907278b9cb7b 100644 (file)
@@ -29,14 +29,14 @@ export interface Form1099DIVInput {
 
 class Input<T extends keyof Form1099DIVInput> extends InputLine<Form1099DIVInput, T> {};
 
-export default class Form1099DIV extends Form<Form1099DIV['_lines'], Form1099DIVInput> {
+export default class Form1099DIV extends Form<Form1099DIV['lines'], Form1099DIVInput> {
   readonly name = '1099-DIV';
 
   readonly supportsMultipleCopies = true;
 
   person() { return this.getInput('payee'); }
 
-  protected readonly _lines = {
+  readonly lines = {
     'payer': new Input('payer'),
     'recipient': new Input('payee'),
     '1a': new Input('ordinaryDividends', undefined, 0),
index e3390318398088cc5869712a2cfdc80b52c826e0..adf4823825218ca107aaee6a2354a5e88be74b77 100644 (file)
@@ -26,14 +26,14 @@ export interface Form1099INTInput {
 
 class Input<T extends keyof Form1099INTInput> extends InputLine<Form1099INTInput, T> {};
 
-export default class Form1099INT extends Form<Form1099INT['_lines'], Form1099INTInput> {
+export default class Form1099INT extends Form<Form1099INT['lines'], Form1099INTInput> {
   readonly name = '1099-INT';
 
   readonly supportsMultipleCopies = true;
 
   person() { return this.getInput('payee'); }
 
-  protected readonly _lines = {
+  readonly lines = {
     'payer': new Input('payer'),
     'recipient': new Input('payee'),
     '1': new Input('interest'),
index c30bb5aadd490e8a163f20e14d24fddfa9a4136e..744741afc10c99190cf942aeaef45af41675b026 100644 (file)
@@ -54,14 +54,14 @@ export interface Form1099RInput {
 
 class Input<T extends keyof Form1099RInput> extends InputLine<Form1099RInput, T> {};
 
-export default class Form1099R extends Form<Form1099R['_lines'], Form1099RInput> {
+export default class Form1099R extends Form<Form1099R['lines'], Form1099RInput> {
   readonly name = '1099-R';
 
   readonly supportsMultipleCopies = true;
 
   person() { return this.getInput('payee'); }
 
-  protected readonly _lines = {
+  readonly lines = {
     'payer': new Input('payer'),
     'recipeint': new Input('payee'),
     '1': new Input('grossDistribution'),
index 0b9253f2151d6223187a5764b86784afcfd75787..bbec8fbe57557eccddf2093846fd54ed555b60a9 100644 (file)
@@ -34,10 +34,10 @@ export interface Form1116Input {
 
 class Input<T extends keyof Form1116Input> extends InputLine<Form1116Input, T> {};
 
-export default class Form1116 extends Form<Form1116['_lines'], Form1116Input> {
+export default class Form1116 extends Form<Form1116['lines'], Form1116Input> {
   readonly name = '1116';
 
-  protected readonly _lines = {
+  readonly lines = {
     'category': new ComputedLine((tr: TaxReturn): ForeignIncomeCategory => {
       const input = this.getInput('incomeCategory');
       if (input != ForeignIncomeCategory.C)
index 4ce135a00f73a71848edca9680406ec9a5846801..38c9fe90dde21bae80e2a56be375e027c10568ff 100644 (file)
@@ -20,14 +20,14 @@ export interface Form8606Input {
 
 class Input<T extends keyof Form8606Input> extends InputLine<Form8606Input, T> {};
 
-export default class Form8606 extends Form<Form8606['_lines'], Form8606Input> {
+export default class Form8606 extends Form<Form8606['lines'], Form8606Input> {
   readonly name = '8606';
 
   readonly supportsMultipleCopies = true;
 
   person() { return this.getInput('person'); }
 
-  protected readonly _lines = {
+  readonly lines = {
     'person': new Input('person'),
 
     // Part 1
index 814d4e73bb52974018954e9ca019a8dddcfb6c0d..51bd2912ed425874d67d35fb6ff0aac5f0b6c411 100644 (file)
@@ -76,12 +76,12 @@ class Form8949Line extends Line<Form8949Total> {
   }
 };
 
-export default class Form8949 extends Form<Form8949['_lines']> {
+export default class Form8949 extends Form<Form8949['lines']> {
   readonly name = '8949';
 
   readonly supportsMultipleCopies = true;
 
-  protected readonly _lines = {
+  readonly lines = {
     'boxA': new Form8949Line(Form8949Box.A),
     'boxB': new Form8949Line(Form8949Box.B),
     'boxC': new Form8949Line(Form8949Box.C),
index 83b439b9db4e6653bf0c8d14248f3db5a2ffa32b..844261f7f4c4364e3845052180cfa5d1061f7c71 100644 (file)
@@ -10,10 +10,10 @@ import { clampToZero } from '../core/Math';
 import Form1040, { FilingStatus } from './Form1040';
 import W2 from './W2';
 
-export default class Form8959 extends Form<Form8959['_lines']> {
+export default class Form8959 extends Form<Form8959['lines']> {
   readonly name = '8959';
 
-  protected readonly _lines = {
+  readonly lines = {
     '1': new AccumulatorLine(W2, '5', 'Medicare wages'),
     // 2 is not supported (Unreported tips from Form 4137)
     // 3 is not supported (Wages from Form 8919)
index 46f45a81b6e05b93a1f9717728f932fa8d39bdfb..a871e82c7b300a08bad7b70c9336f0056b2f080d 100644 (file)
@@ -10,10 +10,10 @@ import { clampToZero, undefinedToZero } from '../core/Math';
 import Form1040, { FilingStatus } from './Form1040';
 import Schedule1 from './Schedule1';
 
-export default class Form8960 extends Form<Form8960['_lines']> {
+export default class Form8960 extends Form<Form8960['lines']> {
   readonly name = '8960';
 
-  protected readonly _lines = {
+  readonly lines = {
     // Part 1
     // Section 6013 elections not supported.
     '1': new ReferenceLine(Form1040, '2b', 'Taxable interest'),
index ad948942c3908568a1420ea3a4a1a39f66ee77d2..677f9e265424b0dc2f928df8a68bd7c0f6df15d7 100644 (file)
@@ -18,11 +18,11 @@ export interface Form8995REITInput {
 // Dividends from REITs get preferential tax treatment, but the form used to
 // calculate that differs based off taxable income amounts. But the QBI
 // computation for RETIs is the same. This just models the REIT portion.
-export default class Form8995REIT extends Form<Form8995REIT['_lines']> {
+export default class Form8995REIT extends Form<Form8995REIT['lines']> {
   readonly name = '8995 REIT';
 
   // This uses line numbers from 8995-A.
-  protected readonly _lines = {
+  readonly lines = {
     // 1-26 not supported
     '27': new ComputedLine(() => 0, 'Total qualified business income component'), // Not supported.
     '28': new AccumulatorLine(Form1099DIV, '5', 'Qualified REIT dividends'),
index 7cea3e8a875c5b0333b9f46d4b4aa865f462ec37..ef6707c0dabf5108d93e0cd9edba9873f177611b 100644 (file)
@@ -58,10 +58,10 @@ class Input<T extends keyof Schedule1Input> extends InputLine<Schedule1Input, T>
   }
 };
 
-export default class Schedule1 extends Form<Schedule1['_lines'], Schedule1Input> {
+export default class Schedule1 extends Form<Schedule1['lines'], Schedule1Input> {
   readonly name = 'Schedule 1';
 
-  readonly _lines = {
+  readonly lines = {
     // Part 1
     '1': new ComputedLine((tr): number => {
       if (this.hasInput('stateAndLocalTaxableRefunds'))
@@ -150,10 +150,10 @@ export interface SALTWorksheetInput {
   prevYearFilingStatus?: FilingStatus;
 };
 
-export class SALTWorksheet extends Form<SALTWorksheet['_lines'], SALTWorksheetInput> {
+export class SALTWorksheet extends Form<SALTWorksheet['lines'], SALTWorksheetInput> {
   readonly name = 'SALT Refund Worksheet';
 
-  protected readonly _lines = {
+  readonly lines = {
     '1': new ComputedLine((tr): number => {
       const refunds = tr.findForm(Schedule1).getInput('stateAndLocalTaxableRefunds');
       const prevYear = this.getInput('prevYearSalt');
index 3ea8c8f73b4f69f9547b18f69c637f48ab7c42fb..eb9899c4ad2397a7cbc61003c3aeb2261c354b77 100644 (file)
@@ -13,10 +13,10 @@ import Form1099INT from './Form1099INT';
 import Form8959 from './Form8959';
 import Form8960 from './Form8960';
 
-export default class Schedule2 extends Form<Schedule2['_lines']> {
+export default class Schedule2 extends Form<Schedule2['lines']> {
   readonly name = 'Schedule 2';
 
-  protected readonly _lines = {
+  readonly lines = {
     '1': new ComputedLine((tr): number => {
       // TODO - this is just using Taxable Income, rather than AMT-limited
       // income
index d68356039ecb134582864092e85b85dd8d00eb4d..98da58ccb74c44d604a0e7a30d62186a2e41bd79 100644 (file)
@@ -17,10 +17,10 @@ export interface Schedule3Input {
   estimatedTaxPayments?: number;
 };
 
-export default class Schedule3 extends Form<Schedule3['_lines'], Schedule3Input> {
+export default class Schedule3 extends Form<Schedule3['lines'], Schedule3Input> {
   readonly name = 'Schedule 3';
 
-  readonly _lines = {
+  readonly lines = {
     // Part 1
     '1': new ComputedLine((tr): number => {
       const f1040 = tr.getForm(Form1040);
index 17fd11af73f11ac523d76ae0d1be4e7c5a8f9f16..08264c11a5e40fd941755eb1405e248d3462633e 100644 (file)
@@ -12,10 +12,10 @@ import Form8949, { Form8949Box } from './Form8949';
 import Form1099DIV from './Form1099DIV';
 import Form1040, { FilingStatus, QDCGTaxWorksheet, computeTax } from './Form1040';
 
-export default class ScheduleD extends Form<ScheduleD['_lines']> {
+export default class ScheduleD extends Form<ScheduleD['lines']> {
   readonly name = 'Schedule D';
 
-  protected readonly _lines = {
+  readonly lines = {
     // 1a not supported (Totals for all short-term transactions reported on Form 1099-B for which basis was reported to the IRS and for which you have no adjustments)
     // 4 is not supported (Short-term gain from Form 6252 and short-term gain or (loss) from Forms 4684, 6781, and 8824)
     // 5 is not supported (Net short-term gain or (loss) from partnerships, S corporations, estates, and trusts from Schedule(s) K-1)
@@ -89,10 +89,10 @@ export default class ScheduleD extends Form<ScheduleD['_lines']> {
   };
 };
 
-export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['_lines']> {
+export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['lines']> {
   readonly name = 'Schedule D Tax Worksheet';
 
-  protected readonly _lines = {
+  readonly lines = {
     '1': new ReferenceLine(Form1040, '11b'),
     '2': new ReferenceLine(Form1040, '3a'),
     // TODO 3 - form 4952
index 2bac4d41c150751f00c6ae8009caa55e5e3fe443..a0f7fffd50bca895aad31f455ea4861d681ff20c 100644 (file)
@@ -37,7 +37,7 @@ export interface W2Input {
 
 class Input<T extends keyof W2Input> extends InputLine<W2Input, T> {};
 
-export default class W2 extends Form<W2['_lines'], W2Input> {
+export default class W2 extends Form<W2['lines'], W2Input> {
   readonly name = 'W-2';
 
   readonly supportsMultipleCopies = true;
@@ -46,7 +46,7 @@ export default class W2 extends Form<W2['_lines'], W2Input> {
     return this.getInput('employee');
   }
 
-  protected readonly _lines = {
+  readonly lines = {
     'c': new Input('employer', 'Employer name'),
     'e': new Input('employee', 'Emplyee name'),
     '1': new Input('wages', 'Wages, tips, other compensation'),