@@ -179,7 +179,58 @@ abstract class Import extends AstNode {
179179 }
180180
181181 /**
182- * Gets the data flow node that the default import of this import is available at.
182+ * Gets the data flow node referring to imported module object.
183+ *
184+ * For example:
185+ * ```js
186+ * // ES2015 style
187+ * import * as foo from "bar"; // gets the node for `foo`
188+ * import foo from "bar"; // gets the node for `foo` (see note on default imports below)
189+ *
190+ * // CommonJS style
191+ * require("bar"); // gets the node for the `require` call
192+ *
193+ * // AMD style
194+ * define(["bar"], function(foo) { // gets the node for the `foo` parameter
195+ * })
196+ * ```
197+ *
198+ * For statements of form `import foo from "bar'`, this gives the node corresponding to `foo`.
199+ * Technically this should refer to the export binding named `"default"`, not the whole module, but for compatibility with non-standard
200+ * interpretations of default imports, this node is usually treated as also referring to the whole module.
201+ * If this behaviour is not wanted, use `isDefaultImport()` to handle that case differently.
183202 */
184203 abstract DataFlow:: Node getImportedModuleNode ( ) ;
204+
205+ /**
206+ * Holds of the result of `getImportedModuleNode` actually refers to the export binding named `"default"`,
207+ * as opposed an object whose properties correspond to the export bindings of the imported module.
208+ *
209+ * For compatibility with non-standard interpretations of `default` imports, the default
210+ * import is usually returned by `getImportedModuleNode()`. If such behaviour is not wanted,
211+ * this predicate can be used to handle that case differently.
212+ *
213+ * For example, `getImportedModuleNode()` returns `foo` in both of these imports, but `isDefaultImport()`
214+ * only holds for the first one:
215+ * ```js
216+ * import foo from "bar";
217+ * import * as foo from "bar";
218+ * ```
219+ */
220+ predicate isDefaultImport ( ) { none ( ) }
221+
222+ /**
223+ * Gets the same as `getImportedModuleNode()` expect this has no result for default imports when the target module
224+ * has both default and named exports.
225+ *
226+ * This is to avoid ambiguity between named export bindings and the properties of the default-exported object.
227+ */
228+ pragma [ nomagic]
229+ final DataFlow:: Node getImportedModuleNodeIfUnambiguous ( ) {
230+ if
231+ this .isDefaultImport ( ) and
232+ this .getImportedModule ( ) .( ES2015Module ) .hasBothNamedAndDefaultExports ( )
233+ then none ( )
234+ else result = this .getImportedModuleNode ( )
235+ }
185236}
0 commit comments