code: void pruneOrphanedNames() {
      nextSymbol:
      for (Symbol s : getAllSymbols()) {
        if (s.isProperty()) {
          continue;
        }
  
        String currentName = s.getName();
        int dot = -1;
        while (-1 != (dot = currentName.lastIndexOf('.'))) {
          currentName = currentName.substring(0, dot);
  
          Symbol owner = s.scope.getQualifiedSlot(currentName);
          if (owner != null
              && getType(owner) != null
              && (getType(owner).isNominalConstructor()
                  || getType(owner).isFunctionPrototypeType()
                  || getType(owner).isEnumType())) {
            removeSymbol(s);
            continue nextSymbol;
          }
        }
      }
    }
docs: Removes symbols where the namespace they're on has been removed.
  
  <p>After filling property scopes, we may have two symbols represented in different ways. For
  example, "A.superClass_.foo" and B.prototype.foo".
  
  <p>This resolves that ambiguity by pruning the duplicates. If we have a lexical symbol with a
  constructor in its property chain, then we assume there's also a property path to this symbol.
  In other words, we can remove "A.superClass_.foo" because it's rooted at "A", and we built a
  property scope for "A" above.