Exemplo n.º 1
0
  private boolean requireFile(String feature, String path, Node currentNode) throws IOException {
    // We expect '/' in various classpath URLs, so normalize Windows file paths to use '/'
    path = path.replace('\\', '/');
    final RubyBasicObject loadedFeatures = context.getCoreLibrary().getLoadedFeatures();

    if (path.startsWith("uri:classloader:/")) {
      // TODO CS 13-Feb-15 this uri:classloader:/ and core:/ thing is a hack - simplify it

      for (Object loaded : Arrays.asList(ArrayNodes.slowToArray(loadedFeatures))) {
        if (loaded.toString().equals(path)) {
          return true;
        }
      }

      String coreFileName = path.substring("uri:classloader:/".length());

      coreFileName = FileSystems.getDefault().getPath(coreFileName).normalize().toString();

      if (context
              .getRuntime()
              .getLoadService()
              .getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName)
          == null) {
        return false;
      }

      if (SHOW_RESOLUTION) {
        System.err.printf("resolved %s -> %s%n", feature, coreFileName);
      }

      context.getCoreLibrary().loadRubyCore(coreFileName, "uri:classloader:/");
      ArrayNodes.slowPush(
          loadedFeatures,
          StringNodes.createString(context.getCoreLibrary().getStringClass(), path));

      return true;
    } else if (path.startsWith("core:/")) {
      for (Object loaded : Arrays.asList(ArrayNodes.slowToArray(loadedFeatures))) {
        if (loaded.toString().equals(path)) {
          return true;
        }
      }

      final String coreFileName = path.substring("core:/".length());

      if (context
              .getRuntime()
              .getLoadService()
              .getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName)
          == null) {
        return false;
      }

      if (SHOW_RESOLUTION) {
        System.err.printf("resolved %s -> %s%n", feature, coreFileName);
      }

      context.getCoreLibrary().loadRubyCore(coreFileName, "core:/");
      ArrayNodes.slowPush(
          loadedFeatures,
          StringNodes.createString(context.getCoreLibrary().getStringClass(), path));

      return true;
    } else {
      final File file = new File(path);

      assert file.isAbsolute();

      if (!file.isAbsolute() || !file.isFile()) {
        return false;
      }

      final String expandedPath = expandPath(context, path);

      for (Object loaded : Arrays.asList(ArrayNodes.slowToArray(loadedFeatures))) {
        if (loaded.toString().equals(expandedPath)) {
          return true;
        }
      }

      if (SHOW_RESOLUTION) {
        System.err.printf("resolved %s -> %s%n", feature, expandedPath);
      }

      // TODO (nirvdrum 15-Jan-15): If we fail to load, we should remove the path from the loaded
      // features because subsequent requires of the same statement may succeed.
      final RubyBasicObject pathString =
          StringNodes.createString(context.getCoreLibrary().getStringClass(), expandedPath);
      ArrayNodes.slowPush(loadedFeatures, pathString);
      try {
        context.loadFile(path, currentNode);
      } catch (RaiseException e) {
        final ArrayMirror mirror =
            ArrayMirror.reflect((Object[]) ArrayNodes.getStore(loadedFeatures));
        final int length = ArrayNodes.getSize(loadedFeatures);
        for (int i = length - 1; i >= 0; i--) {
          if (mirror.get(i) == pathString) {
            for (int j = length - 1; j > i; j--) {
              mirror.set(i - 1, mirror.get(i));
            }
            ArrayNodes.setSize(loadedFeatures, length - 1);
            break;
          }
        }
        throw e;
      }
    }

    return true;
  }