Skip to content

Commit 573b762

Browse files
authored
Fixed use of length operator on array unions and intersections. (#400)
* Fixed use of length operator on array unions and intersections. Also, removed restriction on assigning properties to arrays. * Added test for arrays with properties
1 parent 13a959b commit 573b762

File tree

3 files changed

+46
-30
lines changed

3 files changed

+46
-30
lines changed

src/LuaTransformer.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2990,23 +2990,16 @@ export class LuaTransformer {
29902990

29912991
// Check for primitive types to override
29922992
const type = this.checker.getTypeAtLocation(node.expression);
2993-
switch (type.flags) {
2994-
case ts.TypeFlags.String:
2995-
case ts.TypeFlags.StringLiteral:
2996-
return this.transformStringProperty(node);
2997-
case ts.TypeFlags.Object:
2998-
if (tsHelper.isExplicitArrayType(type, this.checker))
2999-
{
3000-
return this.transformArrayProperty(node);
3001-
}
3002-
else if (tsHelper.isArrayType(type, this.checker)
3003-
&& tsHelper.isDefaultArrayPropertyName(node.name.escapedText as string))
3004-
{
3005-
return this.transformArrayProperty(node);
3006-
}
3007-
}
2993+
if (tsHelper.isStringType(type)) {
2994+
return this.transformStringProperty(node);
30082995

3009-
if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) {
2996+
} else if (tsHelper.isArrayType(type, this.checker)) {
2997+
const arrayPropertyAccess = this.transformArrayProperty(node);
2998+
if (arrayPropertyAccess) {
2999+
return arrayPropertyAccess;
3000+
}
3001+
3002+
} else if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) {
30103003
return this.transformConstEnumValue(type, property, node);
30113004
}
30123005

@@ -3088,13 +3081,13 @@ export class LuaTransformer {
30883081
}
30893082

30903083
// Transpile access of array properties, only supported properties are allowed
3091-
public transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression {
3084+
public transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined {
30923085
switch (node.name.escapedText) {
30933086
case "length":
30943087
return tstl.createUnaryExpression(
30953088
this.transformExpression(node.expression), tstl.SyntaxKind.LengthOperator, node);
30963089
default:
3097-
throw TSTLErrors.UnsupportedProperty("array", node.name.escapedText as string, node);
3090+
return undefined;
30983091
}
30993092
}
31003093

test/unit/array.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ export class ArrayTests {
2121
Expect(result).toBe(5);
2222
}
2323

24+
@Test("Array union length")
25+
public arrayUnionLength(): void {
26+
const result = util.transpileAndExecute(
27+
`function makeArray(): number[] | string[] { return [3,5,1]; }
28+
const arr = makeArray();
29+
return arr.length;`
30+
);
31+
Expect(result).toBe(3);
32+
}
33+
2434
@Test("Array intersection access")
2535
public arrayIntersectionAccess(): void {
2636
const result = util.transpileAndExecute(
@@ -36,6 +46,21 @@ export class ArrayTests {
3646
Expect(result).toBe(5);
3747
}
3848

49+
@Test("Array intersection length")
50+
public arrayIntersectionLength(): void {
51+
const result = util.transpileAndExecute(
52+
`type I = number[] & {foo: string};
53+
function makeArray(): I {
54+
let t = [3,5,1];
55+
(t as I).foo = "bar";
56+
return (t as I);
57+
}
58+
const arr = makeArray();
59+
return arr.length;`
60+
);
61+
Expect(result).toBe(3);
62+
}
63+
3964
@TestCase("firstElement()", 3)
4065
@TestCase("name", "array")
4166
@TestCase("length", 1)
@@ -93,4 +118,14 @@ export class ArrayTests {
93118

94119
Expect(result).toBe("true:1,2,3,4");
95120
}
121+
122+
@Test("Array property access")
123+
public arrayPropertyAccess(): void {
124+
const code =
125+
`type A = number[] & {foo?: string};
126+
const a: A = [1,2,3];
127+
a.foo = "bar";
128+
return \`\${a.foo}\${a[0]}\${a[1]}\${a[2]}\`;`;
129+
Expect(util.transpileAndExecute(code)).toBe("bar123");
130+
}
96131
}

test/unit/expressions.spec.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -509,18 +509,6 @@ export class ExpressionTests {
509509
.toThrowError(TranspileError, "Unsupported property on array: unknownFunction");
510510
}
511511

512-
@Test("Unsupported array property error")
513-
public unsupportedArrayPropertyError(): void {
514-
const transformer = util.makeTestTransformer();
515-
516-
const mockNode: any = {
517-
name: ts.createIdentifier("unknownProperty"),
518-
};
519-
520-
Expect(() => transformer.transformArrayProperty(mockNode as ts.PropertyAccessExpression))
521-
.toThrowError(TranspileError, "Unsupported property on array: unknownProperty");
522-
}
523-
524512
@Test("Unsupported math property error")
525513
public unsupportedMathPropertyError(): void {
526514
const transformer = util.makeTestTransformer();

0 commit comments

Comments
 (0)