@@ -20,6 +20,25 @@ import { getDefaultBazelExecutablePath } from "../extension/configuration";
20
20
import { blaze_query } from "../protos" ;
21
21
import { CodeLensCommandAdapter } from "./code_lens_command_adapter" ;
22
22
23
+ /** Computes the shortened name of a Bazel target.
24
+ *
25
+ * For example, if the target name starts with `//foo/bar/baz:fizbuzz`,
26
+ * the target's short name will be `fizzbuzz`.
27
+ *
28
+ * This allows our code lens suggestions to avoid filling users' screen with
29
+ * redundant path information.
30
+ *
31
+ * @param targetName The unshortened name of the target.
32
+ * @returns The shortened name of the target.
33
+ */
34
+ function getTargetShortName ( targetName : string ) : string {
35
+ const colonFragments = targetName . split ( ":" ) ;
36
+ if ( colonFragments . length !== 2 ) {
37
+ return targetName ;
38
+ }
39
+ return colonFragments [ 1 ] ;
40
+ }
41
+
23
42
/** Provids CodeLenses for targets in Bazel BUILD files. */
24
43
export class BazelBuildCodeLensProvider implements vscode . CodeLensProvider {
25
44
public onDidChangeCodeLenses : vscode . Event < void > ;
@@ -107,40 +126,60 @@ export class BazelBuildCodeLensProvider implements vscode.CodeLensProvider {
107
126
) : vscode . CodeLens [ ] {
108
127
const result : vscode . CodeLens [ ] = [ ] ;
109
128
129
+ interface LensCommand {
130
+ commandString : string ;
131
+ name : string ;
132
+ }
133
+
110
134
for ( const target of queryResult . target ) {
111
135
const location = new QueryLocation ( target . rule . location ) ;
112
136
const targetName = target . rule . name ;
113
137
const ruleClass = target . rule . ruleClass ;
114
- let cmd : vscode . Command ;
138
+ const targetShortName = getTargetShortName ( targetName ) ;
139
+
140
+ const commands : LensCommand [ ] = [ ] ;
141
+
142
+ // Only test targets support testing.
115
143
if ( ruleClass . endsWith ( "_test" ) || ruleClass === "test_suite" ) {
116
- cmd = {
117
- arguments : [
118
- new CodeLensCommandAdapter ( bazelWorkspaceInfo , [ targetName ] ) ,
119
- ] ,
120
- command : "bazel.testTarget" ,
121
- title : `Test ${ targetName } ` ,
122
- tooltip : `Test ${ targetName } ` ,
123
- } ;
124
- } else if ( ruleClass . endsWith ( "_binary" ) ) {
125
- cmd = {
126
- arguments : [
127
- new CodeLensCommandAdapter ( bazelWorkspaceInfo , [ targetName ] ) ,
128
- ] ,
129
- command : "bazel.runTarget" ,
130
- title : `Run ${ targetName } ` ,
131
- tooltip : `Run ${ targetName } ` ,
132
- } ;
133
- } else {
134
- cmd = {
135
- arguments : [
136
- new CodeLensCommandAdapter ( bazelWorkspaceInfo , [ targetName ] ) ,
137
- ] ,
138
- command : "bazel.buildTarget" ,
139
- title : `Build ${ targetName } ` ,
140
- tooltip : `Build ${ targetName } ` ,
141
- } ;
144
+ commands . push ( {
145
+ commandString : "bazel.testTarget" ,
146
+ name : "Test" ,
147
+ } ) ;
148
+ }
149
+
150
+ // Targets which are not libraries may support running.
151
+ //
152
+ // Without checking the Bazel rule's `executable` attribute we can't know
153
+ // for sure which targets can be run. This could be calculated by running
154
+ // `bazel cquery`, but this would introduce significant costs due to
155
+ // first running the `analysis` phase, so we use a heuristic instead.
156
+ const ruleIsLibrary = ruleClass . endsWith ( "_library" ) ;
157
+ if ( ! ruleIsLibrary ) {
158
+ commands . push ( {
159
+ commandString : "bazel.runTarget" ,
160
+ name : "Run" ,
161
+ } ) ;
162
+ }
163
+
164
+ // All targets support building.
165
+ commands . push ( {
166
+ commandString : "bazel.buildTarget" ,
167
+ name : "Build" ,
168
+ } ) ;
169
+
170
+ for ( const command of commands ) {
171
+ const title = `${ command . name } ${ targetShortName } ` ;
172
+ result . push (
173
+ new vscode . CodeLens ( location . range , {
174
+ arguments : [
175
+ new CodeLensCommandAdapter ( bazelWorkspaceInfo , [ targetName ] ) ,
176
+ ] ,
177
+ command : command . commandString ,
178
+ title,
179
+ tooltip : title ,
180
+ } ) ,
181
+ ) ;
142
182
}
143
- result . push ( new vscode . CodeLens ( location . range , cmd ) ) ;
144
183
}
145
184
146
185
return result ;
0 commit comments