Skip to content

Commit

Permalink
Object type wider support (#850)
Browse files Browse the repository at this point in the history
* Allow `as object` types to be used almost everywhere like dynamic

* Fix tsc warning
  • Loading branch information
TwitchBronBron authored Jul 18, 2023
1 parent 091221b commit b4ff08e
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 23 deletions.
100 changes: 100 additions & 0 deletions src/bscPlugin/validation/ScopeValidator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,106 @@ describe('ScopeValidator', () => {
});

describe('argumentTypeMismatch', () => {
it('param `as object` supports all known types', () => {
program.setFile('source/file.bs', `
sub main()
consoleLog(Direction.up)
consoleLog(true)
consoleLog(main)
consoleLog(1.2)
consoleLog({} as Video)
consoleLog("test")
end sub
sub consoleLog(thing as object)
print thing
end sub
interface Video
url as string
end interface
enum Direction
up = "up"
down = "down"
end enum
`);
program.validate();
expectZeroDiagnostics(program);
});

it('`as object` var can be passed to various param types', () => {
program.setFile('source/file.bs', `
sub main()
obj = {} as object
printBoolean(obj)
printClass(obj)
printDouble(obj)
printEnum(obj)
printFloat(obj)
printFunction(obj)
printInteger(obj)
printInterface(obj)
printLongInteger(obj)
printString(obj)
end sub
sub printBoolean(value as boolean)
print value
end sub
class Person
name as string
end class
sub printClass(value as Person)
print value
end sub
sub printDouble(value as double)
print value
end sub
enum Direction
up = "up"
end enum
sub printEnum(value as Direction)
print value
end sub
sub printFloat(value as float)
print value
end sub
sub printFunction(value as function)
print value
end sub
interface Video
url as string
end interface
sub printInterface(value as Video)
print value
end sub
sub printInteger(value as integer)
print value
end sub
sub printLongInteger(value as LongInteger)
print value
end sub
sub printString(value as string)
print value
end sub
`);
program.validate();
expectZeroDiagnostics(program);
});


it('treats string enums as strings when assigned to string vars', () => {
program.setFile('source/file.bs', `
Expand Down
5 changes: 3 additions & 2 deletions src/types/BooleanType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isBooleanType, isDynamicType } from '../astUtils/reflection';
import { isBooleanType, isDynamicType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -16,7 +16,8 @@ export class BooleanType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isBooleanType(targetType) ||
isDynamicType(targetType)
isDynamicType(targetType) ||
isObjectType(targetType)
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/types/ClassType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isClassType, isDynamicType } from '../astUtils/reflection';
import { isClassType, isDynamicType, isObjectType } from '../astUtils/reflection';
import type { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';
import { InheritableType } from './InheritableType';
Expand All @@ -14,7 +14,7 @@ export class ClassType extends InheritableType {
public isTypeCompatible(targetType: BscType) {
if (this.isEqual(targetType)) {
return true;
} else if (isDynamicType(targetType)) {
} else if (isDynamicType(targetType) || isObjectType(targetType)) {
return true;
} else if (isClassType(targetType)) {
return this.isTypeDescendent(targetType);
Expand Down
3 changes: 2 additions & 1 deletion src/types/DoubleType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType } from '../astUtils/reflection';
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -17,6 +17,7 @@ export class DoubleType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isDynamicType(targetType) ||
isObjectType(targetType) ||
isIntegerType(targetType) ||
isFloatType(targetType) ||
isDoubleType(targetType) ||
Expand Down
3 changes: 2 additions & 1 deletion src/types/EnumType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDynamicType, isEnumMemberType, isEnumType } from '../astUtils/reflection';
import { isDynamicType, isEnumMemberType, isEnumType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';
import { DynamicType } from './DynamicType';
Expand All @@ -19,6 +19,7 @@ export class EnumType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isDynamicType(targetType) ||
isObjectType(targetType) ||
this.isEqual(targetType) ||
(isEnumMemberType(targetType) && targetType?.enumName.toLowerCase() === this.name.toLowerCase())
);
Expand Down
3 changes: 2 additions & 1 deletion src/types/FloatType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType } from '../astUtils/reflection';
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -16,6 +16,7 @@ export class FloatType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isDynamicType(targetType) ||
isObjectType(targetType) ||
isIntegerType(targetType) ||
isFloatType(targetType) ||
isDoubleType(targetType) ||
Expand Down
8 changes: 5 additions & 3 deletions src/types/FunctionType.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { isFunctionType } from '../astUtils/reflection';
import { isDynamicType, isFunctionType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';
import { DynamicType } from './DynamicType';

export class FunctionType extends BscType {
constructor(
Expand Down Expand Up @@ -39,7 +38,10 @@ export class FunctionType extends BscType {
}

public isTypeCompatible(targetType: BscType) {
if (targetType instanceof DynamicType) {
if (
isDynamicType(targetType) ||
isObjectType(targetType)
) {
return true;
}
return this.isEqual(targetType);
Expand Down
3 changes: 2 additions & 1 deletion src/types/IntegerType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType } from '../astUtils/reflection';
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -16,6 +16,7 @@ export class IntegerType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isDynamicType(targetType) ||
isObjectType(targetType) ||
isIntegerType(targetType) ||
isFloatType(targetType) ||
isDoubleType(targetType) ||
Expand Down
8 changes: 4 additions & 4 deletions src/types/InterfaceType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SymbolTypeFlag } from '../SymbolTable';
import { isDynamicType, isInterfaceType, isUnionType, isInheritableType } from '../astUtils/reflection';
import { isDynamicType, isInterfaceType, isUnionType, isInheritableType, isObjectType } from '../astUtils/reflection';
import type { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';
import { InheritableType } from './InheritableType';
Expand All @@ -15,11 +15,11 @@ export class InterfaceType extends InheritableType {
public readonly kind = BscTypeKind.InterfaceType;

public isTypeCompatible(targetType: BscType) {
//TODO: We need to make sure that things don't get assigned to built-in types
if (this.isEqual(targetType)) {
if (isDynamicType(targetType) || isObjectType(targetType)) {
return true;
}
if (isDynamicType(targetType)) {
//TODO: We need to make sure that things don't get assigned to built-in types
if (this.isEqual(targetType)) {
return true;
}
const ancestorTypes = this.getAncestorTypeList();
Expand Down
5 changes: 3 additions & 2 deletions src/types/InvalidType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDynamicType, isInvalidType } from '../astUtils/reflection';
import { isDynamicType, isInvalidType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -16,7 +16,8 @@ export class InvalidType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isInvalidType(targetType) ||
isDynamicType(targetType)
isDynamicType(targetType) ||
isObjectType(targetType)
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/types/LongIntegerType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType } from '../astUtils/reflection';
import { isDoubleType, isDynamicType, isFloatType, isIntegerType, isLongIntegerType, isObjectType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -16,6 +16,7 @@ export class LongIntegerType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isDynamicType(targetType) ||
isObjectType(targetType) ||
isIntegerType(targetType) ||
isFloatType(targetType) ||
isDoubleType(targetType) ||
Expand Down
3 changes: 2 additions & 1 deletion src/types/StringType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDynamicType, isEnumMemberType, isEnumType, isStringType } from '../astUtils/reflection';
import { isDynamicType, isEnumMemberType, isEnumType, isObjectType, isStringType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -20,6 +20,7 @@ export class StringType extends BscType {
return (
isStringType(targetType) ||
isDynamicType(targetType) ||
isObjectType(targetType) ||
//string enums are compatible with strings
(
(isEnumType(targetType) || isEnumMemberType(targetType)) && isStringType(targetType.underlyingType)
Expand Down
4 changes: 2 additions & 2 deletions src/types/UnionType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GetTypeOptions } from '../interfaces';
import { isDynamicType, isUnionType } from '../astUtils/reflection';
import { isDynamicType, isObjectType, isUnionType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { ReferenceType } from './ReferenceType';
import { findTypeUnion, getUniqueType } from './helpers';
Expand Down Expand Up @@ -55,7 +55,7 @@ export class UnionType extends BscType {
}

isTypeCompatible(targetType: BscType): boolean {
if (isDynamicType(targetType)) {
if (isDynamicType(targetType) || isObjectType(targetType)) {
return true;
}
if (isUnionType(targetType)) {
Expand Down
5 changes: 3 additions & 2 deletions src/types/VoidType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDynamicType, isVoidType } from '../astUtils/reflection';
import { isDynamicType, isObjectType, isVoidType } from '../astUtils/reflection';
import { BscType } from './BscType';
import { BscTypeKind } from './BscTypeKind';

Expand All @@ -16,7 +16,8 @@ export class VoidType extends BscType {
public isTypeCompatible(targetType: BscType) {
return (
isVoidType(targetType) ||
isDynamicType(targetType)
isDynamicType(targetType) ||
isObjectType(targetType)
);
}

Expand Down

0 comments on commit b4ff08e

Please sign in to comment.