| // Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8; |
| |
| import static com.android.tools.r8.utils.FileUtils.CLASS_EXTENSION; |
| import static com.android.tools.r8.utils.FileUtils.isClassFile; |
| |
| import com.android.tools.r8.ProgramResource.Kind; |
| import com.android.tools.r8.keepanno.annotations.KeepForApi; |
| import com.android.tools.r8.utils.DescriptorUtils; |
| import com.google.common.collect.Sets; |
| import java.io.File; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** Lazy resource provider returning class file resources based on filesystem directory content. */ |
| @KeepForApi |
| public final class DirectoryClassFileProvider implements ClassFileResourceProvider { |
| private final Path root; |
| |
| /** Create resource provider from directory path. */ |
| public static ClassFileResourceProvider fromDirectory(Path dir) { |
| return new DirectoryClassFileProvider(dir.toAbsolutePath()); |
| } |
| |
| private DirectoryClassFileProvider(Path root) { |
| this.root = root; |
| } |
| |
| @Override |
| public Set<String> getClassDescriptors() { |
| HashSet<String> result = Sets.newHashSet(); |
| collectClassDescriptors(root, result); |
| return result; |
| } |
| |
| private void collectClassDescriptors(Path dir, Set<String> result) { |
| File file = dir.toFile(); |
| if (file.exists()) { |
| File[] files = file.listFiles(); |
| if (files != null) { |
| for (File child : files) { |
| if (child.isDirectory()) { |
| collectClassDescriptors(child.toPath(), result); |
| } else { |
| Path relative = root.relativize(child.toPath()); |
| if (isClassFile(relative)) { |
| result.add(DescriptorUtils.guessTypeDescriptor(relative)); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| @Override |
| public ProgramResource getProgramResource(String descriptor) { |
| assert DescriptorUtils.isClassDescriptor(descriptor); |
| // Build expected file path based on type descriptor. |
| String classBinaryName = DescriptorUtils.getClassBinaryNameFromDescriptor(descriptor); |
| Path file = root.resolve(classBinaryName + CLASS_EXTENSION); |
| return (Files.exists(file) && !Files.isDirectory(file)) |
| ? ProgramResource.fromFile(Kind.CF, file) |
| : null; |
| } |
| |
| public Path getRoot() { |
| return root; |
| } |
| } |