private void checkPropertyVisibility(PropertyReference propRef) {
    if (NodeUtil.isEs6ConstructorMemberFunctionDef(propRef.getSourceNode())) {
      // Class ctor *declarations* can never violate visibility restrictions. They are not
      // accesses and we don't consider them overrides.
      //
      // TODO(nickreid): It would be a lot cleaner if we could model this using `PropertyReference`
      // rather than defining a special case here. I think the problem is that the current
      // implementation of this method conflates "override" with "declaration". But that only works
      // because it ignores cases where there's no overridden definition.
      return;
    }

    JSType rawReferenceType = typeOrUnknown(propRef.getReceiverType()).autobox();
    ObjectType referenceType = castToObject(rawReferenceType);

    String propertyName = propRef.getName();
    boolean isPrivateByConvention = isPrivateByConvention(propertyName);

    if (isPrivateByConvention && propertyIsDeclaredButNotPrivate(propRef)) {
      compiler.report(JSError.make(propRef.getSourceNode(), CONVENTION_MISMATCH));
      return;
    }

    StaticSourceFile definingSource =
        AccessControlUtils.getDefiningSource(propRef.getSourceNode(), referenceType, propertyName);

    // Is this a normal property access, or are we trying to override
    // an existing property?
    boolean isOverride = propRef.isDocumentedDeclaration() || propRef.isOverride();

    ObjectType objectType = AccessControlUtils.getObjectType(
        referenceType, isOverride, propertyName);

    Visibility fileOverviewVisibility =
        defaultVisibilityForFiles.get(definingSource);

    Visibility visibility =
        getEffectivePropertyVisibility(
            propRef,
            referenceType,
            defaultVisibilityForFiles,
            enforceCodingConventions ? compiler.getCodingConvention() : null);

    if (isOverride) {
      Visibility overriding = getOverridingPropertyVisibility(propRef);
      if (overriding != null) {
        checkPropertyOverrideVisibilityIsSame(
            overriding, visibility, fileOverviewVisibility, propRef);
      }
    }

    JSType reportType = rawReferenceType;
    if (objectType != null) {
      Node node = objectType.getOwnPropertyDefSite(propertyName);
      if (node == null) {
        // Assume the property is public.
        return;
      }
      reportType = objectType;
      definingSource = node.getStaticSourceFile();
    } else if (!isPrivateByConvention && fileOverviewVisibility == null) {
      // We can only check visibility references if we know what file
      // it was defined in.
      // Otherwise just assume the property is public.
      return;
    }

    StaticSourceFile referenceSource = propRef.getSourceNode().getStaticSourceFile();

    if (isOverride) {
      boolean sameInput = referenceSource != null
          && referenceSource.getName().equals(definingSource.getName());
      checkPropertyOverrideVisibility(
          propRef, visibility, fileOverviewVisibility, reportType, sameInput);
    } else {
      checkPropertyAccessVisibility(
          propRef, visibility, reportType, referenceSource, definingSource);
    }
  }
private void checkPropertyVisibility ( PropertyReference propRef ) { if ( NodeUtil . isEs6ConstructorMemberFunctionDef ( propRef . getSourceNode ( ) ) ) { return ; } JSType rawReferenceType = typeOrUnknown ( propRef . getReceiverType ( ) ) . autobox ( ) ; ObjectType referenceType = castToObject ( rawReferenceType ) ; String propertyName = propRef . getName ( ) ; boolean isPrivateByConvention = isPrivateByConvention ( propertyName ) ; if ( isPrivateByConvention && propertyIsDeclaredButNotPrivate ( propRef ) ) { compiler . report ( JSError . make ( propRef . getSourceNode ( ) , CONVENTION_MISMATCH ) ) ; return ; } StaticSourceFile definingSource = AccessControlUtils . getDefiningSource ( propRef . getSourceNode ( ) , referenceType , propertyName ) ; boolean isOverride = propRef . isDocumentedDeclaration ( ) || propRef . isOverride ( ) ; ObjectType objectType = AccessControlUtils . getObjectType ( referenceType , isOverride , propertyName ) ; Visibility fileOverviewVisibility = defaultVisibilityForFiles . get ( definingSource ) ; Visibility visibility = getEffectivePropertyVisibility ( propRef , referenceType , defaultVisibilityForFiles , enforceCodingConventions ? compiler . getCodingConvention ( ) : null ) ; if ( isOverride ) { Visibility overriding = getOverridingPropertyVisibility ( propRef ) ; if ( overriding != null ) { checkPropertyOverrideVisibilityIsSame ( overriding , visibility , fileOverviewVisibility , propRef ) ; } } JSType reportType = rawReferenceType ; if ( objectType != null ) { Node node = objectType . getOwnPropertyDefSite ( propertyName ) ; if ( node == null ) { return ; } reportType = objectType ; definingSource = node . getStaticSourceFile ( ) ; } else if ( ! isPrivateByConvention && fileOverviewVisibility == null ) { return ; } StaticSourceFile referenceSource = propRef . getSourceNode ( ) . getStaticSourceFile ( ) ; if ( isOverride ) { boolean sameInput = referenceSource != null && referenceSource . getName ( ) . equals ( definingSource . getName ( ) ) ; checkPropertyOverrideVisibility ( propRef , visibility , fileOverviewVisibility , reportType , sameInput ) ; } else { checkPropertyAccessVisibility ( propRef , visibility , reportType , referenceSource , definingSource ) ; } }
Reports an error if the given property is not visible in the current context.

<p>This method covers both:

<ul>
<li>accesses to properties during execution
<li>overrides of properties during declaration
</ul>

TODO(nickreid): Things would probably be a lot simpler, though a bit duplicated, if these two
concepts were separated. Much of the underlying logic could stop checking various inconsistent
definitions of "is this an override".