Skip to content

Commit

Permalink
fix duplicated semantic token for decorators which caused them to not…
Browse files Browse the repository at this point in the history
… get highlighted as decorators in neovim
  • Loading branch information
DetachHead committed Dec 5, 2024
1 parent 482dfe0 commit 10ff115
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 30 deletions.
29 changes: 10 additions & 19 deletions packages/pyright-internal/src/analyzer/semanticTokensWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,13 @@ export class SemanticTokensWalker extends ParseTreeWalker {
}

override visitDecorator(node: DecoratorNode) {
let nameNode: NameNode | undefined;
this._addItem(node.start, 1 /* '@' symbol */, SemanticTokenTypes.decorator, []);
switch (node.d.expr.nodeType) {
case ParseNodeType.Call:
if (node.d.expr.d.leftExpr.nodeType === ParseNodeType.MemberAccess) {
nameNode = node.d.expr.d.leftExpr.d.member;
} else if (node.d.expr.d.leftExpr.nodeType === ParseNodeType.Name) {
nameNode = node.d.expr.d.leftExpr;
}
break;
case ParseNodeType.MemberAccess:
nameNode = node.d.expr.d.member;
break;
case ParseNodeType.Name:
nameNode = node.d.expr;
break;
}
if (nameNode) {
this._addItem(nameNode.start, nameNode.length, SemanticTokenTypes.decorator, []);
// only add the decorator token type if it's just a name (eg. `@property`). any more complicated
// decorator expressions (eg. `@foo.setter`, `@mark.parametrize("foo", (bar, baz))`) are left
// as-is and their individual symbols are highlighted with their normal token type.
// see discussion in https://github.com/DetachHead/basedpyright/issues/278#issuecomment-2517502311
if (node.d.expr.nodeType === ParseNodeType.Name) {
this._addItem(node.d.expr.start, node.d.expr.length, SemanticTokenTypes.decorator, []);
}
return super.visitDecorator(node);
}
Expand Down Expand Up @@ -122,7 +110,10 @@ export class SemanticTokensWalker extends ParseTreeWalker {
}

override visitName(node: NameNode): boolean {
this._visitNameWithType(node, this._evaluator?.getType(node));
// covered by visitDecorator
if (node.parent?.nodeType !== ParseNodeType.Decorator) {
this._visitNameWithType(node, this._evaluator?.getType(node));
}
return super.visitName(node);
}

Expand Down
13 changes: 2 additions & 11 deletions packages/pyright-internal/src/tests/semanticTokensProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,17 @@ if (process.platform !== 'win32' || !process.env['CI']) {
{ type: 'method', modifiers: ['definition'], start: 103, length: 3 },
{ type: 'decorator', modifiers: [], start: 85, length: 1 },
{ type: 'decorator', modifiers: [], start: 86, length: 8 },
{ type: 'class', modifiers: ['defaultLibrary', 'builtin'], start: 86, length: 8 },
{ type: 'method', modifiers: [], start: 103, length: 3 },
{ type: 'parameter', modifiers: ['definition'], start: 107, length: 4 },
{ type: 'class', modifiers: ['defaultLibrary', 'builtin'], start: 116, length: 3 },
{ type: 'method', modifiers: ['definition'], start: 148, length: 3 },
{ type: 'decorator', modifiers: [], start: 130, length: 1 },
{ type: 'decorator', modifiers: [], start: 131, length: 8 },
{ type: 'class', modifiers: ['defaultLibrary', 'builtin'], start: 131, length: 8 },
{ type: 'method', modifiers: [], start: 148, length: 3 },
{ type: 'parameter', modifiers: ['definition'], start: 152, length: 4 },
{ type: 'class', modifiers: ['defaultLibrary', 'builtin'], start: 161, length: 3 },
{ type: 'method', modifiers: ['definition'], start: 194, length: 3 },
{ type: 'decorator', modifiers: [], start: 174, length: 1 },
{ type: 'decorator', modifiers: [], start: 179, length: 6 },
{ type: 'variable', modifiers: [], start: 175, length: 3 },
{ type: 'function', modifiers: [], start: 179, length: 6 },
{ type: 'method', modifiers: [], start: 194, length: 3 },
Expand Down Expand Up @@ -224,33 +221,28 @@ if (process.platform !== 'win32' || !process.env['CI']) {

{ type: 'class', modifiers: ['definition'], start: 115, length: 1 }, // A
{ type: 'decorator', modifiers: [], start: 96, length: 1 }, // @
{ type: 'decorator', modifiers: [], start: 97, length: 9 }, // dataclass
{ type: 'function', modifiers: [], start: 97, length: 9 },
{ type: 'class', modifiers: [], start: 115, length: 1 },

{ type: 'class', modifiers: ['definition'], start: 154, length: 1 }, // B
{ type: 'decorator', modifiers: [], start: 123, length: 1 }, // @
{ type: 'decorator', modifiers: [], start: 136, length: 9 }, // dataclass
{ type: 'namespace', modifiers: [], start: 124, length: 11 }, // dataclasses
{ type: 'function', modifiers: [], start: 136, length: 9 },
{ type: 'function', modifiers: [], start: 136, length: 9 }, // dataclass
{ type: 'class', modifiers: [], start: 154, length: 1 },
{ type: 'method', modifiers: ['definition'], start: 176, length: 6 }, // method
{ type: 'decorator', modifiers: [], start: 161, length: 1 }, // @
{ type: 'decorator', modifiers: [], start: 162, length: 5 }, // final
{ type: 'function', modifiers: [], start: 162, length: 5 },
{ type: 'method', modifiers: [], start: 176, length: 6 },
{ type: 'parameter', modifiers: ['definition'], start: 183, length: 4 }, // self
{ type: 'method', modifiers: ['definition'], start: 220, length: 6 }, // static
{ type: 'decorator', modifiers: [], start: 198, length: 1 }, // @
{ type: 'decorator', modifiers: [], start: 199, length: 12 },
{ type: 'class', modifiers: ['defaultLibrary', 'builtin'], start: 199, length: 12 }, // staticmethod
{ type: 'method', modifiers: [], start: 220, length: 6 },

{ type: 'function', modifiers: ['definition'], start: 256, length: 6 }, // cached
{ type: 'decorator', modifiers: [], start: 235, length: 1 }, // @
{ type: 'decorator', modifiers: [], start: 246, length: 5 }, // cache
{ type: 'namespace', modifiers: [], start: 236, length: 9 }, // functools
{ type: 'function', modifiers: [], start: 246, length: 5 },
{ type: 'function', modifiers: [], start: 246, length: 5 }, // cache
{ type: 'function', modifiers: [], start: 256, length: 6 },
]);
});
Expand All @@ -271,7 +263,6 @@ if (process.platform !== 'win32' || !process.env['CI']) {
{ type: 'method', modifiers: ['definition'], start: 81, length: 1 }, // m
{ type: 'decorator', modifiers: [], start: 60, length: 1 }, // @
{ type: 'decorator', modifiers: [], start: 61, length: 11 },
{ type: 'class', modifiers: ['defaultLibrary', 'builtin'], start: 61, length: 11 }, // classmethod
{ type: 'method', modifiers: [], start: 81, length: 1 },
{ type: 'parameter', modifiers: ['definition'], start: 83, length: 3 }, // cls
{ type: 'parameter', modifiers: [], start: 104, length: 3 }, // cls
Expand Down

0 comments on commit 10ff115

Please sign in to comment.