diff options
author | Benoit Lamarche <benoitlamarche@google.com> | 2014-05-20 11:36:44 +0200 |
---|---|---|
committer | Benoit Lamarche <benoitlamarche@google.com> | 2014-05-23 12:09:19 +0200 |
commit | 13b01b483520bec5491167aa4d09120f21311b25 (patch) | |
tree | 5425e02b2ce435de093f7c8eeff7ea360e627b6b | |
parent | 397d6ff9d3c277e05bc9e99b6b138bff3e18369d (diff) | |
download | toolchain_jack-13b01b483520bec5491167aa4d09120f21311b25.zip toolchain_jack-13b01b483520bec5491167aa4d09120f21311b25.tar.gz toolchain_jack-13b01b483520bec5491167aa4d09120f21311b25.tar.bz2 |
Add VPath to abstract file system paths
Change-Id: Id693176ab9a6351a2bc59c90aadcc0c250114420
10 files changed, 150 insertions, 59 deletions
diff --git a/jack/src/com/android/jack/backend/ResourceWriter.java b/jack/src/com/android/jack/backend/ResourceWriter.java index 0e4fe25..3bf470b 100644 --- a/jack/src/com/android/jack/backend/ResourceWriter.java +++ b/jack/src/com/android/jack/backend/ResourceWriter.java @@ -28,6 +28,7 @@ import com.android.sched.schedulable.Support; import com.android.sched.vfs.InputVFile; import com.android.sched.vfs.OutputVDir; import com.android.sched.vfs.OutputVFile; +import com.android.sched.vfs.VPath; import java.io.InputStream; import java.io.OutputStream; @@ -51,7 +52,7 @@ public class ResourceWriter implements RunnableSchedulable<JSession> { List<Resource> resources = session.getResources(); for (Resource resource : resources) { InputVFile inputFile = resource.getVFile(); - String path = resource.getName(); + VPath path = resource.getPath(); OutputVFile outputFile = outputVDir.createOutputVFile(path); InputStream is = inputFile.openRead(); OutputStream os = outputFile.openWrite(); diff --git a/jack/src/com/android/jack/backend/dex/DexZipWriter.java b/jack/src/com/android/jack/backend/dex/DexZipWriter.java index dc1a84d..d253b06 100644 --- a/jack/src/com/android/jack/backend/dex/DexZipWriter.java +++ b/jack/src/com/android/jack/backend/dex/DexZipWriter.java @@ -29,6 +29,7 @@ import com.android.sched.item.Name; import com.android.sched.schedulable.Constraint; import com.android.sched.schedulable.Produce; import com.android.sched.schedulable.Support; +import com.android.sched.vfs.VPath; import java.io.FileOutputStream; import java.io.IOException; @@ -76,7 +77,8 @@ public class DexZipWriter extends DexFileWriter { private void writeResource(@Nonnull Resource resource, @Nonnull ZipOutputStream zos) throws IOException { - ZipEntry resourceEntry = new ZipEntry(resource.getName()); + VPath path = resource.getPath(); + ZipEntry resourceEntry = new ZipEntry(path.getPathAsString('/')); zos.putNextEntry(resourceEntry); BytesStreamSucker sucker = new BytesStreamSucker(resource.getVFile().openRead(), zos); sucker.suck(); diff --git a/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java b/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java index 0adf52c..5863b14 100644 --- a/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java +++ b/jack/src/com/android/jack/backend/jayce/JayceFileImporter.java @@ -20,14 +20,12 @@ import com.android.jack.Jack; import com.android.jack.JackEventType; import com.android.jack.JackFileException; import com.android.jack.ir.ast.JDefinedClassOrInterface; -import com.android.jack.ir.ast.JPackage; import com.android.jack.ir.ast.JPackageLookupException; import com.android.jack.ir.ast.JSession; import com.android.jack.ir.ast.Resource; -import com.android.jack.ir.formatter.BinaryQualifiedNameFormatter; -import com.android.jack.ir.formatter.TypeFormatter; import com.android.jack.jayce.JayceFormatException; import com.android.jack.jayce.JayceVersionException; +import com.android.jack.lookup.JLookup; import com.android.sched.util.codec.EnumCodec; import com.android.sched.util.config.HasKeyId; import com.android.sched.util.config.ThreadConfig; @@ -40,6 +38,7 @@ import com.android.sched.util.log.TracerFactory; import com.android.sched.vfs.InputVDir; import com.android.sched.vfs.InputVFile; import com.android.sched.vfs.VElement; +import com.android.sched.vfs.VPath; import java.io.IOException; import java.util.List; @@ -67,6 +66,8 @@ public class JayceFileImporter { @Nonnull private final List<InputVDir> jayceContainers; + private static final char VPATH_SEPARATOR = JLookup.PACKAGE_SEPARATOR; + private enum CollisionPolicy { KEEP_FIRST, FAIL @@ -107,9 +108,8 @@ public class JayceFileImporter { for (InputVDir jayceContainer : jayceContainers) { try { logger.log(Level.FINE, "Importing {0}", jayceContainer.getLocation().getDescription()); - JPackage topLevelPackage = session.getTopLevelPackage(); for (VElement subFile : jayceContainer.list()) { - importJayceFile(subFile, session, topLevelPackage); + importJayceFile(subFile, session, ""); } } catch (IOException e) { throw new JackFileException( @@ -119,18 +119,19 @@ public class JayceFileImporter { } private void importJayceFile(@Nonnull VElement element, @Nonnull JSession session, - @Nonnull JPackage pack) throws IOException, JayceFormatException, JayceVersionException, + @Nonnull String currentPath) throws IOException, JayceFormatException, JayceVersionException, JPackageLookupException, TypeImportConflictException, ResourceImportConflictException { + String path = currentPath + element.getName(); if (element instanceof InputVDir) { for (VElement subFile : ((InputVDir) element).list()) { - importJayceFile(subFile, session, pack.getSubPackage(element.getName())); + importJayceFile(subFile, session, path + VPATH_SEPARATOR); } } else if (element instanceof InputVFile) { InputVFile file = (InputVFile) element; if (isJackFileName(file.getName())) { - addImportedTypes(session, file.getName(), pack, file.getLocation()); + addImportedTypes(session, path, file.getLocation()); } else { - addImportedResource(file, session, pack); + addImportedResource(file, session, path); } } else { throw new AssertionError(); @@ -138,14 +139,13 @@ public class JayceFileImporter { } private void addImportedTypes(@Nonnull JSession session, @Nonnull String path, - @Nonnull JPackage pack, @Nonnull Location expectedLoadSource) - throws TypeImportConflictException { + @Nonnull Location expectedLoadSource) throws TypeImportConflictException { Event readEvent = tracer.start(JackEventType.NNODE_READING_FOR_IMPORT); try { - logger.log(Level.FINEST, "Importing jack file ''{0}'' in package ''{1}''", - new Object[] {path, Jack.getUserFriendlyFormatter().getName(pack)}); - String simpleName = path.substring(0, path.length() - JAYCE_FILE_EXTENSION.length()); - JDefinedClassOrInterface declaredType = pack.getType(simpleName); + logger.log(Level.FINEST, "Importing jack file ''{0}''", expectedLoadSource.getDescription()); + String signature = convertJackFilePathToSignature(path); + JDefinedClassOrInterface declaredType = + (JDefinedClassOrInterface) session.getLookup().getType(signature); Location existingSource = declaredType.getLocation(); if (!expectedLoadSource.equals(existingSource)) { if (collisionPolicy == CollisionPolicy.FAIL) { @@ -166,13 +166,18 @@ public class JayceFileImporter { } } + @Nonnull + private String convertJackFilePathToSignature(String path) { + String pathWithoutExt = path.substring(0, path.length() - JAYCE_FILE_EXTENSION.length()); + return "L" + pathWithoutExt.replace(VPATH_SEPARATOR, JLookup.PACKAGE_SEPARATOR) + ";"; + } + private void addImportedResource(@Nonnull InputVFile file, @Nonnull JSession session, - @Nonnull JPackage pack) throws ResourceImportConflictException { - TypeFormatter formatter = BinaryQualifiedNameFormatter.getFormatter(); - String resourceName = formatter.getName(pack, file.getName()); - Resource newResource = new Resource(resourceName, file); + @Nonnull String currentPath) throws ResourceImportConflictException { + VPath path = new VPath(currentPath, VPATH_SEPARATOR); + Resource newResource = new Resource(path, file); for (Resource existingResource : session.getResources()) { - if (existingResource.getName().equals(resourceName)) { + if (existingResource.getPath().equals(path)) { if (resourceCollisionPolicy == CollisionPolicy.FAIL) { throw new ResourceImportConflictException(newResource.getLocation(), existingResource.getLocation()); diff --git a/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java b/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java index ae261e3..3fcfc68 100644 --- a/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java +++ b/jack/src/com/android/jack/backend/jayce/JayceSingleTypeWriter.java @@ -20,13 +20,14 @@ import com.android.jack.Jack; import com.android.jack.JackFileException; import com.android.jack.Options; import com.android.jack.Options.Container; -import com.android.jack.backend.VDirPathFormatter; import com.android.jack.experimental.incremental.CompilerState; import com.android.jack.experimental.incremental.JackIncremental; import com.android.jack.ir.JackFormatIr; import com.android.jack.ir.NonJackFormatIr; import com.android.jack.ir.ast.JDefinedClassOrInterface; -import com.android.jack.ir.formatter.TypeFormatter; +import com.android.jack.ir.naming.CompositeName; +import com.android.jack.ir.naming.TypeName; +import com.android.jack.ir.naming.TypeName.Kind; import com.android.jack.jayce.JayceWriter; import com.android.jack.scheduling.feature.JackFileOutput; import com.android.sched.item.Description; @@ -40,6 +41,7 @@ import com.android.sched.util.config.ThreadConfig; import com.android.sched.util.file.Directory; import com.android.sched.vfs.OutputVDir; import com.android.sched.vfs.OutputVFile; +import com.android.sched.vfs.VPath; import com.android.sched.vfs.direct.OutputDirectDir; import java.io.BufferedOutputStream; @@ -77,11 +79,9 @@ public class JayceSingleTypeWriter implements RunnableSchedulable<JDefinedClassO public synchronized void run(@Nonnull JDefinedClassOrInterface type) throws Exception { OutputVDir vDir = type.getSession().getOutputVDir(); assert vDir != null; - VDirPathFormatter formatter = new VDirPathFormatter(vDir); - String filePath = getFilePath(type, formatter); + VPath filePath = getFilePath(type); OutputVFile vFile = vDir.createOutputVFile(filePath); - try { OutputStream out = new BufferedOutputStream(vFile.openWrite()); try { @@ -94,8 +94,8 @@ public class JayceSingleTypeWriter implements RunnableSchedulable<JDefinedClassO assert outputDir != null; CompilerState csm = JackIncremental.getCompilerState(); assert csm != null; - csm.addMappingBetweenJavaAndJackFile(type.getSourceInfo().getFileName(), - new File(outputDir.getFile(), filePath).getAbsolutePath()); + csm.addMappingBetweenJavaAndJackFile(type.getSourceInfo().getFileName(), new File( + outputDir.getFile(), filePath.getPathAsString(File.separatorChar)).getAbsolutePath()); } } finally { out.close(); @@ -106,8 +106,8 @@ public class JayceSingleTypeWriter implements RunnableSchedulable<JDefinedClassO } @Nonnull - protected static String getFilePath(@Nonnull JDefinedClassOrInterface type, - @Nonnull TypeFormatter formatter) { - return formatter.getName(type) + JayceFileImporter.JAYCE_FILE_EXTENSION; + protected static VPath getFilePath(@Nonnull JDefinedClassOrInterface type) { + return new VPath(new CompositeName(new TypeName(Kind.BINARY_QN, type), + JayceFileImporter.JAYCE_FILE_EXTENSION), '/'); } } diff --git a/jack/src/com/android/jack/ir/ast/Resource.java b/jack/src/com/android/jack/ir/ast/Resource.java index 9c417f5..e574170 100644 --- a/jack/src/com/android/jack/ir/ast/Resource.java +++ b/jack/src/com/android/jack/ir/ast/Resource.java @@ -19,6 +19,7 @@ package com.android.jack.ir.ast; import com.android.sched.item.Description; import com.android.sched.util.location.Location; import com.android.sched.vfs.InputVFile; +import com.android.sched.vfs.VPath; import javax.annotation.Nonnull; @@ -26,17 +27,17 @@ import javax.annotation.Nonnull; * Represents a resource. */ @Description("Represents a resource") -public class Resource implements HasName { +public class Resource { @Nonnull - private CharSequence name; + private VPath path; @Nonnull private final InputVFile vFile; - public Resource(@Nonnull CharSequence resourceName, @Nonnull InputVFile vFile) { + public Resource(@Nonnull VPath path, @Nonnull InputVFile vFile) { this.vFile = vFile; - name = resourceName; + this.path = path; } @Nonnull @@ -49,13 +50,12 @@ public class Resource implements HasName { return vFile.getLocation(); } - @Override @Nonnull - public String getName() { - return name.toString(); + public VPath getPath() { + return path; } - public void setName(@Nonnull CharSequence name) { - this.name = name; + public void setPath(@Nonnull VPath path) { + this.path = path; } } diff --git a/jack/src/com/android/jack/shrob/obfuscation/resource/ResourceRefiner.java b/jack/src/com/android/jack/shrob/obfuscation/resource/ResourceRefiner.java index 81c6745..75fad06 100644 --- a/jack/src/com/android/jack/shrob/obfuscation/resource/ResourceRefiner.java +++ b/jack/src/com/android/jack/shrob/obfuscation/resource/ResourceRefiner.java @@ -16,8 +16,6 @@ package com.android.jack.shrob.obfuscation.resource; -import com.google.common.base.Splitter; - import com.android.jack.Options; import com.android.jack.ir.ast.JPackage; import com.android.jack.ir.ast.JPackageLookupException; @@ -36,6 +34,7 @@ import com.android.sched.item.Description; import com.android.sched.schedulable.Constraint; import com.android.sched.schedulable.RunnableSchedulable; import com.android.sched.util.config.ThreadConfig; +import com.android.sched.vfs.VPath; import java.util.Iterator; @@ -52,16 +51,15 @@ public class ResourceRefiner implements RunnableSchedulable<JSession>{ @Nonnull private final Flags flags = ThreadConfig.get(Options.FLAGS); - private static final char RESOURCE_SEPARATOR = '/'; + private static final char BINARY_QN_SEPARATOR = '/'; - @Nonnull - protected static final Splitter resourceNameSplitter = Splitter.on(RESOURCE_SEPARATOR); + private static final char SHROB_PATH_SEPARATOR = '/'; @CheckForNull - private CharSequence getResourceRefinedName(@Nonnull String resName, + private CharSequence getResourceRefinedName(@Nonnull VPath resPath, @Nonnull JPackage topLevelPackage) { JPackage currentPackage = topLevelPackage; - Iterator<String> iterator = resourceNameSplitter.split(resName).iterator(); + Iterator<String> iterator = resPath.split().iterator(); String name = null; while (iterator.hasNext()) { name = iterator.next(); @@ -101,11 +99,11 @@ public class ResourceRefiner implements RunnableSchedulable<JSession>{ // Construct remaining resource name StringBuilder sb = new StringBuilder(); - sb.append(RESOURCE_SEPARATOR); + sb.append(BINARY_QN_SEPARATOR); assert name != null; sb.append(name); while (iterator.hasNext()) { - sb.append(RESOURCE_SEPARATOR); + sb.append(BINARY_QN_SEPARATOR); sb.append(iterator.next()); } CompositeName refinedName = new CompositeName( @@ -119,12 +117,13 @@ public class ResourceRefiner implements RunnableSchedulable<JSession>{ FilterSpecification adaptResourceFileNames = flags.getAdaptResourceFileNames(); if (adaptResourceFileNames != null) { for (Resource res : session.getResources()) { - String resName = res.getName().toString(); - if (adaptResourceFileNames.matches(resName)) { + VPath resName = res.getPath(); + if (adaptResourceFileNames.matches(resName.getPathAsString(SHROB_PATH_SEPARATOR))) { CharSequence refinedName = getResourceRefinedName(resName, session.getTopLevelPackage()); if (refinedName != null) { - assert refinedName.toString().equals(resName); - res.setName(refinedName); + VPath vPath = new VPath(refinedName, BINARY_QN_SEPARATOR); + assert vPath.equals(resName); + res.setPath(vPath); } } } diff --git a/sched/src/com/android/sched/vfs/OutputVDir.java b/sched/src/com/android/sched/vfs/OutputVDir.java index 92a4c5a..0d05cd3 100644 --- a/sched/src/com/android/sched/vfs/OutputVDir.java +++ b/sched/src/com/android/sched/vfs/OutputVDir.java @@ -26,7 +26,7 @@ import javax.annotation.Nonnull; public interface OutputVDir extends VElement { @Nonnull - OutputVFile createOutputVFile(@Nonnull String filePath) throws IOException; + OutputVFile createOutputVFile(@Nonnull VPath path) throws IOException; char getSeparator(); diff --git a/sched/src/com/android/sched/vfs/VPath.java b/sched/src/com/android/sched/vfs/VPath.java new file mode 100644 index 0000000..6a0f54c --- /dev/null +++ b/sched/src/com/android/sched/vfs/VPath.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sched.vfs; + +import com.google.common.base.Splitter; + +import javax.annotation.Nonnull; + +/** + * A path relative to a VFS. Two instances of {@link VPath} can be compared regardless of the + * separator used as initialization. + */ +public final class VPath { + + @Nonnull + private final CharSequence path; + + private final char separator; + + /** + * Creates an instance of VFS-relative path. The {@link CharSequence} is evaluated lazily at each + * usage. + * @param path the relative path + * @param separator the separator used as file separator in the path + */ + public VPath(@Nonnull CharSequence path, char separator) { + this.path = path; + this.separator = separator; + } + + /** + * Returns the VFS-relative path as an {@link Iterable} of path elements. + */ + @Nonnull + public Iterable<String> split() { + Splitter splitter = Splitter.on(separator); + return splitter.split(path); + } + + /** + * Returns the VFS-relative path using the given separator. + * @param separator the file separator wanted + * @return the relative path + */ + @Nonnull + public String getPathAsString(char separator) { + return path.toString().replace(this.separator, separator); + } + + @Override + public final boolean equals(Object obj) { + if (!(obj instanceof VPath)) { + return false; + } + return getInternalPath().equals(((VPath) obj).getInternalPath()); + } + + @Override + public final int hashCode() { + return getInternalPath().hashCode(); + } + + @Nonnull + private String getInternalPath() { + return path.toString().replace(separator, '/'); + } +} diff --git a/sched/src/com/android/sched/vfs/direct/OutputDirectDir.java b/sched/src/com/android/sched/vfs/direct/OutputDirectDir.java index 02d4cad..f2b084a 100644 --- a/sched/src/com/android/sched/vfs/direct/OutputDirectDir.java +++ b/sched/src/com/android/sched/vfs/direct/OutputDirectDir.java @@ -25,6 +25,7 @@ import com.android.sched.util.location.Location; import com.android.sched.vfs.AbstractVElement; import com.android.sched.vfs.OutputVDir; import com.android.sched.vfs.OutputVFile; +import com.android.sched.vfs.VPath; import java.io.File; @@ -56,9 +57,9 @@ public class OutputDirectDir extends AbstractVElement implements OutputVDir { @Override @Nonnull - public OutputVFile createOutputVFile(@Nonnull String filePath) throws CannotCreateFileException, + public OutputVFile createOutputVFile(@Nonnull VPath path) throws CannotCreateFileException, FileAlreadyExistsException { - File file = new File(dir, filePath); + File file = new File(dir, path.getPathAsString(getSeparator())); if (!file.getParentFile().mkdirs() && !file.getParentFile().isDirectory()) { throw new CannotCreateFileException(new DirectoryLocation(file.getParentFile())); } @@ -69,4 +70,5 @@ public class OutputDirectDir extends AbstractVElement implements OutputVDir { public char getSeparator() { return File.separatorChar; } + } diff --git a/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java b/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java index c4f43f6..635b8ce 100644 --- a/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java +++ b/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java @@ -23,6 +23,7 @@ import com.android.sched.vfs.AbstractVElement; import com.android.sched.vfs.OutputVDir; import com.android.sched.vfs.OutputVFile; import com.android.sched.vfs.VElement; +import com.android.sched.vfs.VPath; import java.io.Closeable; import java.io.File; @@ -69,8 +70,8 @@ public class OutputZipRootVDir extends AbstractVElement implements OutputVDir, C @Override @Nonnull - public OutputVFile createOutputVFile(@Nonnull String filePath) { - return new OutputZipVFile(zos, new ZipEntry(filePath), zipFile); + public OutputVFile createOutputVFile(@Nonnull VPath path) { + return new OutputZipVFile(zos, new ZipEntry(path.getPathAsString(getSeparator())), zipFile); } @Override |