|
| 1 | +/*--------------------------------------------------------------------------------------------- |
| 2 | + * Copyright (c) Microsoft Corporation. All rights reserved. |
| 3 | + * Licensed under the MIT License. See License.txt in the project root for license information. |
| 4 | + *--------------------------------------------------------------------------------------------*/ |
| 5 | + |
| 6 | +import * as assert from 'assert'; |
| 7 | +import { DisposableStore } from 'vs/base/common/lifecycle'; |
| 8 | +import { MultilineTokens2, SparseEncodedTokens } from 'vs/editor/common/model/tokensStore'; |
| 9 | +import { MetadataConsts } from 'vs/editor/common/modes'; |
| 10 | +import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry'; |
| 11 | +import { SemanticTokensProviderStyling, toMultilineTokens2 } from 'vs/editor/common/services/semanticTokensProviderStyling'; |
| 12 | +import { createModelServices } from 'vs/editor/test/common/editorTestUtils'; |
| 13 | +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; |
| 14 | +import { IThemeService, ITokenStyle } from 'vs/platform/theme/common/themeService'; |
| 15 | + |
| 16 | +suite('ModelService', () => { |
| 17 | + let disposables: DisposableStore; |
| 18 | + let instantiationService: TestInstantiationService; |
| 19 | + |
| 20 | + setup(() => { |
| 21 | + [instantiationService, disposables] = createModelServices(); |
| 22 | + }); |
| 23 | + |
| 24 | + teardown(() => { |
| 25 | + disposables.dispose(); |
| 26 | + }); |
| 27 | + |
| 28 | + test('issue #134973: invalid semantic tokens should be handled better', () => { |
| 29 | + const languageId = 'java'; |
| 30 | + disposables.add(ModesRegistry.registerLanguage({ id: languageId })); |
| 31 | + const legend = { |
| 32 | + tokenTypes: ['st0', 'st1', 'st2', 'st3', 'st4', 'st5', 'st6', 'st7', 'st8', 'st9', 'st10'], |
| 33 | + tokenModifiers: [] |
| 34 | + }; |
| 35 | + instantiationService.stub(IThemeService, <Partial<IThemeService>>{ |
| 36 | + getColorTheme() { |
| 37 | + return { |
| 38 | + getTokenStyleMetadata: (tokenType, tokenModifiers, languageId): ITokenStyle => { |
| 39 | + return { |
| 40 | + foreground: parseInt(tokenType.substr(2), 10) |
| 41 | + }; |
| 42 | + } |
| 43 | + }; |
| 44 | + } |
| 45 | + }); |
| 46 | + const styling = instantiationService.createInstance(SemanticTokensProviderStyling, legend); |
| 47 | + const badTokens = { |
| 48 | + data: new Uint32Array([ |
| 49 | + 0, 13, 16, 1, 0, |
| 50 | + 1, 2, 6, 2, 0, |
| 51 | + 0, 7, 6, 3, 0, |
| 52 | + 0, 15, 8, 4, 0, |
| 53 | + 0, 17, 1, 5, 0, |
| 54 | + 0, 7, 5, 6, 0, |
| 55 | + 1, 12, 8, 7, 0, |
| 56 | + 0, 19, 5, 8, 0, |
| 57 | + 0, 7, 1, 9, 0, |
| 58 | + 0, 4294967294, 5, 10, 0 |
| 59 | + ]) |
| 60 | + }; |
| 61 | + const result = toMultilineTokens2(badTokens, styling, languageId); |
| 62 | + const expected = new MultilineTokens2(1, new SparseEncodedTokens(new Uint32Array([ |
| 63 | + 0, 13, 29, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (1 << MetadataConsts.FOREGROUND_OFFSET)), |
| 64 | + 1, 2, 8, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (2 << MetadataConsts.FOREGROUND_OFFSET)), |
| 65 | + 1, 9, 15, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (3 << MetadataConsts.FOREGROUND_OFFSET)), |
| 66 | + 1, 24, 32, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (4 << MetadataConsts.FOREGROUND_OFFSET)), |
| 67 | + 1, 41, 42, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (5 << MetadataConsts.FOREGROUND_OFFSET)), |
| 68 | + 1, 48, 53, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (6 << MetadataConsts.FOREGROUND_OFFSET)), |
| 69 | + 2, 12, 20, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (7 << MetadataConsts.FOREGROUND_OFFSET)), |
| 70 | + 2, 31, 36, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (8 << MetadataConsts.FOREGROUND_OFFSET)), |
| 71 | + 2, 36, 41, (MetadataConsts.SEMANTIC_USE_FOREGROUND | (9 << MetadataConsts.FOREGROUND_OFFSET)), |
| 72 | + ]))); |
| 73 | + assert.deepStrictEqual(result.toString(), expected.toString()); |
| 74 | + }); |
| 75 | +}); |
0 commit comments