@@ -1038,6 +1038,14 @@ export class Parser {
10381038 range : name . range
10391039 } ) ;
10401040 }
1041+ if ( this . check ( TokenKind . As ) ) {
1042+ // v1 syntax allows type declaration on lhs of assignment
1043+ this . warnIfNotBrighterScriptMode ( 'typed assignment' ) ;
1044+
1045+ this . advance ( ) ; // skip 'as'
1046+ this . typeToken ( ) ; // skip typeToken;
1047+ }
1048+
10411049 let operator = this . consume (
10421050 DiagnosticMessages . expectedOperatorAfterIdentifier ( AssignmentOperators , name . text ) ,
10431051 ...AssignmentOperators
@@ -1170,10 +1178,33 @@ export class Parser {
11701178 // `let`, (...) keyword. As such, we must check the token *after* an identifier to figure
11711179 // out what to do with it.
11721180 if (
1173- this . checkAny ( TokenKind . Identifier , ...this . allowedLocalIdentifiers ) &&
1174- this . checkAnyNext ( ...AssignmentOperators )
1181+ this . checkAny ( TokenKind . Identifier , ...this . allowedLocalIdentifiers )
11751182 ) {
1176- return this . assignment ( ) ;
1183+ if ( this . checkAnyNext ( ...AssignmentOperators ) ) {
1184+ return this . assignment ( ) ;
1185+ } else if ( this . checkNext ( TokenKind . As ) ) {
1186+ // may be a typed assignment - this is v1 syntax
1187+ const backtrack = this . current ;
1188+ let validTypeExpression = false ;
1189+ try {
1190+ // skip the identifier, and check for valid type expression
1191+ this . advance ( ) ;
1192+ // skip the 'as'
1193+ this . advance ( ) ;
1194+ // check if there is a valid type
1195+ const typeToken = this . typeToken ( true ) ;
1196+ const allowedNameKinds = [ TokenKind . Identifier , ...DeclarableTypes , ...this . allowedLocalIdentifiers ] ;
1197+ validTypeExpression = allowedNameKinds . includes ( typeToken . kind ) ;
1198+ } catch ( e ) {
1199+ // ignore any errors
1200+ } finally {
1201+ this . current = backtrack ;
1202+ }
1203+ if ( validTypeExpression ) {
1204+ // there is a valid 'as' and type expression
1205+ return this . assignment ( ) ;
1206+ }
1207+ }
11771208 }
11781209
11791210 //some BrighterScript keywords are allowed as a local identifiers, so we need to check for them AFTER the assignment check
@@ -1388,13 +1419,21 @@ export class Parser {
13881419 /**
13891420 * Get an expression with identifiers separated by periods. Useful for namespaces and class extends
13901421 */
1391- private getNamespacedVariableNameExpression ( ) {
1392- let firstIdentifier = this . consume (
1393- DiagnosticMessages . expectedIdentifierAfterKeyword ( this . previous ( ) . text ) ,
1394- TokenKind . Identifier ,
1395- ...this . allowedLocalIdentifiers
1396- ) as Identifier ;
1397-
1422+ private getNamespacedVariableNameExpression ( ignoreDiagnostics = false ) {
1423+ let firstIdentifier : Identifier ;
1424+ if ( ignoreDiagnostics ) {
1425+ if ( this . checkAny ( ...this . allowedLocalIdentifiers ) ) {
1426+ firstIdentifier = this . advance ( ) as Identifier ;
1427+ } else {
1428+ throw new Error ( ) ;
1429+ }
1430+ } else {
1431+ firstIdentifier = this . consume (
1432+ DiagnosticMessages . expectedIdentifierAfterKeyword ( this . previous ( ) . text ) ,
1433+ TokenKind . Identifier ,
1434+ ...this . allowedLocalIdentifiers
1435+ ) as Identifier ;
1436+ }
13981437 let expr : DottedGetExpression | VariableExpression ;
13991438
14001439 if ( firstIdentifier ) {
@@ -2618,7 +2657,7 @@ export class Parser {
26182657 * Will return a token of whatever is next to be parsed
26192658 * Will allow v1 type syntax (typed arrays, union types), but there is no validation on types used this way
26202659 */
2621- private typeToken ( ) : Token {
2660+ private typeToken ( ignoreDiagnostics = false ) : Token {
26222661 let typeToken : Token ;
26232662 let lookForUnions = true ;
26242663 let isAUnion = false ;
@@ -2632,7 +2671,7 @@ export class Parser {
26322671 } else if ( this . options . mode === ParseMode . BrighterScript ) {
26332672 try {
26342673 // see if we can get a namespaced identifer
2635- const qualifiedType = this . getNamespacedVariableNameExpression ( ) ;
2674+ const qualifiedType = this . getNamespacedVariableNameExpression ( ignoreDiagnostics ) ;
26362675 typeToken = createToken ( TokenKind . Identifier , qualifiedType . getName ( this . options . mode ) , qualifiedType . range ) ;
26372676 } catch {
26382677 //could not get an identifier - just get whatever's next
0 commit comments