Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3bd91bd

Browse files
committed
JS: introduce common class for Babel plugins
1 parent 7285562 commit 3bd91bd

2 files changed

Lines changed: 63 additions & 39 deletions

File tree

javascript/ql/src/Declarations/UnusedVariable.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ predicate isReactImportForJSX(UnusedLocal v) {
6565
or
6666
// JSX pragma from a .babelrc file
6767
exists (Babel::TransformReactJsxConfig plugin |
68-
plugin.getConfig().getAContainerInScope() = is.getFile() and
69-
plugin.getJSXFactoryVariableName() = v.getName())
68+
plugin.appliesTo(is.getTopLevel()) and
69+
plugin.getJsxFactoryVariableName() = v.getName())
7070
)
7171
}
7272

javascript/ql/src/semmle/javascript/frameworks/Babel.qll

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,50 @@ module Babel {
4040
not result.getAChildContainer() = any(PackageJSON pkg).getFile() and
4141
not result.getAChildContainer() = any(Config pkg).getFile()
4242
}
43+
44+
/**
45+
* Holds if this configuration applies to `tl`.
46+
*/
47+
predicate appliesTo(TopLevel tl) {
48+
tl.getFile() = getAContainerInScope()
49+
}
50+
}
51+
52+
/**
53+
* Configuration object for a Babel plugin.
54+
*/
55+
class Plugin extends JSONValue {
56+
Config cfg;
57+
string pluginName;
58+
59+
Plugin() {
60+
this = cfg.getPluginConfig(pluginName)
61+
}
62+
63+
/** Gets the name of the plugin begin installed. */
64+
string getPluginName() {
65+
result = pluginName
66+
}
67+
68+
/** Gets the enclosing Babel configuration object. */
69+
Config getConfig() {
70+
result = cfg
71+
}
72+
73+
/** Gets the options value passed to the plugin, if any. */
74+
JSONValue getOptions() {
75+
result = this.(JSONArray).getElementValue(1)
76+
}
77+
78+
/** Gets a named option from the option object, if present. */
79+
JSONValue getOption(string name) {
80+
result = getOptions().(JSONObject).getPropValue(name)
81+
}
82+
83+
/** Holds if this plugin applies to `tl`. */
84+
predicate appliesTo(TopLevel tl) {
85+
cfg.appliesTo(tl)
86+
}
4387
}
4488

4589
/**
@@ -50,11 +94,9 @@ module Babel {
5094
* each path is of the form `{ "rootPathPrefix": "...", "rootPathSuffix": "..." }` and explicitly
5195
* specifies a mapping from a path prefix to a root.
5296
*/
53-
class RootImportConfig extends JSONArray {
54-
Config cfg;
55-
97+
class RootImportConfig extends Plugin {
5698
RootImportConfig() {
57-
this = cfg.getPluginConfig("babel-plugin-root-import")
99+
pluginName = "babel-plugin-root-import"
58100
}
59101

60102
/**
@@ -74,15 +116,16 @@ module Babel {
74116
*/
75117
private JSONObject getARootPathSpec() {
76118
// ["babel-plugin-root-import", <spec>]
77-
result = getElementValue(1) and
119+
result = getOptions() and
78120
exists(result.getPropValue("rootPathSuffix"))
79121
or
80122
exists (JSONArray pathSpecs |
81123
// ["babel-plugin-root-import", [ <spec>... ] ]
82-
pathSpecs = getElementValue(1)
124+
pathSpecs = getOptions()
83125
or
84126
// ["babel-plugin-root-import", { "paths": [ <spec> ... ] }]
85-
pathSpecs = getElementValue(1).(JSONObject).getPropValue("paths") |
127+
pathSpecs = getOption("paths")
128+
|
86129
result = pathSpecs.getElementValue(_)
87130
)
88131
}
@@ -107,37 +150,30 @@ module Babel {
107150
Folder getFolder() {
108151
result = getFile().getParentContainer()
109152
}
110-
111-
/**
112-
* Holds if this configuration applies to `tl`.
113-
*/
114-
predicate appliesTo(TopLevel tl) {
115-
tl.getFile().getParentContainer+() = getFolder()
116-
}
117153
}
118154

119155
/**
120156
* An import path expression that may be transformed by `babel-plugin-root-import`.
121157
*/
122158
private class BabelRootTransformedPathExpr extends PathExpr, Expr {
123-
RootImportConfig cfg;
159+
RootImportConfig plugin;
124160
string rawPath;
125161
string prefix;
126162
string mappedPrefix;
127163
string suffix;
128164

129165
BabelRootTransformedPathExpr() {
130166
this instanceof PathExpr and
131-
cfg.appliesTo(getTopLevel()) and
167+
plugin.appliesTo(getTopLevel()) and
132168
rawPath = getStringValue() and
133169
prefix = rawPath.regexpCapture("(.)/(.*)", 1) and
134170
suffix = rawPath.regexpCapture("(.)/(.*)", 2) and
135-
mappedPrefix = cfg.getRoot(prefix)
171+
mappedPrefix = plugin.getRoot(prefix)
136172
}
137173

138174
/** Gets the configuration that applies to this path. */
139-
RootImportConfig getConfig() {
140-
result = cfg
175+
RootImportConfig getPlugin() {
176+
result = plugin
141177
}
142178

143179
override string getValue() {
@@ -146,7 +182,7 @@ module Babel {
146182

147183
override Folder getSearchRoot(int priority) {
148184
priority = 0 and
149-
result = cfg.getFolder()
185+
result = plugin.getFolder()
150186
}
151187
}
152188

@@ -161,7 +197,7 @@ module Babel {
161197
}
162198

163199
override Folder getARootFolder() {
164-
result = pathExpr.getConfig().getFolder()
200+
result = pathExpr.getPlugin().getFolder()
165201
}
166202
}
167203

@@ -171,26 +207,14 @@ module Babel {
171207
* The plugin option `{"pragma": xxx}` specifies a variable name used to instantiate
172208
* JSX elements.
173209
*/
174-
class TransformReactJsxConfig extends JSONArray {
175-
Config cfg;
176-
210+
class TransformReactJsxConfig extends Plugin {
177211
TransformReactJsxConfig() {
178-
this = cfg.getPluginConfig("transform-react-jsx")
179-
}
180-
181-
/** Gets the Babel configuration object. */
182-
Config getConfig() {
183-
result = cfg
184-
}
185-
186-
/** Gets the options passed to this plugin. */
187-
JSONObject getOptions() {
188-
result = getElementValue(1)
212+
pluginName = "transform-react-jsx"
189213
}
190214

191215
/** Gets the name of the variable used to create JSX elements. */
192-
string getJSXFactoryVariableName() {
193-
result = getOptions().getPropStringValue("pragma")
216+
string getJsxFactoryVariableName() {
217+
result = getOption("pragma").(JSONString).getValue()
194218
}
195219
}
196220
}

0 commit comments

Comments
 (0)