All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.parsing.ParsingUtil Maven / Gradle / Ivy

/*
 * Copyright 2019 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.javascript.jscomp.parsing;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.javascript.rhino.Node;
import java.util.function.Consumer;

/** Utility functions for parsing that don't depend on the compiler. */
public final class ParsingUtil {
  // Utility class; do not instantiate.
  private ParsingUtil() {}

  /** Calls {@code cb} with all NAMEs declared in a PARAM_LIST or destructuring pattern. */
  public static void getParamOrPatternNames(Node n, Consumer cb) {
    checkNotNull(n);
    switch (n.getToken()) {
      case EMPTY: // let [,] = ...
      case GETELEM: // [someArray[1]] = ...
      case GETPROP: // [someObj.someProp] = ...
        // An empty node or assigned to an existing value means nothings here and we can't recurse
        // further.
        break;

      case NAME: // let [someName] = ...
        // A name node generally means we found an assignment happening.
        cb.accept(n);
        break;

      case ITER_REST: // let [...name] = ...
      case OBJECT_REST: // let {...name} = ...
      case STRING_KEY: // let {name} = ...
      case DEFAULT_VALUE: // let {name = 10} = ...
        // For these node types there is a name node as the first child.
        getParamOrPatternNames(n.getFirstChild(), cb);
        break;

      case COMPUTED_PROP: // let {[someProp]: name} = ...
        // For this node types there is a name node as the second child.
        getParamOrPatternNames(n.getSecondChild(), cb);
        break;

      case OBJECT_PATTERN: // let {} = ...
      case ARRAY_PATTERN: // let [] = ...
      case PARAM_LIST: // function fn() ...
        // Each item in the destructuring pattern is scanned for assignments. Although PARAM_LIST
        // isn't technically a pattern, we know how to handle it anyway.
        for (Node c = n.getFirstChild(); c != null; c = c.getNext()) {
          getParamOrPatternNames(c, cb);
        }
        break;

      default:
        throw new IllegalStateException("Unexpected parameter structure");
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy