code: static Visibility getEffectivePropertyVisibility(
        PropertyReference propRef,
        ObjectType referenceType,
        ImmutableMap<StaticSourceFile, Visibility> fileVisibilityMap,
        @Nullable CodingConvention codingConvention) {
      String propertyName = propRef.getName();
      boolean isOverride = propRef.isOverride();
  
      StaticSourceFile definingSource =
          AccessControlUtils.getDefiningSource(propRef.getSourceNode(), referenceType, propertyName);
      Visibility fileOverviewVisibility = fileVisibilityMap.get(definingSource);
      ObjectType objectType =
          AccessControlUtils.getObjectType(referenceType, isOverride, propertyName);
  
      if (isOverride) {
        Visibility overridden =
            AccessControlUtils.getOverriddenPropertyVisibility(objectType, propertyName);
        return AccessControlUtils.getEffectiveVisibilityForOverriddenProperty(
            overridden, fileOverviewVisibility, propertyName, codingConvention);
      } else {
        return getEffectiveVisibilityForNonOverriddenProperty(
            propRef, objectType, fileOverviewVisibility, codingConvention);
      }
    }
docs: Returns the effective visibility of the given property. This can differ from the property's
  declared visibility if the property is inherited from a superclass, or if the file's
  {@code @fileoverview} JsDoc specifies a default visibility.
  
  <p>TODO(b/111789692): The following methods are forked from `AccessControlUtils`. Consider
  consolidating them.
  
  @param referenceType The JavaScript type of the property.
  @param fileVisibilityMap A map of {@code @fileoverview} visibility annotations, used to compute
  the property's default visibility.
  @param codingConvention The coding convention in effect (if any), used to determine whether the
  property is private by lexical convention (example: trailing underscore).