blob: 53f15bac4b3b28bf7ff3e137dad4fd6131ec5167 [file] [log] [blame]
// 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;
}
}