Merge "resourceloader: Remove redundant 'group' setting for StartupModule"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 19 Jun 2019 12:26:04 +0000 (12:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 19 Jun 2019 12:26:04 +0000 (12:26 +0000)
1  2 
includes/resourceloader/ResourceLoaderStartUpModule.php

@@@ -124,50 -124,29 +124,50 @@@ class ResourceLoaderStartUpModule exten
         *
         * @param array $registryData
         * @param string $moduleName
 +       * @param string[] $handled Internal parameter for recursion. (Optional)
         * @return array
 +       * @throws ResourceLoaderCircularDependencyError
         */
 -      protected static function getImplicitDependencies( array $registryData, $moduleName ) {
 +      protected static function getImplicitDependencies(
 +              array $registryData,
 +              $moduleName,
 +              array $handled = []
 +      ) {
                static $dependencyCache = [];
  
 -              // The list of implicit dependencies won't be altered, so we can
 -              // cache them without having to worry.
 +              // No modules will be added or changed server-side after this point,
 +              // so we can safely cache parts of the tree for re-use.
                if ( !isset( $dependencyCache[$moduleName] ) ) {
                        if ( !isset( $registryData[$moduleName] ) ) {
 -                              // Dependencies may not exist
 -                              $dependencyCache[$moduleName] = [];
 +                              // Unknown module names are allowed here, this is only an optimisation.
 +                              // Checks for illegal and unknown dependencies happen as PHPUnit structure tests,
 +                              // and also client-side at run-time.
 +                              $flat = [];
                        } else {
                                $data = $registryData[$moduleName];
 -                              $dependencyCache[$moduleName] = $data['dependencies'];
 +                              $flat = $data['dependencies'];
  
 +                              // Prevent recursion
 +                              $handled[] = $moduleName;
                                foreach ( $data['dependencies'] as $dependency ) {
 -                                      // Recursively get the dependencies of the dependencies
 -                                      $dependencyCache[$moduleName] = array_merge(
 -                                              $dependencyCache[$moduleName],
 -                                              self::getImplicitDependencies( $registryData, $dependency )
 -                                      );
 +                                      if ( in_array( $dependency, $handled, true ) ) {
 +                                              // If we encounter a circular dependency, then stop the optimiser and leave the
 +                                              // original dependencies array unmodified. Circular dependencies are not
 +                                              // supported in ResourceLoader. Awareness of them exists here so that we can
 +                                              // optimise the registry when it isn't broken, and otherwise transport the
 +                                              // registry unchanged. The client will handle this further.
 +                                              throw new ResourceLoaderCircularDependencyError();
 +                                      } else {
 +                                              // Recursively add the dependencies of the dependencies
 +                                              $flat = array_merge(
 +                                                      $flat,
 +                                                      self::getImplicitDependencies( $registryData, $dependency, $handled )
 +                                              );
 +                                      }
                                }
                        }
 +
 +                      $dependencyCache[$moduleName] = $flat;
                }
  
                return $dependencyCache[$moduleName];
        public static function compileUnresolvedDependencies( array &$registryData ) {
                foreach ( $registryData as $name => &$data ) {
                        $dependencies = $data['dependencies'];
 -                      foreach ( $data['dependencies'] as $dependency ) {
 -                              $implicitDependencies = self::getImplicitDependencies( $registryData, $dependency );
 -                              $dependencies = array_diff( $dependencies, $implicitDependencies );
 +                      try {
 +                              foreach ( $data['dependencies'] as $dependency ) {
 +                                      $implicitDependencies = self::getImplicitDependencies( $registryData, $dependency );
 +                                      $dependencies = array_diff( $dependencies, $implicitDependencies );
 +                              }
 +                      } catch ( ResourceLoaderCircularDependencyError $err ) {
 +                              // Leave unchanged
 +                              $dependencies = $data['dependencies'];
                        }
 +
                        // Rebuild keys
                        $data['dependencies'] = array_values( $dependencies );
                }
         * @private For internal use by SpecialJavaScriptTest
         * @since 1.32
         * @return array
 +       * @codeCoverageIgnore
         */
        public function getBaseModulesInternal() {
                return $this->getBaseModules();
                // and hash it to determine the version (as used by E-Tag HTTP response header).
                return true;
        }
-       /**
-        * @return string
-        */
-       public function getGroup() {
-               return 'startup';
-       }
  }