docs: function checkClassPropertyAccess(node, left, type, prop) {
              var flags = getDeclarationFlagsFromSymbol(prop);
              var declaringClass = getDeclaredTypeOfSymbol(getParentOfSymbol(prop));
              var errorNode = node.kind === 172 /* PropertyAccessExpression */ || node.kind === 218 /* VariableDeclaration */ ?
                  node.name :
                  node.right;
              if (left.kind === 95 /* SuperKeyword */) {
                  // TS 1.0 spec (April 2014): 4.8.2
                  // - In a constructor, instance member function, instance member accessor, or
                  //   instance member variable initializer where this references a derived class instance,
                  //   a super property access is permitted and must specify a public instance member function of the base class.
                  // - In a static member function or static member accessor
                  //   where this references the constructor function object of a derived class,
                  //   a super property access is permitted and must specify a public static member function of the base class.
                  if (languageVersion < 2 /* ES6 */ && getDeclarationKindFromSymbol(prop) !== 147 /* MethodDeclaration */) {
                      // `prop` refers to a *property* declared in the super class
                      // rather than a *method*, so it does not satisfy the above criteria.
                      error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                      return false;
                  }
                  if (flags & 128 /* Abstract */) {
                      // A method cannot be accessed in a super property access if the method is abstract.
                      // This error could mask a private property access error. But, a member
                      // cannot simultaneously be private and abstract, so this will trigger an
                      // additional error elsewhere.
                      error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(declaringClass));
                      return false;
                  }
              }
              // Public properties are otherwise accessible.
              if (!(flags & (8 /* Private */ | 16 /* Protected */))) {
                  return true;
              }
              // Property is known to be private or protected at this point
              // Private property is accessible if the property is within the declaring class
              if (flags & 8 /* Private */) {
                  var declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                  if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                      error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(declaringClass));
                      return false;
                  }
                  return true;
              }
              // Property is known to be protected at this point
              // All protected properties of a supertype are accessible in a super access
              if (left.kind === 95 /* SuperKeyword */) {
                  return true;
              }
              // Get the enclosing class that has the declaring class as its base type
              var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
                  var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
                  return hasBaseType(enclosingClass, declaringClass) ? enclosingClass : undefined;
              });
              // A protected property is accessible if the property is within the declaring class or classes derived from it
              if (!enclosingClass) {
                  error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(declaringClass));
                  return false;
              }
              // No further restrictions for static properties
              if (flags & 32 /* Static */) {
                  return true;
              }
              // An instance property must be accessed through an instance of the enclosing class
              if (type.flags & 268435456 /* ThisType */) {
                  // get the original type -- represented as the type constraint of the 'this' type
                  type = getConstraintOfTypeParameter(type);
              }
              // TODO: why is the first part of this check here?
              if (!(getTargetType(type).flags & (32768 /* Class */ | 65536 /* Interface */) && hasBaseType(type, enclosingClass))) {
                  error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                  return false;
              }
              return true;
          }