code: private void flattenNameRef(String alias, Node n, Node parent,
        String originalName) {
      Preconditions.checkArgument(
          n.isGetProp(), "Expected GETPROP, found %s. Node: %s", n.getToken(), n);
  
      // BEFORE:
      //   getprop
      //     getprop
      //       name a
      //       string b
      //     string c
      // AFTER:
      //   name a$b$c
      Node ref = NodeUtil.newName(compiler, alias, n, originalName);
      NodeUtil.copyNameAnnotations(n.getLastChild(), ref);
      if (parent.isCall() && n == parent.getFirstChild()) {
        // The node was a call target, we are deliberately flatten these as
        // we node the "this" isn't provided by the namespace. Mark it as such:
        parent.putBooleanProp(Node.FREE_CALL, true);
      }
  
      JSType type = n.getJSType();
      if (type != null) {
        ref.setJSType(type);
      }
  
      parent.replaceChild(n, ref);
      compiler.reportChangeToEnclosingScope(ref);
    }
docs: Replaces a GETPROP a.b.c with a NAME a$b$c.
  
  @param alias A flattened prefix name (e.g. "a$b")
  @param n The GETPROP node corresponding to the original name (e.g. "a.b")
  @param parent {@code n}'s parent
  @param originalName String version of the property name.