Skip to content

Commit 84c971c

Browse files
authored
Dynamic and Function do not need semantic tokens in Type expressions (#1500)
2 parents ce167b8 + 13c8132 commit 84c971c

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,4 +575,22 @@ describe('BrsFileSemanticTokensProcessor', () => {
575575
[SemanticTokenTypes.variable, 2, 30, 2, 34]
576576
]);
577577
});
578+
579+
it('ignores dynamic and function in type expressions', () => {
580+
const file = program.setFile<BrsFile>('source/main.bs', `
581+
sub test(data as dynamic, func as function)
582+
func(data)
583+
end sub
584+
`);
585+
expectSemanticTokens(file, [
586+
// sub |test|(data as dynamic, func as function)
587+
[SemanticTokenTypes.function, 1, 16, 1, 20],
588+
// sub test(|data| as dynamic, func as function)
589+
[SemanticTokenTypes.parameter, 1, 21, 1, 25],
590+
// sub test(data as dynamic, |func| as function)
591+
[SemanticTokenTypes.parameter, 1, 38, 1, 42],
592+
// |func|(data)
593+
[SemanticTokenTypes.function, 2, 16, 2, 20]
594+
]);
595+
});
578596
});

src/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SemanticTokenModifiers } from 'vscode-languageserver-protocol';
22
import { SemanticTokenTypes } from 'vscode-languageserver-protocol';
3-
import { isCallableType, isClassType, isComponentType, isConstStatement, isDottedGetExpression, isEnumMemberType, isEnumType, isFunctionExpression, isFunctionStatement, isInterfaceType, isNamespaceType, isPrimitiveType, isVariableExpression } from '../../astUtils/reflection';
3+
import { isCallableType, isClassType, isComponentType, isConstStatement, isDottedGetExpression, isDynamicType, isEnumMemberType, isEnumType, isFunctionExpression, isFunctionStatement, isInterfaceType, isNamespaceType, isPrimitiveType, isVariableExpression } from '../../astUtils/reflection';
44
import type { BrsFile } from '../../files/BrsFile';
55
import type { ExtraSymbolData, OnGetSemanticTokensEvent, SemanticToken, TypeChainEntry } from '../../interfaces';
66
import type { Locatable, Token } from '../../lexer/Token';
@@ -103,19 +103,20 @@ export class BrsFileSemanticTokensProcessor {
103103
}
104104

105105
private getSemanticTokenInfo(node: AstNode, type: BscType, extraData: ExtraSymbolData): { type: SemanticTokenTypes; modifiers?: SemanticTokenModifiers[] } {
106+
const isInTypeExpression = util.isInTypeExpression(node);
107+
106108
if (isConstStatement(extraData?.definingNode)) {
107109
return { type: SemanticTokenTypes.variable, modifiers: [SemanticTokenModifiers.readonly, SemanticTokenModifiers.static] };
108110
// non-instances of classes should be colored like classes
109111
} else if (isClassType(type) && extraData.isInstance !== true) {
110112
return { type: SemanticTokenTypes.class };
111113
//function statements and expressions
112-
} else if (isCallableType(type)) {
114+
} else if (!isInTypeExpression && isCallableType(type)) {
113115
//if the typetime type is a class, then color this like a class
114116
const typetimeType = node.getType({ flags: SymbolTypeFlag.typetime });
115117
if (isClassType(typetimeType)) {
116118
return { type: SemanticTokenTypes.class };
117119
}
118-
119120
//if this is a function statement or expression, treat it as a function
120121
if (isFunctionExpression(node) || isFunctionStatement(node)) {
121122
return { type: SemanticTokenTypes.function };
@@ -126,7 +127,9 @@ export class BrsFileSemanticTokensProcessor {
126127
//if this is a dottedGet, and the LHS is a namespace, treat it as a function.
127128
(isDottedGetExpression(node) && isNamespaceType(node.obj.getType({ flags: SymbolTypeFlag.typetime })))
128129
) {
129-
return { type: SemanticTokenTypes.function };
130+
if (!isDynamicType(type)) {
131+
return { type: SemanticTokenTypes.function };
132+
}
130133

131134
//all others should be treated as methods
132135
} else {
@@ -145,10 +148,10 @@ export class BrsFileSemanticTokensProcessor {
145148
//this is separate from the checks above because we want to resolve alias lookups before turning this variable into a const
146149
} else if (isConstStatement(node)) {
147150
return { type: SemanticTokenTypes.variable, modifiers: [SemanticTokenModifiers.readonly, SemanticTokenModifiers.static] };
148-
} else if (util.isInTypeExpression(node) && isPrimitiveType(type)) {
151+
} else if (isInTypeExpression && isPrimitiveType(type)) {
149152
// primitive types in type expressions should be already properly colored. do not add a semantic token
150153
return undefined;
151-
} else if (isVariableExpression(node)) {
154+
} else if (!isInTypeExpression && isVariableExpression(node)) {
152155
if (/m/i.test(node.tokens?.name?.text)) {
153156
//don't color `m` variables
154157
} else {

0 commit comments

Comments
 (0)