1515 * that should be changed to fix the alert.
1616 */
1717
18- import javascript
19-
20- /**
21- * The name of a VS Code command.
22- */
23- class CommandName extends string {
24- CommandName ( ) { exists ( CommandUsage e | e .getCommandName ( ) = this ) }
25-
26- /**
27- * In how many ways is this command used. Will always be at least 1.
28- */
29- int getNumberOfUsages ( ) { result = count ( this .getAUse ( ) ) }
30-
31- /**
32- * Get a usage of this command.
33- */
34- CommandUsage getAUse ( ) { result .getCommandName ( ) = this }
35-
36- /**
37- * Get the canonical first usage of this command, to use for the location
38- * of the alert. The implementation of this ordering of usages is arbitrary
39- * and the usage given may not be the one that should be changed when fixing
40- * the alert.
41- */
42- CommandUsage getFirstUsage ( ) {
43- result =
44- max ( CommandUsage use |
45- use = this .getAUse ( )
46- |
47- use
48- order by
49- use .getFile ( ) .getRelativePath ( ) , use .getLocation ( ) .getStartLine ( ) ,
50- use .getLocation ( ) .getStartColumn ( )
51- )
52- }
53- }
54-
55- /**
56- * Represents a single usage of a command, either from within code or
57- * from the command's definition in package.json
58- */
59- abstract class CommandUsage extends Locatable {
60- abstract string getCommandName ( ) ;
61- }
62-
63- /**
64- * A usage of a command from the typescript code, by calling `executeCommand`.
65- */
66- class CommandUsageCallExpr extends CommandUsage , CallExpr {
67- CommandUsageCallExpr ( ) {
68- this .getCalleeName ( ) = "executeCommand" and
69- this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) .matches ( "%codeQL%" ) and
70- not this .getFile ( ) .getRelativePath ( ) .matches ( "extensions/ql-vscode/test/%" )
71- }
72-
73- override string getCommandName ( ) { result = this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) }
74- }
75-
76- /**
77- * A usage of a command from the typescript code, by calling `CommandManager.execute`.
78- */
79- class CommandUsageCommandManagerMethodCallExpr extends CommandUsage , MethodCallExpr {
80- CommandUsageCommandManagerMethodCallExpr ( ) {
81- this .getCalleeName ( ) = "execute" and
82- this .getReceiver ( ) .getType ( ) .unfold ( ) .( TypeReference ) .getTypeName ( ) .getName ( ) = "CommandManager" and
83- this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) .matches ( "%codeQL%" ) and
84- not this .getFile ( ) .getRelativePath ( ) .matches ( "extensions/ql-vscode/test/%" )
85- }
86-
87- override string getCommandName ( ) { result = this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) }
88- }
89-
90- /**
91- * A usage of a command from any menu that isn't the command palette.
92- * This means a user could invoke the command by clicking on a button in
93- * something like a menu or a dropdown.
94- */
95- class CommandUsagePackageJsonMenuItem extends CommandUsage , JsonObject {
96- CommandUsagePackageJsonMenuItem ( ) {
97- exists ( this .getPropValue ( "command" ) ) and
98- exists ( PackageJson packageJson , string menuName |
99- packageJson
100- .getPropValue ( "contributes" )
101- .getPropValue ( "menus" )
102- .getPropValue ( menuName )
103- .getElementValue ( _) = this and
104- menuName != "commandPalette"
105- )
106- }
107-
108- override string getCommandName ( ) { result = this .getPropValue ( "command" ) .getStringValue ( ) }
109- }
110-
111- /**
112- * Is the given command disabled for use in the command palette by
113- * a block with a `"when": "false"` field.
114- */
115- predicate isDisabledInCommandPalette ( string commandName ) {
116- exists ( PackageJson packageJson , JsonObject commandPaletteObject |
117- packageJson
118- .getPropValue ( "contributes" )
119- .getPropValue ( "menus" )
120- .getPropValue ( "commandPalette" )
121- .getElementValue ( _) = commandPaletteObject and
122- commandPaletteObject .getPropValue ( "command" ) .getStringValue ( ) = commandName and
123- commandPaletteObject .getPropValue ( "when" ) .getStringValue ( ) = "false"
124- )
125- }
126-
127- /**
128- * Represents a command being usable from the command palette.
129- * This means that a user could choose to manually invoke the command.
130- */
131- class CommandUsagePackageJsonCommandPalette extends CommandUsage , JsonObject {
132- CommandUsagePackageJsonCommandPalette ( ) {
133- this .getFile ( ) .getBaseName ( ) = "package.json" and
134- exists ( this .getPropValue ( "command" ) ) and
135- exists ( PackageJson packageJson |
136- packageJson .getPropValue ( "contributes" ) .getPropValue ( "commands" ) .getElementValue ( _) = this
137- ) and
138- not isDisabledInCommandPalette ( this .getPropValue ( "command" ) .getStringValue ( ) )
139- }
140-
141- override string getCommandName ( ) { result = this .getPropValue ( "command" ) .getStringValue ( ) }
142- }
143-
144- from CommandName c
145- where c .getNumberOfUsages ( ) > 1
146- select c .getFirstUsage ( ) ,
147- "The " + c + " command is used from " + c .getNumberOfUsages ( ) + " locations"
148-
18+ import javascript
19+
20+ /**
21+ * The name of a VS Code command.
22+ */
23+ class CommandName extends string {
24+ CommandName ( ) { exists ( CommandUsage e | e .getCommandName ( ) = this ) }
25+
26+ /**
27+ * In how many ways is this command used. Will always be at least 1.
28+ */
29+ int getNumberOfUsages ( ) { result = count ( this .getAUse ( ) ) }
30+
31+ /**
32+ * Get a usage of this command.
33+ */
34+ CommandUsage getAUse ( ) { result .getCommandName ( ) = this }
35+
36+ /**
37+ * Get the canonical first usage of this command, to use for the location
38+ * of the alert. The implementation of this ordering of usages is arbitrary
39+ * and the usage given may not be the one that should be changed when fixing
40+ * the alert.
41+ */
42+ CommandUsage getFirstUsage ( ) {
43+ result =
44+ max ( CommandUsage use |
45+ use = this .getAUse ( )
46+ |
47+ use
48+ order by
49+ use .getFile ( ) .getRelativePath ( ) , use .getLocation ( ) .getStartLine ( ) ,
50+ use .getLocation ( ) .getStartColumn ( )
51+ )
52+ }
53+ }
54+
55+ /**
56+ * Matches one of the members of `BuiltInVsCodeCommands` from `extensions/ql-vscode/src/common/commands.ts`.
57+ */
58+ class BuiltInVSCodeCommand extends string {
59+ BuiltInVSCodeCommand ( ) {
60+ exists ( TypeAliasDeclaration tad |
61+ tad .getIdentifier ( ) .getName ( ) = "BuiltInVsCodeCommands" and
62+ tad .getDefinition ( ) .( InterfaceTypeExpr ) .getAMember ( ) .getName ( ) = this
63+ )
64+ }
65+ }
66+
67+ /**
68+ * Represents a single usage of a command, either from within code or
69+ * from the command's definition in package.json
70+ */
71+ abstract class CommandUsage extends Locatable {
72+ abstract string getCommandName ( ) ;
73+ }
74+
75+ /**
76+ * A usage of a command from the typescript code, by calling `executeCommand`.
77+ */
78+ class CommandUsageCallExpr extends CommandUsage , CallExpr {
79+ CommandUsageCallExpr ( ) {
80+ this .getCalleeName ( ) = "executeCommand" and
81+ this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) .matches ( "%codeQL%" ) and
82+ not this .getFile ( ) .getRelativePath ( ) .matches ( "extensions/ql-vscode/test/%" )
83+ }
84+
85+ override string getCommandName ( ) { result = this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) }
86+ }
87+
88+ /**
89+ * A usage of a command from the typescript code, by calling `CommandManager.execute`.
90+ */
91+ class CommandUsageCommandManagerMethodCallExpr extends CommandUsage , MethodCallExpr {
92+ CommandUsageCommandManagerMethodCallExpr ( ) {
93+ this .getCalleeName ( ) = "execute" and
94+ this .getReceiver ( ) .getType ( ) .unfold ( ) .( TypeReference ) .getTypeName ( ) .getName ( ) = "CommandManager" and
95+ this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) .matches ( "%codeQL%" ) and
96+ not this .getFile ( ) .getRelativePath ( ) .matches ( "extensions/ql-vscode/test/%" )
97+ }
98+
99+ override string getCommandName ( ) { result = this .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) }
100+ }
101+
102+ /**
103+ * A usage of a command from any menu that isn't the command palette.
104+ * This means a user could invoke the command by clicking on a button in
105+ * something like a menu or a dropdown.
106+ */
107+ class CommandUsagePackageJsonMenuItem extends CommandUsage , JsonObject {
108+ CommandUsagePackageJsonMenuItem ( ) {
109+ exists ( this .getPropValue ( "command" ) ) and
110+ exists ( PackageJson packageJson , string menuName |
111+ packageJson
112+ .getPropValue ( "contributes" )
113+ .getPropValue ( "menus" )
114+ .getPropValue ( menuName )
115+ .getElementValue ( _) = this and
116+ menuName != "commandPalette"
117+ )
118+ }
119+
120+ override string getCommandName ( ) { result = this .getPropValue ( "command" ) .getStringValue ( ) }
121+ }
122+
123+ /**
124+ * Is the given command disabled for use in the command palette by
125+ * a block with a `"when": "false"` field.
126+ */
127+ predicate isDisabledInCommandPalette ( string commandName ) {
128+ exists ( PackageJson packageJson , JsonObject commandPaletteObject |
129+ packageJson
130+ .getPropValue ( "contributes" )
131+ .getPropValue ( "menus" )
132+ .getPropValue ( "commandPalette" )
133+ .getElementValue ( _) = commandPaletteObject and
134+ commandPaletteObject .getPropValue ( "command" ) .getStringValue ( ) = commandName and
135+ commandPaletteObject .getPropValue ( "when" ) .getStringValue ( ) = "false"
136+ )
137+ }
138+
139+ /**
140+ * Represents a command being usable from the command palette.
141+ * This means that a user could choose to manually invoke the command.
142+ */
143+ class CommandUsagePackageJsonCommandPalette extends CommandUsage , JsonObject {
144+ CommandUsagePackageJsonCommandPalette ( ) {
145+ this .getFile ( ) .getBaseName ( ) = "package.json" and
146+ exists ( this .getPropValue ( "command" ) ) and
147+ exists ( PackageJson packageJson |
148+ packageJson .getPropValue ( "contributes" ) .getPropValue ( "commands" ) .getElementValue ( _) = this
149+ ) and
150+ not isDisabledInCommandPalette ( this .getPropValue ( "command" ) .getStringValue ( ) )
151+ }
152+
153+ override string getCommandName ( ) { result = this .getPropValue ( "command" ) .getStringValue ( ) }
154+ }
155+
156+ from CommandName c
157+ where c .getNumberOfUsages ( ) > 1 and not c instanceof BuiltInVSCodeCommand
158+ select c .getFirstUsage ( ) ,
159+ "The " + c + " command is used from " + c .getNumberOfUsages ( ) + " locations"
0 commit comments