Skip to content

Commit 2feb00b

Browse files
authored
Merge pull request github#13303 from asgerf/js/use-server-and-client
JS: Move Directive subclasses into module and support "use client/server"
2 parents c378d6a + f8641dd commit 2feb00b

File tree

8 files changed

+205
-140
lines changed

8 files changed

+205
-140
lines changed

javascript/ql/lib/semmle/javascript/AST.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class TopLevel extends @toplevel, StmtContainer {
245245
/** Gets the number of lines containing comments in this toplevel. */
246246
int getNumberOfLinesOfComments() { numlines(this, _, _, result) }
247247

248-
override predicate isStrict() { this.getAStmt() instanceof StrictModeDecl }
248+
override predicate isStrict() { this.getAStmt() instanceof Directive::StrictModeDecl }
249249

250250
override ControlFlowNode getFirstControlFlowNode() { result = this.getEntry() }
251251

javascript/ql/lib/semmle/javascript/Functions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
237237

238238
override predicate isStrict() {
239239
// check for explicit strict mode directive
240-
exists(StrictModeDecl smd | this = smd.getContainer()) or
240+
exists(Directive::StrictModeDecl smd | this = smd.getContainer()) or
241241
// check for enclosing strict function
242242
StmtContainer.super.isStrict() or
243243
// all parts of a class definition are strict code

javascript/ql/lib/semmle/javascript/Stmt.qll

Lines changed: 190 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -259,150 +259,211 @@ class Directive extends MaybeDirective {
259259
}
260260

261261
/**
262-
* A known directive, such as a strict mode declaration.
263-
*
264-
* Example:
265-
*
266-
* ```
267-
* "use strict";
268-
* ```
262+
* Module containing subclasses of the `Directive` class.
269263
*/
270-
abstract class KnownDirective extends Directive { }
264+
module Directive {
265+
/**
266+
* A known directive, such as a strict mode declaration.
267+
*
268+
* Example:
269+
*
270+
* ```
271+
* "use strict";
272+
* ```
273+
*/
274+
abstract class KnownDirective extends Directive { }
271275

272-
/**
273-
* A strict mode declaration.
274-
*
275-
* Example:
276-
*
277-
* ```
278-
* "use strict";
279-
* ```
280-
*/
281-
class StrictModeDecl extends KnownDirective {
282-
StrictModeDecl() { this.getDirectiveText() = "use strict" }
283-
}
276+
/**
277+
* A strict mode declaration.
278+
*
279+
* Example:
280+
*
281+
* ```
282+
* "use strict";
283+
* ```
284+
*/
285+
class StrictModeDecl extends KnownDirective {
286+
StrictModeDecl() { this.getDirectiveText() = "use strict" }
287+
}
284288

285-
/**
286-
* An asm.js directive.
287-
*
288-
* Example:
289-
*
290-
* ```
291-
* "use asm";
292-
* ```
293-
*/
294-
class AsmJSDirective extends KnownDirective {
295-
AsmJSDirective() { this.getDirectiveText() = "use asm" }
296-
}
289+
/**
290+
* An asm.js directive.
291+
*
292+
* Example:
293+
*
294+
* ```
295+
* "use asm";
296+
* ```
297+
*/
298+
class AsmJSDirective extends KnownDirective {
299+
AsmJSDirective() { this.getDirectiveText() = "use asm" }
300+
}
297301

298-
/**
299-
* A Babel directive.
300-
*
301-
* Example:
302-
*
303-
* ```
304-
* "use babel";
305-
* ```
306-
*/
307-
class BabelDirective extends KnownDirective {
308-
BabelDirective() { this.getDirectiveText() = "use babel" }
309-
}
302+
/**
303+
* A Babel directive.
304+
*
305+
* Example:
306+
*
307+
* ```
308+
* "use babel";
309+
* ```
310+
*/
311+
class BabelDirective extends KnownDirective {
312+
BabelDirective() { this.getDirectiveText() = "use babel" }
313+
}
310314

311-
/**
312-
* A legacy 6to5 directive.
313-
*
314-
* Example:
315-
*
316-
* ```
317-
* "use 6to5";
318-
* ```
319-
*/
320-
class SixToFiveDirective extends KnownDirective {
321-
SixToFiveDirective() { this.getDirectiveText() = "use 6to5" }
322-
}
315+
/**
316+
* A legacy 6to5 directive.
317+
*
318+
* Example:
319+
*
320+
* ```
321+
* "use 6to5";
322+
* ```
323+
*/
324+
class SixToFiveDirective extends KnownDirective {
325+
SixToFiveDirective() { this.getDirectiveText() = "use 6to5" }
326+
}
323327

324-
/**
325-
* A SystemJS `format` directive.
326-
*
327-
* Example:
328-
*
329-
* ```
330-
* "format global";
331-
* ```
332-
*/
333-
class SystemJSFormatDirective extends KnownDirective {
334-
SystemJSFormatDirective() {
335-
this.getDirectiveText().regexpMatch("format (cjs|esm|global|register)")
328+
/**
329+
* A SystemJS `format` directive.
330+
*
331+
* Example:
332+
*
333+
* ```
334+
* "format global";
335+
* ```
336+
*/
337+
class SystemJSFormatDirective extends KnownDirective {
338+
SystemJSFormatDirective() {
339+
this.getDirectiveText().regexpMatch("format (cjs|esm|global|register)")
340+
}
336341
}
337-
}
338342

339-
/**
340-
* A SystemJS `format register` directive.
341-
*
342-
* Example:
343-
*
344-
* ```
345-
* "format register";
346-
* ```
347-
*/
348-
class FormatRegisterDirective extends SystemJSFormatDirective {
349-
FormatRegisterDirective() { this.getDirectiveText() = "format register" }
350-
}
343+
/**
344+
* A SystemJS `format register` directive.
345+
*
346+
* Example:
347+
*
348+
* ```
349+
* "format register";
350+
* ```
351+
*/
352+
class FormatRegisterDirective extends SystemJSFormatDirective {
353+
FormatRegisterDirective() { this.getDirectiveText() = "format register" }
354+
}
351355

352-
/**
353-
* A `ngInject` or `ngNoInject` directive.
354-
*
355-
* Example:
356-
*
357-
* ```
358-
* "ngInject";
359-
* ```
360-
*/
361-
class NgInjectDirective extends KnownDirective {
362-
NgInjectDirective() { this.getDirectiveText().regexpMatch("ng(No)?Inject") }
363-
}
356+
/**
357+
* A `ngInject` or `ngNoInject` directive.
358+
*
359+
* Example:
360+
*
361+
* ```
362+
* "ngInject";
363+
* ```
364+
*/
365+
class NgInjectDirective extends KnownDirective {
366+
NgInjectDirective() { this.getDirectiveText().regexpMatch("ng(No)?Inject") }
367+
}
364368

365-
/**
366-
* A YUI compressor directive.
367-
*
368-
* Example:
369-
*
370-
* ```
371-
* "console:nomunge";
372-
* ```
373-
*/
374-
class YuiDirective extends KnownDirective {
375-
YuiDirective() {
376-
this.getDirectiveText().regexpMatch("([a-z0-9_]+:nomunge, ?)*([a-z0-9_]+:nomunge)")
369+
/**
370+
* A YUI compressor directive.
371+
*
372+
* Example:
373+
*
374+
* ```
375+
* "console:nomunge";
376+
* ```
377+
*/
378+
class YuiDirective extends KnownDirective {
379+
YuiDirective() {
380+
this.getDirectiveText().regexpMatch("([a-z0-9_]+:nomunge, ?)*([a-z0-9_]+:nomunge)")
381+
}
377382
}
378-
}
379383

380-
/**
381-
* A SystemJS `deps` directive.
382-
*
383-
* Example:
384-
*
385-
* ```
386-
* "deps fs";
387-
* ```
388-
*/
389-
class SystemJSDepsDirective extends KnownDirective {
390-
SystemJSDepsDirective() { this.getDirectiveText().regexpMatch("deps [^ ]+") }
391-
}
384+
/**
385+
* A SystemJS `deps` directive.
386+
*
387+
* Example:
388+
*
389+
* ```
390+
* "deps fs";
391+
* ```
392+
*/
393+
class SystemJSDepsDirective extends KnownDirective {
394+
SystemJSDepsDirective() { this.getDirectiveText().regexpMatch("deps [^ ]+") }
395+
}
392396

393-
/**
394-
* A `bundle` directive.
395-
*
396-
* Example:
397-
*
398-
* ```
399-
* "bundle";
400-
* ```
401-
*/
402-
class BundleDirective extends KnownDirective {
403-
BundleDirective() { this.getDirectiveText() = "bundle" }
397+
/**
398+
* A `bundle` directive.
399+
*
400+
* Example:
401+
*
402+
* ```
403+
* "bundle";
404+
* ```
405+
*/
406+
class BundleDirective extends KnownDirective {
407+
BundleDirective() { this.getDirectiveText() = "bundle" }
408+
}
409+
410+
/**
411+
* A `use server` directive.
412+
*
413+
* Example:
414+
*
415+
* ```
416+
* "use server";
417+
* ```
418+
*/
419+
class UseServerDirective extends KnownDirective {
420+
UseServerDirective() { this.getDirectiveText() = "use server" }
421+
}
422+
423+
/**
424+
* A `use client` directive.
425+
*
426+
* Example:
427+
*
428+
* ```
429+
* "use client";
430+
* ```
431+
*/
432+
class UseClientDirective extends KnownDirective {
433+
UseClientDirective() { this.getDirectiveText() = "use client" }
434+
}
404435
}
405436

437+
/** DEPRECATED. Use `Directive::KnownDirective` instead. */
438+
deprecated class KnownDirective = Directive::KnownDirective;
439+
440+
/** DEPRECATED. Use `Directive::StrictModeDecl` instead. */
441+
deprecated class StrictModeDecl = Directive::StrictModeDecl;
442+
443+
/** DEPRECATED. Use `Directive::AsmJSDirective` instead. */
444+
deprecated class AsmJSDirective = Directive::AsmJSDirective;
445+
446+
/** DEPRECATED. Use `Directive::BabelDirective` instead. */
447+
deprecated class BabelDirective = Directive::BabelDirective;
448+
449+
/** DEPRECATED. Use `Directive::SixToFiveDirective` instead. */
450+
deprecated class SixToFiveDirective = Directive::SixToFiveDirective;
451+
452+
/** DEPRECATED. Use `Directive::SystemJSFormatDirective` instead. */
453+
deprecated class SystemJSFormatDirective = Directive::SystemJSFormatDirective;
454+
455+
/** DEPRECATED. Use `Directive::NgInjectDirective` instead. */
456+
deprecated class NgInjectDirective = Directive::NgInjectDirective;
457+
458+
/** DEPRECATED. Use `Directive::YuiDirective` instead. */
459+
deprecated class YuiDirective = Directive::YuiDirective;
460+
461+
/** DEPRECATED. Use `Directive::SystemJSDepsDirective` instead. */
462+
deprecated class SystemJSDepsDirective = Directive::SystemJSDepsDirective;
463+
464+
/** DEPRECATED. Use `Directive::BundleDirective` instead. */
465+
deprecated class BundleDirective = Directive::BundleDirective;
466+
406467
/**
407468
* An `if` statement.
408469
*

javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ predicate isMultiLicenseBundle(TopLevel tl) {
242242
/**
243243
* Holds if this is a bundle with a "bundle" directive.
244244
*/
245-
predicate isDirectiveBundle(TopLevel tl) { exists(BundleDirective d | d.getTopLevel() = tl) }
245+
predicate isDirectiveBundle(TopLevel tl) {
246+
exists(Directive::BundleDirective d | d.getTopLevel() = tl)
247+
}
246248

247249
/**
248250
* Holds if toplevel `tl` contains code that looks like the output of a module bundler.

javascript/ql/src/Expressions/UnknownDirective.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import javascript
1212

1313
from Directive d
1414
where
15-
not d instanceof KnownDirective and
15+
not d instanceof Directive::KnownDirective and
1616
// ignore ":" pseudo-directive sometimes seen in dual-use shell/node.js scripts
1717
not d.getExpr().getStringValue() = ":" and
1818
// but exclude attribute top-levels: `<a href="javascript:'some-attribute-string'">`
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import javascript
22

3-
from KnownDirective d
3+
from Directive::KnownDirective d
44
select d, d.getDirectiveText()

javascript/ql/test/query-tests/Expressions/UnknownDirective/UnknownDirective.expected

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
| UnknownDirective.js:12:5:12:17 | "use struct;" | Unknown directive: 'use struct;'. |
1212
| UnknownDirective.js:13:5:13:17 | "Use Strict"; | Unknown directive: 'Use Strict'. |
1313
| UnknownDirective.js:14:5:14:14 | "use bar"; | Unknown directive: 'use bar'. |
14-
| UnknownDirective.js:38:5:38:17 | "[0, 0, 0];"; | Unknown directive: '[0, 0, 0];'. |
15-
| UnknownDirective.js:39:5:39:65 | "[0, 0, ... , 0];"; | Unknown directive: '[0, 0, 0, 0, 0, 0, 0 ... (truncated)'. |
16-
| UnknownDirective.js:45:5:45:15 | ":nomunge"; | Unknown directive: ':nomunge'. |
17-
| UnknownDirective.js:46:5:46:30 | "foo(), ... munge"; | Unknown directive: 'foo(), bar, baz:nomu ... (truncated)'. |
14+
| UnknownDirective.js:40:5:40:17 | "[0, 0, 0];"; | Unknown directive: '[0, 0, 0];'. |
15+
| UnknownDirective.js:41:5:41:65 | "[0, 0, ... , 0];"; | Unknown directive: '[0, 0, 0, 0, 0, 0, 0 ... (truncated)'. |
16+
| UnknownDirective.js:47:5:47:15 | ":nomunge"; | Unknown directive: ':nomunge'. |
17+
| UnknownDirective.js:48:5:48:30 | "foo(), ... munge"; | Unknown directive: 'foo(), bar, baz:nomu ... (truncated)'. |

0 commit comments

Comments
 (0)