Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object type wider support #850

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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