Skip to content

Commit 196a4a9

Browse files
committed
cleaned up ktUtils, passing tests
1 parent 142fa2b commit 196a4a9

File tree

4 files changed

+130
-68
lines changed

4 files changed

+130
-68
lines changed

src/tools/kotlin-generation-utils.ts

+66-24
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,84 @@
1-
export interface KotlinConstants {
1+
/**
2+
* @license
3+
* Copyright (c) 2020 Google Inc. All rights reserved.
4+
* This code may only be used under the BSD style license found at
5+
* http://polymer.github.io/LICENSE.txt
6+
* Code distributed by Google as part of this project is also
7+
* subject to an additional IP rights grant found at
8+
* http://polymer.github.io/PATENTS.txt
9+
*/
10+
11+
/**
12+
* Kotlin language formatting preferences.
13+
*/
14+
export interface KotlinPreferences {
215
indent: number;
316
lineLength: number;
417
}
518

6-
export const KT_BASE: KotlinConstants = {indent: 4, lineLength: 120};
19+
/**
20+
* Default language formatting settings.
21+
*/
22+
export const KT_DEFAULT: KotlinPreferences = {indent: 4, lineLength: 120};
723

8-
function collectionTemplate(items: string[], indent: number = KT_BASE.indent, collection: string = 'list') {
9-
const lowered = collection.toLowerCase();
10-
if (items.length == 0){
11-
return `empty${lowered[0].toUpperCase()}${lowered.substring(1)}()`;
24+
/**
25+
* Collection of utilities for generating Kotlin code.
26+
*/
27+
export class KotlinGenerationUtils {
28+
constructor(public pref: KotlinPreferences = KT_DEFAULT) {
1229
}
13-
return `${lowered}Of(${joinWithinLine(items, indent)})`;
14-
}
1530

16-
export function mapOf(items: string[], indent: number = KT_BASE.indent): string {
17-
return collectionTemplate(items, indent, 'map');
18-
}
31+
/**
32+
* Formats a function application in Kotlin.
33+
*
34+
* @param name name of the function
35+
* @param args list of arguments to the function
36+
* @param emptyName alternative name for the function with empty arguments.
37+
*/
38+
applyFun(name: string, args: string[], emptyName: string = name): string {
39+
if (args.length == 0) return `${emptyName}()`;
40+
return `${name}(${this.joinWithIndents(args)})`;
41+
}
1942

20-
export function listOf(items: string[], indent: number = KT_BASE.indent): string {
21-
return collectionTemplate(items, indent);
22-
}
43+
/** Formats `mapOf` with correct indentation and defaults. */
44+
mapOf(args: string[]): string {
45+
return this.applyFun('mapOf', args, 'emptyMap');
46+
}
47+
48+
/** Formats `mutableMapOf` with correct indentation and defaults. */
49+
mutableMapOf(args: string[]): string {
50+
return this.applyFun('mutableMapOf', args);
51+
}
2352

24-
export function setOf(items: string[], indent: number = KT_BASE.indent): string {
25-
return collectionTemplate(items, indent, 'set');
53+
/** Formats `listOf` with correct indentation and defaults. */
54+
listOf(args: string[]): string {
55+
return this.applyFun('listOf', args, 'emptyList');
56+
}
57+
58+
/** Formats `setOf` with correct indentation and defaults. */
59+
setOf(args: string[]): string {
60+
return this.applyFun('setOf', args, 'setList');
61+
}
62+
63+
/**
64+
* Joins a list of items, taking line length and indentation into account.
65+
*
66+
* @param items strings to join
67+
* @param lineStart (optional) add the starting indentation when calculating line limits.
68+
*/
69+
joinWithIndents(items: string[], lineStart: number = 0): string {
70+
const candidate = items.join(', ');
71+
if (lineStart + candidate.length <= this.pref.lineLength) return candidate;
72+
return '\n' + leftPad(leftPad(items.join(',\n'), this.pref.indent), lineStart) + '\n';
73+
}
2674
}
2775

76+
77+
/** Everyone's favorite NPM module, install not required. */
2878
export function leftPad(input: string, indent: number, skipFirst: boolean = false) {
2979
return input
3080
.split('\n')
3181
.map((line: string, idx: number) => (idx === 0 && skipFirst) ? line : ' '.repeat(indent) + line)
3282
.join('\n');
3383
}
3484

35-
export function joinWithinLine(items: string[],
36-
startIndent: number,
37-
indent: number = KT_BASE.indent,
38-
limit: number = KT_BASE.lineLength): string {
39-
const candidate = items.join(', ');
40-
if (startIndent + candidate.length <= limit) return candidate;
41-
return '\n' + leftPad(items.join(',\n' + indent), startIndent) + '\n';
42-
}

src/tools/schema2kotlin.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {Schema2Base, ClassGenerator, AddFieldOptions} from './schema2base.js';
1111
import {SchemaNode} from './schema2graph.js';
1212
import {ParticleSpec} from '../runtime/particle-spec.js';
1313
import minimist from 'minimist';
14-
import {leftPad, mapOf} from './kotlin-generation-utils.js';
14+
import {leftPad, KotlinGenerationUtils} from './kotlin-generation-utils.js';
1515

1616
// TODO: use the type lattice to generate interfaces
1717

@@ -35,6 +35,8 @@ const typeMap = {
3535
'B': {type: 'Boolean', decodeFn: 'decodeBool()', defaultVal: 'false', schemaType: 'FieldType.Boolean'},
3636
};
3737

38+
const ktUtils = new KotlinGenerationUtils();
39+
3840
export class Schema2Kotlin extends Schema2Base {
3941
// test-KOTLIN.file_Name.arcs -> TestKotlinFileName.kt
4042
outputName(baseName: string): string {
@@ -205,8 +207,8 @@ export class KotlinGenerator implements ClassGenerator {
205207
Schema(
206208
listOf(${schemaNames.join(',\n' + ' '.repeat(8))}),
207209
SchemaFields(
208-
singletons = ${leftPad(mapOf(this.singletonSchemaFields), 8, true)},
209-
collections = ${leftPad(mapOf(this.collectionSchemaFields), 8, true)}
210+
singletons = ${leftPad(ktUtils.mapOf(this.singletonSchemaFields), 8, true)},
211+
collections = ${leftPad(ktUtils.mapOf(this.collectionSchemaFields), 8, true)}
210212
),
211213
"${schemaHash}"
212214
)`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @license
3+
* Copyright (c) 2020 Google Inc. All rights reserved.
4+
* This code may only be used under the BSD style license found at
5+
* http://polymer.github.io/LICENSE.txt
6+
* Code distributed by Google as part of this project is also
7+
* subject to an additional IP rights grant found at
8+
* http://polymer.github.io/PATENTS.txt
9+
*/
10+
11+
import {assert} from '../../platform/chai-node.js';
12+
import {KotlinGenerationUtils} from '../kotlin-generation-utils.js';
13+
14+
describe('kotlin-generations-utils', () => {
15+
const ktUtils = new KotlinGenerationUtils();
16+
describe('mapOf', () => {
17+
it('when no items are present, it creates an empty map', () => {
18+
const actual = ktUtils.mapOf([]);
19+
assert.strictEqual('emptyMap()', actual);
20+
});
21+
it('when one item is present, it creates a single-line map', () => {
22+
const actual = ktUtils.mapOf([`"a" to "b"`]);
23+
assert.strictEqual('mapOf("a" to "b")', actual);
24+
});
25+
it('when few items are present, it creates a single-line map', () => {
26+
const actual = ktUtils.mapOf([`"a" to "b"`, `"b" to "c"`]);
27+
assert.strictEqual(`mapOf("a" to "b", "b" to "c")`, actual);
28+
});
29+
it('when many items are present, it creates a multi-line map', () => {
30+
const actual = ktUtils.mapOf([
31+
`"a" to "b"`,
32+
`"b" to "c"`,
33+
`"c" to "d"`,
34+
`"d" to "e"`,
35+
`"e" to "f"`,
36+
`"f" to "g"`,
37+
`"g" to "h"`,
38+
`"h" to "i"`,
39+
`"i" to "j"`,
40+
`"j" to "k"`,
41+
`"k" to "l"`,
42+
]);
43+
assert.strictEqual(`\
44+
mapOf(
45+
"a" to "b",
46+
"b" to "c",
47+
"c" to "d",
48+
"d" to "e",
49+
"e" to "f",
50+
"f" to "g",
51+
"g" to "h",
52+
"h" to "i",
53+
"i" to "j",
54+
"j" to "k",
55+
"k" to "l"
56+
)`, actual);
57+
});
58+
});
59+
});

src/tools/tests/schema2kotlin-test.ts

-41
This file was deleted.

0 commit comments

Comments
 (0)