public static Node getDeclaringParent(Node targetNode) {
    Node rootTarget = getRootTarget(targetNode);
    Node parent = rootTarget.getParent();
    if (parent.isRest() || parent.isDefaultValue()) {
      // e.g. `function foo(targetNode1 = default, ...targetNode2) {}`
      parent = parent.getParent();
      checkState(parent.isParamList(), parent);
    } else if (parent.isDestructuringLhs()) {
      // e.g. `let [a, b] = something;` targetNode is `[a, b]`
      parent = parent.getParent();
      checkState(isNameDeclaration(parent), parent);
    } else if (parent.isClass() || parent.isFunction()) {
      // e.g. `function targetNode() {}`
      // e.g. `class targetNode {}`
      checkState(targetNode == parent.getFirstChild(), targetNode);
    } else if (parent.isImportSpec()) {
      // e.g. `import {foo as targetNode} from './foo';
      checkState(targetNode == parent.getSecondChild(), targetNode);
      // import -> import_specs -> import_spec
      // we want import
      parent = parent.getGrandparent();
      checkState(parent.isImport(), parent);
    } else {
      // e.g. `function foo(targetNode) {};`
      // e.g. `let targetNode = something;`
      // e.g. `import targetNode from './foo';
      // e.g. `} catch (foo) {`
      checkState(
          parent.isParamList()
              || isNameDeclaration(parent)
              || parent.isImport()
              || parent.isCatch(),
          parent);
    }
    return parent;
  }
public static Node getDeclaringParent ( Node targetNode ) { Node rootTarget = getRootTarget ( targetNode ) ; Node parent = rootTarget . getParent ( ) ; if ( parent . isRest ( ) || parent . isDefaultValue ( ) ) { parent = parent . getParent ( ) ; checkState ( parent . isParamList ( ) , parent ) ; } else if ( parent . isDestructuringLhs ( ) ) { parent = parent . getParent ( ) ; checkState ( isNameDeclaration ( parent ) , parent ) ; } else if ( parent . isClass ( ) || parent . isFunction ( ) ) { checkState ( targetNode == parent . getFirstChild ( ) , targetNode ) ; } else if ( parent . isImportSpec ( ) ) { checkState ( targetNode == parent . getSecondChild ( ) , targetNode ) ; parent = parent . getGrandparent ( ) ; checkState ( parent . isImport ( ) , parent ) ; } else { checkState ( parent . isParamList ( ) || isNameDeclaration ( parent ) || parent . isImport ( ) || parent . isCatch ( ) , parent ) ; } return parent ; }
Returns the node that is effectively declaring the given target.

<p>Examples:

<pre><code>
const a = 1; // getDeclaringParent(a) returns CONST
let {[expression]: [x = 3]} = obj; // getDeclaringParent(x) returns LET
function foo({a, b}) {}; // getDeclaringParent(a) returns PARAM_LIST
function foo(a = 1) {}; // getDeclaringParent(a) returns PARAM_LIST
function foo({a, b} = obj) {}; // getDeclaringParent(a) returns PARAM_LIST
function foo(...a) {}; // getDeclaringParent(a) returns PARAM_LIST
function foo() {}; // gotRootTarget(foo) returns FUNCTION
class foo {}; // gotRootTarget(foo) returns CLASS
import foo from './foo'; // getDeclaringParent(foo) returns IMPORT
import {foo} from './foo'; // getDeclaringParent(foo) returns IMPORT
import {foo as bar} from './foo'; // getDeclaringParent(bar) returns IMPORT
} catch (err) { // getDeclaringParent(err) returns CATCH
</code></pre>

@param targetNode a NAME, OBJECT_PATTERN, or ARRAY_PATTERN
@return node of type LET, CONST, VAR, FUNCTION, CLASS, PARAM_LIST, CATCH, or IMPORT
@throws IllegalStateException if targetNode is not actually used as a declaration target