Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into dynamic-range
  • Loading branch information
TwitchBronBron committed Feb 23, 2022
2 parents 51047e9 + b7d7167 commit 6f92680
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 106 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0



## [0.45.1](https://github.com/rokucommunity/brighterscript/compare/v0.45.0...v0.45.1) - 2022-02-16
### Changed
- upgrade to [roku-deploy@3.5.3](https://github.com/rokucommunity/roku-deploy/blob/master/CHANGELOG.md#353---2022-02-16) which fixed a missing typescript definition issue.



## [1.0.0-alpha.15](https://github.com/rokucommunity/brighterscript/compare/v1.0.0-alpha.14...v1.0.0-alpha.15) - 2022-02-14
### Added
- all changes from [v0.45.0](#0450---2022-02-11)
Expand Down
90 changes: 7 additions & 83 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
"@types/glob": "^7.1.1",
"@types/mocha": "^5.2.5",
"@types/node": "^11.9.0",
"@types/request": "^2.47.0",
"@types/sinon": "^9.0.4",
"@types/yargs": "^15.0.5",
"@typescript-eslint/eslint-plugin": "4.32.0",
Expand Down Expand Up @@ -129,7 +128,7 @@
"moment": "^2.23.0",
"p-settle": "^2.1.0",
"parse-ms": "^2.1.0",
"roku-deploy": "^3.5.0",
"roku-deploy": "^3.5.3",
"serialize-error": "^7.0.1",
"source-map": "^0.7.3",
"vscode-languageserver": "7.0.0",
Expand Down
113 changes: 112 additions & 1 deletion src/Scope.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import type { BrsFile } from './files/BrsFile';
import type { FunctionStatement, NamespaceStatement } from './parser/Statement';
import type { OnScopeValidateEvent } from './interfaces';
import type { FunctionType } from './types/FunctionType';
import { isFloatType } from './astUtils/reflection';
import { isFloatType, isUniversalFunctionType } from './astUtils/reflection';
import type { SymbolTable } from './SymbolTable';
import type { Scope } from './Scope';
import { UniversalFunctionType } from './types/UniversalFunctionType';

describe('Scope', () => {
let sinon = sinonImport.createSandbox();
Expand Down Expand Up @@ -1704,6 +1705,116 @@ describe('Scope', () => {
expect(properties).to.contain('foo');
});

it('allows `Function` param type to have zero or more parameters', () => {
program.setFile('source/main.brs', `
sub callFuncWithParam(func as Function, value)
func(value)
end sub
sub printValue(value)
print value
end sub
sub main()
callFuncWithParam(printValue, "hello world")
end sub
`);

program.validate();
expectZeroDiagnostics(program);
});

it('allows any functional param to match `as Function` ', () => {
program.setFile('source/main.brs', `
sub callFuncWithParam(func as Function)
print func
end sub
sub printValue(value)
print value
end sub
sub main()
callFuncWithParam(printValue)
end sub
`);

program.validate();
expectZeroDiagnostics(program);
});

it('validates a non-function being used where a function is expected as a parameter', () => {
program.setFile('source/main.brs', `
sub callFuncWithParam(func as Function)
func("helloWorld")
end sub
sub printValue(value)
print value
end sub
sub main()
myString = "hello"
callFuncWithParam(myString) ' error
end sub
`);

program.validate();
expectDiagnostics(program, [
DiagnosticMessages.argumentTypeMismatch('string', (new UniversalFunctionType()).toString()).message
]);
});

it('allows a function result to be used as a parameter ', () => {
program.setFile('source/main.brs', `
sub callFuncWithParam(func as Function)
print func
end sub
function getFunc() as Function
return printValue
end function
sub printValue(value)
print value
end sub
sub main()
callFuncWithParam(getFunc())
end sub
`);

program.validate();
expectZeroDiagnostics(program);
});

it('allows a universal function result to be used as an assignment ', () => {
program.setFile('source/main.brs', `
sub callFuncWithParam(func as Function)
print func
end sub
function getFunc() as Function
return printValue
end function
sub printValue(value)
print value
end sub
sub main()
someFunc = getFunc()
callFuncWithParam(someFunc)
end sub
`);

program.validate();
expectZeroDiagnostics(program);
const mainSymbolTable = (program.getScopeByName('source')?.getAllFiles()[0] as BrsFile)?.parser.references.functionStatementLookup.get('main')?.func.symbolTable;
expect(mainSymbolTable).not.to.be.undefined;
expect(isUniversalFunctionType(mainSymbolTable.getSymbolType('someFunc'))).to.be.true;
});

});
describe('buildNamespaceLookup', () => {
it('does not crash when class statement is missing `name` prop', () => {
Expand Down
7 changes: 5 additions & 2 deletions src/Scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { URI } from 'vscode-uri';
import { LogLevel } from './Logger';
import type { BrsFile, TokenSymbolLookup } from './files/BrsFile';
import type { DependencyGraph, DependencyChangedEvent } from './DependencyGraph';
import { isBrsFile, isClassMethodStatement, isClassStatement, isCustomType, isDynamicType, isEnumStatement, isFunctionStatement, isFunctionType, isInvalidType, isVariableExpression, isXmlFile } from './astUtils/reflection';
import { isBrsFile, isClassMethodStatement, isClassStatement, isCustomType, isDynamicType, isEnumStatement, isFunctionStatement, isFunctionType, isInvalidType, isUniversalFunctionType, isVariableExpression, isXmlFile } from './astUtils/reflection';
import { SymbolTable } from './SymbolTable';
import type { BscType, TypeContext } from './types/BscType';
import { getTypeFromContext } from './types/BscType';
Expand Down Expand Up @@ -792,7 +792,10 @@ export class Scope {
}
}
}
if (isFunctionType(funcType)) {

if (isUniversalFunctionType(funcType)) {
// This is a generic function, and it is callable
} else if (isFunctionType(funcType)) {
// Check for Argument count mismatch.
//get min/max parameter count for callable
let paramCount = util.getMinMaxParamCount(funcType.params);
Expand Down
2 changes: 1 addition & 1 deletion src/astUtils/creators.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Range } from 'vscode-languageserver';
import type { Identifier, Token } from '../lexer/Token';
import { SGAttribute, SGComponent, SGInterface, SGInterfaceField, SGInterfaceFunction, SGScript } from '../parser/SGTypes';
import { TokenKind } from '../lexer/TokenKind';
import type { Expression, NamespacedVariableNameExpression } from '../parser/Expression';
import { LiteralExpression, CallExpression, DottedGetExpression, VariableExpression, FunctionExpression } from '../parser/Expression';
import { SGAttribute, SGComponent, SGInterface, SGInterfaceField, SGInterfaceFunction, SGScript } from '../parser/SGTypes';
import { Block, ClassMethodStatement } from '../parser/Statement';

/**
Expand Down
6 changes: 5 additions & 1 deletion src/astUtils/reflection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type { UninitializedType } from '../types/UninitializedType';
import type { ArrayType } from '../types/ArrayType';
import type { LazyType } from '../types/LazyType';
import type { SGInterfaceField, SGInterfaceFunction, SGNode } from '../parser/SGTypes';
import type { UniversalFunctionType } from '../types/UniversalFunctionType';

// File reflection

Expand Down Expand Up @@ -244,7 +245,10 @@ export function isStringType(value: any): value is StringType {
return value?.constructor.name === 'StringType';
}
export function isFunctionType(e: any): e is FunctionType {
return e?.constructor.name === 'FunctionType';
return e?.constructor.name === 'FunctionType' || e?.constructor.name === 'UniversalFunctionType';
}
export function isUniversalFunctionType(e: any): e is UniversalFunctionType {
return e?.constructor.name === 'UniversalFunctionType';
}
export function isBooleanType(e: any): e is BooleanType {
return e?.constructor.name === 'BooleanType';
Expand Down
14 changes: 8 additions & 6 deletions src/parser/Statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,9 +836,10 @@ export class ForStatement extends Statement {
state.lineage.unshift(this);
result.push(...this.body.transpile(state));
state.lineage.shift();
if (this.body.statements.length > 0) {
result.push('\n');
}

// add new line before "end for"
result.push('\n');

//end for
result.push(
state.indent(),
Expand Down Expand Up @@ -907,9 +908,10 @@ export class ForEachStatement extends Statement {
state.lineage.unshift(this);
result.push(...this.body.transpile(state));
state.lineage.shift();
if (this.body.statements.length > 0) {
result.push('\n');
}

// add new line before "end for"
result.push('\n');

//end for
result.push(
state.indent(),
Expand Down
Loading

0 comments on commit 6f92680

Please sign in to comment.