aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/java/buck-ios-support
diff options
context:
space:
mode:
authorGravatar Han-Wen Nienhuys <hanwen@google.com>2015-02-25 16:45:20 +0100
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-02-25 16:45:20 +0100
commitd08b27fa9701fecfdb69e1b0d1ac2459efc2129b (patch)
tree5d50963026239ca5aebfb47ea5b8db7e814e57c8 /third_party/java/buck-ios-support
Update from Google.
-- MOE_MIGRATED_REVID=85702957
Diffstat (limited to 'third_party/java/buck-ios-support')
-rw-r--r--third_party/java/buck-ios-support/LICENSE202
-rw-r--r--third_party/java/buck-ios-support/README15
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/FileTypes.java121
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/GidGenerator.java50
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/XcodeprojSerializer.java140
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXAggregateTarget.java31
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildFile.java80
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildPhase.java44
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildStyle.java61
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainer.java28
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItem.java36
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItemProxy.java88
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXCopyFilesBuildPhase.java85
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFileReference.java78
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFrameworksBuildPhase.java28
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXGroup.java165
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXHeadersBuildPhase.java28
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXNativeTarget.java32
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXObject.java67
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProject.java102
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProjectItem.java24
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXReference.java158
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXResourcesBuildPhase.java30
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXShellScriptBuildPhase.java130
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXSourcesBuildPhase.java29
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTarget.java138
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTargetDependency.java53
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXVariantGroup.java96
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/SourceTreePath.java65
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCBuildConfiguration.java55
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCConfigurationList.java82
-rw-r--r--third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCVersionGroup.java114
32 files changed, 2455 insertions, 0 deletions
diff --git a/third_party/java/buck-ios-support/LICENSE b/third_party/java/buck-ios-support/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/java/buck-ios-support/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/third_party/java/buck-ios-support/README b/third_party/java/buck-ios-support/README
new file mode 100644
index 0000000000..2799abedba
--- /dev/null
+++ b/third_party/java/buck-ios-support/README
@@ -0,0 +1,15 @@
+URL: https://github.com/facebook/buck/tarball/2ff4f45a971776afcfbe88333d78c4ca6bf03df9
+Version: 2ff4f45a971776afcfbe88333d78c4ca6bf03df9
+License: Apache 2.0
+License File: LICENSE
+
+Description:
+Buck: An Android (and Java!) build tool
+
+This copy is stripped down to only include the files needed for Xcode project generation, specifically:
+com/facebook/buck/apple/{FileTypes,xcode/{xcodeproj/**,GidGenerator,XcodeprojSerializer}}.java
+
+Local Modifications:
+Add FILE_REFERENCE(2) to the PBXContainerItemProxy.ProxyType enum.
+Update LastUpgradeCheck from 600 to 610
+Add logic to automatically detect XCVersionGroup type even if there is no currentVersion set
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/FileTypes.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/FileTypes.java
new file mode 100644
index 0000000000..1ea0c04831
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/FileTypes.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2014-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * File types used in Apple targets.
+ */
+public final class FileTypes {
+
+ // Utility class. Do not instantiate.
+ private FileTypes() { }
+
+ /**
+ * Map of file extension to Apple UTI (Uniform Type Identifier).
+ */
+ public static final ImmutableMap<String, String> FILE_EXTENSION_TO_UTI =
+ ImmutableMap.<String, String>builder()
+ .put("a", "archive.ar")
+ .put("app", "wrapper.application")
+ .put("appex", "wrapper.app-extension")
+ .put("bdic", "file")
+ .put("bin", "archive.macbinary")
+ .put("bmp", "image.bmp")
+ .put("bundle", "wrapper.cfbundle")
+ .put("c", "sourcecode.c.c")
+ .put("cc", "sourcecode.cpp.cpp")
+ .put("cpp", "sourcecode.cpp.cpp")
+ .put("css", "text.css")
+ .put("cxx", "sourcecode.cpp.cpp")
+ .put("dart", "sourcecode")
+ .put("dylib", "compiled.mach-o.dylib")
+ .put("exp", "sourcecode.exports")
+ .put("framework", "wrapper.framework")
+ .put("fsh", "sourcecode.glsl")
+ .put("gyp", "sourcecode")
+ .put("gypi", "text")
+ .put("h", "sourcecode.c.h")
+ .put("hxx", "sourcecode.cpp.h")
+ .put("icns", "image.icns")
+ .put("java", "sourcecode.java")
+ .put("jar", "archive.jar")
+ .put("jpeg", "image.jpeg")
+ .put("jpg", "image.jpeg")
+ .put("js", "sourcecode.javascript")
+ .put("json", "text.json")
+ .put("m", "sourcecode.c.objc")
+ .put("mm", "sourcecode.cpp.objcpp")
+ .put("nib", "wrapper.nib")
+ .put("o", "compiled.mach-o.objfile")
+ .put("octest", "wrapper.cfbundle")
+ .put("pdf", "image.pdf")
+ .put("pl", "text.script.perl")
+ .put("plist", "text.plist.xml")
+ .put("pm", "text.script.perl")
+ .put("png", "image.png")
+ .put("proto", "text")
+ .put("py", "text.script.python")
+ .put("r", "sourcecode.rez")
+ .put("rez", "sourcecode.rez")
+ .put("rtf", "text.rtf")
+ .put("s", "sourcecode.asm")
+ .put("storyboard", "file.storyboard")
+ .put("strings", "text.plist.strings")
+ .put("tif", "image.tiff")
+ .put("tiff", "image.tiff")
+ .put("tcc", "sourcecode.cpp.cpp")
+ .put("ttf", "file")
+ .put("vsh", "sourcecode.glsl")
+ .put("xcassets", "folder.assetcatalog")
+ .put("xcconfig", "text.xcconfig")
+ .put("xcodeproj", "wrapper.pb-project")
+ .put("xcdatamodel", "wrapper.xcdatamodel")
+ .put("xcdatamodeld", "wrapper.xcdatamodeld")
+ .put("xctest", "wrapper.cfbundle")
+ .put("xib", "file.xib")
+ .put("y", "sourcecode.yacc")
+ .put("zip", "archive.zip")
+ .build();
+
+ /**
+ * Set of UTIs which only work as "lastKnownFileType" and not "explicitFileType"
+ * in a PBXFileReference.
+ *
+ * Yes, really. Because Xcode.
+ */
+ public static final ImmutableSet<String> EXPLICIT_FILE_TYPE_BROKEN_UTIS =
+ ImmutableSet.of("file.xib");
+
+ /**
+ * Multimap of Apple UTI (Uniform Type Identifier) to file extension(s).
+ */
+ public static final ImmutableMultimap<String, String> UTI_TO_FILE_EXTENSIONS;
+
+ static {
+ // Invert the map of (file extension -> UTI) pairs to
+ // (UTI -> [file extension 1, ...]) pairs.
+ ImmutableMultimap.Builder<String, String> builder = ImmutableMultimap.builder();
+ for (ImmutableMap.Entry<String, String> entry : FILE_EXTENSION_TO_UTI.entrySet()) {
+ builder.put(entry.getValue(), entry.getKey());
+ }
+ UTI_TO_FILE_EXTENSIONS = builder.build();
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/GidGenerator.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/GidGenerator.java
new file mode 100644
index 0000000000..03395a05ba
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/GidGenerator.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * Generator for Global ID (GID) which are present on every xcode project object.
+ *
+ * The GID is a 96 bit identifier that's unique on a per-project basis.
+ */
+public class GidGenerator {
+ private final Set<String> generatedAndReservedIds;
+
+ public GidGenerator(Set<String> reservedIds) {
+ generatedAndReservedIds = Sets.newHashSet(reservedIds);
+ }
+
+ /**
+ * Generate a stable GID based on the class name and hash of some object info.
+ *
+ * GIDs generated this way will be in the form of
+ * {@code <class-name-hash-32> <obj-hash-32> <counter-32>}
+ */
+ public String generateGid(String pbxClassName, int hash) {
+ int counter = 0;
+ String gid;
+ do {
+ gid = String.format("%08X%08X%08X", pbxClassName.hashCode(), hash, counter++);
+ } while (generatedAndReservedIds.contains(gid));
+ generatedAndReservedIds.add(gid);
+ return gid;
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/XcodeprojSerializer.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/XcodeprojSerializer.java
new file mode 100644
index 0000000000..b43081f90a
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/XcodeprojSerializer.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode;
+
+import com.dd.plist.NSArray;
+import com.dd.plist.NSDictionary;
+import com.dd.plist.NSObject;
+import com.dd.plist.NSString;
+import com.facebook.buck.log.Logger;
+import com.facebook.buck.apple.xcode.xcodeproj.PBXObject;
+import com.facebook.buck.apple.xcode.xcodeproj.PBXProject;
+
+import java.util.List;
+
+import javax.annotation.concurrent.NotThreadSafe;
+
+/**
+ * Serializer that handles conversion of an in-memory object graph representation of an xcode
+ * project (instances of {@link PBXObject}) into an Apple property list.
+ *
+ * Serialization proceeds from the root object, a ${link PBXProject} instance, to all of its
+ * referenced objects. Each object being visited calls back into this class ({@link #addField}) to
+ * populate the plist representation with its fields.
+ */
+@NotThreadSafe
+public class XcodeprojSerializer {
+ private static final Logger LOG = Logger.get(XcodeprojSerializer.class);
+
+ private final PBXProject rootObject;
+ private final NSDictionary objects;
+ private final GidGenerator gidGenerator;
+ private NSDictionary currentObject;
+
+ public XcodeprojSerializer(GidGenerator gidGenerator, PBXProject project) {
+ rootObject = project;
+ objects = new NSDictionary();
+ this.gidGenerator = gidGenerator;
+ }
+
+ /**
+ * Generate a plist serialization of project bound to this serializer.
+ */
+ public NSDictionary toPlist() {
+ serializeObject(rootObject);
+
+ NSDictionary root = new NSDictionary();
+ root.put("archiveVersion", "1");
+ root.put("classes", new NSDictionary());
+ root.put("objectVersion", "46");
+ root.put("objects", objects);
+ root.put("rootObject", rootObject.getGlobalID());
+
+ return root;
+ }
+
+ /**
+ * Serialize a {@link PBXObject} and its recursive descendants into the object dictionary.
+ *
+ * @return the GID of the serialized object
+ *
+ * @see PBXObject#serializeInto
+ */
+ private String serializeObject(PBXObject obj) {
+ if (obj.getGlobalID() == null) {
+ obj.setGlobalID(obj.generateGid(gidGenerator));
+ LOG.verbose("Set new object GID: %s", obj);
+ } else {
+ // Check that the object has already been serialized.
+ NSObject object = objects.get(obj.getGlobalID());
+ if (object != null) {
+ LOG.verbose("Object %s found, returning existing object %s", obj, object);
+ return obj.getGlobalID();
+ } else {
+ LOG.verbose("Object already had GID set: %s", obj);
+ }
+ }
+
+ // Save the existing object being deserialized.
+ NSDictionary stack = currentObject;
+
+ currentObject = new NSDictionary();
+ currentObject.put("isa", obj.isa());
+ obj.serializeInto(this);
+ objects.put(obj.getGlobalID(), currentObject);
+
+ // Restore the existing object being deserialized.
+ currentObject = stack;
+ return obj.getGlobalID();
+ }
+
+ public void addField(String name, PBXObject obj) {
+ if (obj != null) {
+ String gid = serializeObject(obj);
+ currentObject.put(name, gid);
+ }
+ }
+
+ public void addField(String name, int val) {
+ currentObject.put(name, val);
+ }
+
+ public void addField(String name, String val) {
+ if (val != null) {
+ currentObject.put(name, val);
+ }
+ }
+
+ public void addField(String name, boolean val) {
+ currentObject.put(name, val);
+ }
+
+ public void addField(String name, List<? extends PBXObject> objectList) {
+ NSArray array = new NSArray(objectList.size());
+ for (int i = 0; i < objectList.size(); i++) {
+ String gid = serializeObject(objectList.get(i));
+ array.setValue(i, new NSString(gid));
+ }
+ currentObject.put(name, array);
+ }
+
+ public void addField(String name, NSObject v) {
+ if (v != null) {
+ currentObject.put(name, v);
+ }
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXAggregateTarget.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXAggregateTarget.java
new file mode 100644
index 0000000000..1e6601004f
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXAggregateTarget.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Target backed by shell scripts or nothing (only specifying dependencies).
+ */
+public class PBXAggregateTarget extends PBXTarget {
+ public PBXAggregateTarget(String name, ProductType productType) {
+ super(name, productType);
+ }
+
+ @Override
+ public String isa() {
+ return "PBXAggregateTarget";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildFile.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildFile.java
new file mode 100644
index 0000000000..cdab5b64c7
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildFile.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.dd.plist.NSDictionary;
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * File referenced by a build phase, unique to each build phase.
+ *
+ * Contains a dictionary {@link #settings} which holds additional information to be interpreted by
+ * the particular phase referencing this object, e.g.:
+ *
+ * - {@link PBXHeadersBuildPhase } may read <code>{"ATTRIBUTES": ["Public"]}</code> and interpret
+ * the build file as a public (exported) header.
+ * - {@link PBXSourcesBuildPhase } may read <code>{"COMPILER_FLAGS": "-foo"}</code> and interpret
+ * that this file should be compiled with the additional flag {@code "-foo" }.
+ */
+public class PBXBuildFile extends PBXProjectItem {
+ private final PBXReference fileRef;
+ private Optional<NSDictionary> settings;
+
+ public PBXBuildFile(PBXReference fileRef) {
+ this.fileRef = Preconditions.checkNotNull(fileRef);
+ this.settings = Optional.absent();
+ }
+
+ public PBXReference getFileRef() {
+ return fileRef;
+ }
+
+ public Optional<NSDictionary> getSettings() {
+ return settings;
+ }
+
+ public void setSettings(Optional<NSDictionary> v) {
+ settings = v;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXBuildFile";
+ }
+
+ @Override
+ public int stableHash() {
+ return fileRef.stableHash();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("fileRef", fileRef);
+ if (settings.isPresent()) {
+ s.addField("settings", settings.get());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s fileRef=%s settings=%s", super.toString(), fileRef, settings);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildPhase.java
new file mode 100644
index 0000000000..96d0cd336a
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildPhase.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Superclass of build phases. Each build phase represents one step in building a target.
+ */
+public abstract class PBXBuildPhase extends PBXProjectItem {
+ private final List<PBXBuildFile> files;
+
+ public PBXBuildPhase() {
+ this.files = Lists.newArrayList();
+ }
+
+ public List<PBXBuildFile> getFiles() {
+ return files;
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("files", files);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildStyle.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildStyle.java
new file mode 100644
index 0000000000..be572d557c
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildStyle.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.dd.plist.NSDictionary;
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Preconditions;
+
+public class PBXBuildStyle extends PBXProjectItem {
+ private final String name;
+ private NSDictionary buildSettings;
+
+ public PBXBuildStyle(String name) {
+ this.name = Preconditions.checkNotNull(name);
+ this.buildSettings = new NSDictionary();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public NSDictionary getBuildSettings() {
+ return buildSettings;
+ }
+
+ public void setBuildSettings(NSDictionary buildSettings) {
+ this.buildSettings = buildSettings;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXBuildStyle";
+ }
+
+ @Override
+ public int stableHash() {
+ return name.hashCode();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("name", name);
+ s.addField("buildSettings", buildSettings);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainer.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainer.java
new file mode 100644
index 0000000000..6954f7ffed
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainer.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Superclass of all container types. This is here to reflect Xcode's object hierarchy, and does
+ * not implement any special functionality.
+ */
+public abstract class PBXContainer extends PBXObject {
+ @Override
+ public String isa() {
+ return "PBXContainer";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItem.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItem.java
new file mode 100644
index 0000000000..c182b8ad08
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItem.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+
+/**
+ * Superclass in Xcode's object hierarchy, has no non-structural functionality here.
+ */
+public abstract class PBXContainerItem extends PBXObject {
+
+ @Override
+ public String isa() {
+ return "PBXContainerItem";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItemProxy.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItemProxy.java
new file mode 100644
index 0000000000..72badae239
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXContainerItemProxy.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Preconditions;
+
+/**
+ * Reference to another object used by {@link PBXTargetDependency}. Can reference a remote file
+ * by specifying the {@link PBXFileReference} to the remote project file, and the GID of the object
+ * within that file.
+ */
+public class PBXContainerItemProxy extends PBXContainerItem {
+ public enum ProxyType {
+ TARGET_REFERENCE(1),
+ FILE_REFERENCE(2);
+
+ private final int intValue;
+ private ProxyType(int intValue) {
+ this.intValue = intValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+ }
+
+ private final PBXFileReference containerPortal;
+ private final String remoteGlobalIDString;
+ private final ProxyType proxyType;
+
+ public PBXContainerItemProxy(
+ PBXFileReference containerPortal,
+ String remoteGlobalIDString,
+ ProxyType proxyType) {
+ Preconditions.checkNotNull(containerPortal);
+ Preconditions.checkNotNull(remoteGlobalIDString);
+ Preconditions.checkNotNull(proxyType);
+ this.containerPortal = containerPortal;
+ this.remoteGlobalIDString = remoteGlobalIDString;
+ this.proxyType = proxyType;
+ }
+
+ public PBXFileReference getContainerPortal() {
+ return containerPortal;
+ }
+
+ public String getRemoteGlobalIDString() {
+ return remoteGlobalIDString;
+ }
+
+ public ProxyType getProxyType() {
+ return proxyType;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXContainerItemProxy";
+ }
+
+ @Override
+ public int stableHash() {
+ return remoteGlobalIDString.hashCode();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("containerPortal", containerPortal);
+ s.addField("remoteGlobalIDString", remoteGlobalIDString);
+ s.addField("proxyType", proxyType.getIntValue());
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXCopyFilesBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXCopyFilesBuildPhase.java
new file mode 100644
index 0000000000..fcf2ed5e1b
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXCopyFilesBuildPhase.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Preconditions;
+
+public class PBXCopyFilesBuildPhase extends PBXBuildPhase {
+ /**
+ * The prefix path, this does not use SourceTreePath and build variables but rather some sort of
+ * enum.
+ */
+ public enum Destination {
+ ABSOLUTE(0),
+ WRAPPER(1),
+ EXECUTABLES(6),
+ RESOURCES(7),
+ FRAMEWORKS(10),
+ SHARED_FRAMEWORKS(11),
+ SHARED_SUPPORT(12),
+ PLUGINS(13),
+ JAVA_RESOURCES(15),
+ PRODUCTS(16),
+ ;
+
+ private int value;
+
+ public int getValue() {
+ return value;
+ }
+
+ private Destination(int value) {
+ this.value = value;
+ }
+ }
+
+ /**
+ * Base path of destination folder.
+ */
+ private Destination dstSubfolderSpec;
+
+ /**
+ * Subdirectory under the destination folder.
+ */
+ private String path;
+
+ public PBXCopyFilesBuildPhase(Destination dstSubfolderSpec, String path) {
+ this.dstSubfolderSpec = Preconditions.checkNotNull(dstSubfolderSpec);
+ this.path = Preconditions.checkNotNull(path);
+ }
+
+ public Destination getDstSubfolderSpec() {
+ return dstSubfolderSpec;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXCopyFilesBuildPhase";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+ s.addField("dstSubfolderSpec", dstSubfolderSpec.getValue());
+ s.addField("dstPath", path);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFileReference.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFileReference.java
new file mode 100644
index 0000000000..50b9144309
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFileReference.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.FileTypes;
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Optional;
+import com.google.common.io.Files;
+
+/**
+ * Reference to a concrete file.
+ */
+public class PBXFileReference extends PBXReference {
+ private Optional<String> explicitFileType;
+ private Optional<String> lastKnownFileType;
+
+ public PBXFileReference(String name, String path, SourceTree sourceTree) {
+ super(name, path, sourceTree);
+
+ // this is necessary to prevent O(n^2) behavior in xcode project loading
+ String fileType = FileTypes.FILE_EXTENSION_TO_UTI.get(Files.getFileExtension(name));
+ if (FileTypes.EXPLICIT_FILE_TYPE_BROKEN_UTIS.contains(fileType)) {
+ explicitFileType = Optional.absent();
+ lastKnownFileType = Optional.of(fileType);
+ } else {
+ explicitFileType = Optional.fromNullable(fileType);
+ lastKnownFileType = Optional.absent();
+ }
+ }
+
+ public Optional<String> getExplicitFileType() {
+ return explicitFileType;
+ }
+
+ public void setExplicitFileType(Optional<String> explicitFileType) {
+ this.explicitFileType = explicitFileType;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXFileReference";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ if (explicitFileType.isPresent()) {
+ s.addField("explicitFileType", explicitFileType.get());
+ }
+
+ if (lastKnownFileType.isPresent()) {
+ s.addField("lastKnownFileType", lastKnownFileType.get());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "%s explicitFileType=%s",
+ super.toString(),
+ getExplicitFileType());
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFrameworksBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFrameworksBuildPhase.java
new file mode 100644
index 0000000000..be4b613bc1
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXFrameworksBuildPhase.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Build phase representing the linking step of a target. Contains references to libraries and
+ * system frameworks. In library targets, it may alter the include path.
+ */
+public class PBXFrameworksBuildPhase extends PBXBuildPhase {
+ @Override
+ public String isa() {
+ return "PBXFrameworksBuildPhase";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXGroup.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXGroup.java
new file mode 100644
index 0000000000..dc636b7969
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXGroup.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Lists;
+import com.google.common.base.Preconditions;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * A collection of files in Xcode's virtual filesystem hierarchy.
+ */
+public class PBXGroup extends PBXReference {
+ /**
+ * Method by which group contents will be sorted.
+ */
+ public enum SortPolicy {
+ /**
+ * By name, in default Java sort order.
+ */
+ BY_NAME,
+
+ /**
+ * Group contents will not be sorted, and will remain in the
+ * order they were added.
+ */
+ UNSORTED;
+ }
+
+ // Unfortunately, we can't determine this at constructor time, because CacheBuilder
+ // calls our constructor and it's not easy to pass arguments to it.
+ private SortPolicy sortPolicy;
+
+ private final List<PBXReference> children;
+
+ private final LoadingCache<String, PBXGroup> childGroupsByName;
+ private final LoadingCache<String, PBXVariantGroup> childVariantGroupsByName;
+ private final LoadingCache<SourceTreePath, PBXFileReference> fileReferencesBySourceTreePath;
+ private final LoadingCache<SourceTreePath, XCVersionGroup> childVersionGroupsBySourceTreePath;
+
+ public PBXGroup(String name, @Nullable String path, SourceTree sourceTree) {
+ super(name, path, sourceTree);
+
+ sortPolicy = SortPolicy.BY_NAME;
+ children = Lists.newArrayList();
+
+ childGroupsByName = CacheBuilder.newBuilder().build(
+ new CacheLoader<String, PBXGroup>() {
+ @Override
+ public PBXGroup load(String key) throws Exception {
+ PBXGroup group = new PBXGroup(key, null, SourceTree.GROUP);
+ children.add(group);
+ return group;
+ }
+ });
+
+ childVariantGroupsByName = CacheBuilder.newBuilder().build(
+ new CacheLoader<String, PBXVariantGroup>() {
+ @Override
+ public PBXVariantGroup load(String key) throws Exception {
+ PBXVariantGroup group = new PBXVariantGroup(key, null, SourceTree.GROUP);
+ children.add(group);
+ return group;
+ }
+ });
+
+ fileReferencesBySourceTreePath = CacheBuilder.newBuilder().build(
+ new CacheLoader<SourceTreePath, PBXFileReference>() {
+ @Override
+ public PBXFileReference load(SourceTreePath key) throws Exception {
+ PBXFileReference ref = new PBXFileReference(
+ key.getPath().getFileName().toString(),
+ key.getPath().toString(),
+ key.getSourceTree());
+ children.add(ref);
+ return ref;
+ }
+ });
+
+ childVersionGroupsBySourceTreePath = CacheBuilder.newBuilder().build(
+ new CacheLoader<SourceTreePath, XCVersionGroup>() {
+ @Override
+ public XCVersionGroup load(SourceTreePath key) throws Exception {
+ XCVersionGroup ref = new XCVersionGroup(
+ key.getPath().getFileName().toString(),
+ key.getPath().toString(),
+ key.getSourceTree());
+ children.add(ref);
+ return ref;
+ }
+ });
+ }
+
+ public PBXGroup getOrCreateChildGroupByName(String name) {
+ return childGroupsByName.getUnchecked(name);
+ }
+
+ public PBXVariantGroup getOrCreateChildVariantGroupByName(String name) {
+ return childVariantGroupsByName.getUnchecked(name);
+ }
+
+ public PBXFileReference getOrCreateFileReferenceBySourceTreePath(SourceTreePath sourceTreePath) {
+ return fileReferencesBySourceTreePath.getUnchecked(sourceTreePath);
+ }
+
+ public XCVersionGroup getOrCreateChildVersionGroupsBySourceTreePath(
+ SourceTreePath sourceTreePath) {
+ return childVersionGroupsBySourceTreePath.getUnchecked(sourceTreePath);
+ }
+
+ public List<PBXReference> getChildren() {
+ return children;
+ }
+
+ public void setSortPolicy(SortPolicy sortPolicy) {
+ this.sortPolicy = Preconditions.checkNotNull(sortPolicy);
+ }
+
+ public SortPolicy getSortPolicy() {
+ return sortPolicy;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXGroup";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ if (sortPolicy == SortPolicy.BY_NAME) {
+ Collections.sort(children, new Comparator<PBXReference>() {
+ @Override
+ public int compare(PBXReference o1, PBXReference o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ }
+
+ s.addField("children", children);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXHeadersBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXHeadersBuildPhase.java
new file mode 100644
index 0000000000..3793d2db38
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXHeadersBuildPhase.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Build phase that copies header files into the output headers directory. Does nothing for binary
+ * and test rules.
+ */
+public class PBXHeadersBuildPhase extends PBXBuildPhase {
+ @Override
+ public String isa() {
+ return "PBXHeadersBuildPhase";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXNativeTarget.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXNativeTarget.java
new file mode 100644
index 0000000000..a99c6b76c9
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXNativeTarget.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Concrete target type representing targets built by xcode itself, rather than an external build
+ * system.
+ */
+public class PBXNativeTarget extends PBXTarget {
+ public PBXNativeTarget(String name, ProductType productType) {
+ super(name, productType);
+ }
+
+ @Override
+ public String isa() {
+ return "PBXNativeTarget";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXObject.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXObject.java
new file mode 100644
index 0000000000..d665f7549c
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXObject.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.GidGenerator;
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+
+import javax.annotation.Nullable;
+
+public abstract class PBXObject {
+ @Nullable
+ private String globalID;
+
+ @Nullable
+ public String getGlobalID() {
+ return globalID;
+ }
+
+ public void setGlobalID(String gid) {
+ globalID = gid;
+ }
+
+ /**
+ * @return Type name of the serialized object.
+ */
+ public abstract String isa();
+
+ /**
+ * Populates the serializer with the fields of this object.
+ */
+ public void serializeInto(@SuppressWarnings("unused") XcodeprojSerializer serializer) {
+ }
+
+ /**
+ * This method is used to generate stable GIDs and must be stable for identical contents.
+ * Returning a constant value is ok but will make the generated project order-dependent.
+ */
+ public int stableHash() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s isa=%s gid=%s", super.toString(), isa(), getGlobalID());
+ }
+
+ /**
+ * Generate a stable GID.
+ */
+ public final String generateGid(GidGenerator generator) {
+ return generator.generateGid(isa(), stableHash());
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProject.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProject.java
new file mode 100644
index 0000000000..1eec5e9fdd
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProject.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
+import com.dd.plist.NSDictionary;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The root object representing the project itself.
+ */
+public class PBXProject extends PBXContainer {
+ private String name;
+ private final PBXGroup mainGroup;
+ private final List<PBXTarget> targets;
+ private final XCConfigurationList buildConfigurationList;
+ private final String compatibilityVersion;
+
+ public PBXProject(String name) {
+ this.name = Preconditions.checkNotNull(name);
+ this.mainGroup = new PBXGroup("mainGroup", null, PBXReference.SourceTree.GROUP);
+ this.targets = Lists.newArrayList();
+ this.buildConfigurationList = new XCConfigurationList();
+ this.compatibilityVersion = "Xcode 3.2";
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String v) {
+ name = v;
+ }
+
+ public PBXGroup getMainGroup() {
+ return mainGroup;
+ }
+
+ public List<PBXTarget> getTargets() {
+ return targets;
+ }
+
+ public XCConfigurationList getBuildConfigurationList() {
+ return buildConfigurationList;
+ }
+
+ public String getCompatibilityVersion() {
+ return compatibilityVersion;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXProject";
+ }
+
+ @Override
+ public int stableHash() {
+ return name.hashCode();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("mainGroup", mainGroup);
+
+ Collections.sort(targets, Ordering.natural().onResultOf(new Function<PBXTarget, String>() {
+ @Override
+ public String apply(PBXTarget input) {
+ return input.getName();
+ }
+ }));
+ s.addField("targets", targets);
+ s.addField("buildConfigurationList", buildConfigurationList);
+ s.addField("compatibilityVersion", compatibilityVersion);
+
+ NSDictionary d = new NSDictionary();
+ d.put("LastUpgradeCheck", "0610");
+
+ s.addField("attributes", d);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProjectItem.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProjectItem.java
new file mode 100644
index 0000000000..2b9003427b
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXProjectItem.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+public abstract class PBXProjectItem extends PBXContainerItem {
+ @Override
+ public String isa() {
+ return "PBXProjectItem";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXReference.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXReference.java
new file mode 100644
index 0000000000..a7bed6d35b
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXReference.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+import javax.annotation.Nullable;
+
+/**
+ * Superclass for file, directories, and groups. Xcode's virtual file hierarchy are made of these
+ * objects.
+ */
+public class PBXReference extends PBXContainerItem {
+ public enum SourceTree {
+ /**
+ * Relative to the path of the group containing this.
+ */
+ GROUP("<group>"),
+
+ /**
+ * Absolute system path.
+ */
+ ABSOLUTE("<absolute>"),
+ /**
+ * Relative to the build setting {@code BUILT_PRODUCTS_DIR}.
+ */
+ BUILT_PRODUCTS_DIR("BUILT_PRODUCTS_DIR"),
+
+ /**
+ * Relative to the build setting {@code SDKROOT}.
+ */
+ SDKROOT("SDKROOT"),
+
+ /**
+ * Relative to the directory containing the project file {@code SOURCE_ROOT}.
+ */
+ SOURCE_ROOT("SOURCE_ROOT"),
+
+ /**
+ * Relative to the Developer content directory inside the Xcode application
+ * (e.g. {@code /Applications/Xcode.app/Contents/Developer}).
+ */
+ DEVELOPER_DIR("DEVELOPER_DIR"),
+ ;
+
+ private final String rep;
+
+ SourceTree(String str) {
+ rep = str;
+ }
+
+ @Override
+ public String toString() {
+ return rep;
+ }
+
+ /**
+ * Return a sourceTree given a build setting that is typically used as a source tree prefix.
+ *
+ * The build setting may be optionally prefixed by '$' which will be stripped.
+ */
+ public static Optional<SourceTree> fromBuildSetting(String buildSetting) {
+ switch (CharMatcher.is('$').trimLeadingFrom(buildSetting)) {
+ case "BUILT_PRODUCTS_DIR":
+ return Optional.of(BUILT_PRODUCTS_DIR);
+ case "SDKROOT":
+ return Optional.of(SDKROOT);
+ case "SOURCE_ROOT":
+ return Optional.of(SOURCE_ROOT);
+ case "DEVELOPER_DIR":
+ return Optional.of(DEVELOPER_DIR);
+ default:
+ return Optional.absent();
+ }
+ }
+ }
+
+ private final String name;
+ @Nullable private String path;
+
+ /**
+ * The "base" path of the reference. The absolute path is resolved by prepending the resolved
+ * base path.
+ */
+ private SourceTree sourceTree;
+
+ public PBXReference(String name, @Nullable String path, SourceTree sourceTree) {
+ this.name = Preconditions.checkNotNull(name);
+ this.path = path;
+ this.sourceTree = Preconditions.checkNotNull(sourceTree);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Nullable
+ public String getPath() {
+ return path;
+ }
+ public void setPath(String v) {
+ path = v;
+ }
+ public SourceTree getSourceTree() {
+ return sourceTree;
+ }
+ public void setSourceTree(SourceTree v) {
+ sourceTree = v;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXReference";
+ }
+
+ @Override
+ public int stableHash() {
+ return name.hashCode();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("name", name);
+ if (path != null) {
+ s.addField("path", path);
+ }
+ s.addField("sourceTree", sourceTree.toString());
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "%s name=%s path=%s sourceTree=%s",
+ super.toString(),
+ getName(),
+ getPath(),
+ getSourceTree());
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXResourcesBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXResourcesBuildPhase.java
new file mode 100644
index 0000000000..e0fd771fa2
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXResourcesBuildPhase.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Lists the files to be copied into the output resources directory for the containing
+ * {@link PBXTarget}. Has no effect in library rules.
+ *
+ * A target should contain at most one of this build phase.
+ */
+public class PBXResourcesBuildPhase extends PBXBuildPhase {
+ @Override
+ public String isa() {
+ return "PBXResourcesBuildPhase";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXShellScriptBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXShellScriptBuildPhase.java
new file mode 100644
index 0000000000..7192826a5c
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXShellScriptBuildPhase.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2014-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.dd.plist.NSArray;
+import com.dd.plist.NSString;
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Build phase which represents running a shell script.
+ */
+public class PBXShellScriptBuildPhase extends PBXBuildPhase {
+ private List<String> inputPaths;
+ private List<String> outputPaths;
+ @Nullable private String shellPath;
+ @Nullable private String shellScript;
+
+ private static final NSString DEFAULT_SHELL_PATH = new NSString("/bin/sh");
+ private static final NSString DEFAULT_SHELL_SCRIPT = new NSString("");
+
+ public PBXShellScriptBuildPhase() {
+ this.inputPaths = Lists.newArrayList();
+ this.outputPaths = Lists.newArrayList();
+ }
+
+ @Override
+ public String isa() {
+ return "PBXShellScriptBuildPhase";
+ }
+
+ /**
+ * Returns the list (possibly empty) of files passed as input to the shell script.
+ * May not be actual paths, because they can have variable interpolations.
+ */
+ public List<String> getInputPaths() {
+ return inputPaths;
+ }
+
+ /**
+ * Returns the list (possibly empty) of files created as output of the shell script.
+ * May not be actual paths, because they can have variable interpolations.
+ */
+ public List<String> getOutputPaths() {
+ return outputPaths;
+ }
+
+ /**
+ * Returns the path to the shell under which the script is to be executed.
+ * Defaults to "/bin/sh".
+ */
+ @Nullable
+ public String getShellPath() {
+ return shellPath;
+ }
+
+ /**
+ * Sets the path to the shell under which the script is to be executed.
+ */
+ public void setShellPath(String shellPath) {
+ this.shellPath = shellPath;
+ }
+
+ /**
+ * Gets the contents of the shell script to execute under the shell
+ * returned by {@link #getShellPath()}.
+ */
+ @Nullable
+ public String getShellScript() {
+ return shellScript;
+ }
+
+ /**
+ * Sets the contents of the script to execute.
+ */
+ public void setShellScript(String shellScript) {
+ this.shellScript = shellScript;
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ NSArray inputPathsArray = new NSArray(inputPaths.size());
+ for (int i = 0; i < inputPaths.size(); i++) {
+ inputPathsArray.setValue(i, new NSString(inputPaths.get(i)));
+ }
+ s.addField("inputPaths", inputPathsArray);
+
+ NSArray outputPathsArray = new NSArray(outputPaths.size());
+ for (int i = 0; i < outputPaths.size(); i++) {
+ outputPathsArray.setValue(i, new NSString(outputPaths.get(i)));
+ }
+ s.addField("outputPaths", outputPathsArray);
+
+ NSString shellPathString;
+ if (shellPath == null) {
+ shellPathString = DEFAULT_SHELL_PATH;
+ } else {
+ shellPathString = new NSString(shellPath);
+ }
+ s.addField("shellPath", shellPathString);
+
+ NSString shellScriptString;
+ if (shellScript == null) {
+ shellScriptString = DEFAULT_SHELL_SCRIPT;
+ } else {
+ shellScriptString = new NSString(shellScript);
+ }
+ s.addField("shellScript", shellScriptString);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXSourcesBuildPhase.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXSourcesBuildPhase.java
new file mode 100644
index 0000000000..8a43dc7884
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXSourcesBuildPhase.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+/**
+ * Lists the files to be compiled for the containing {@link PBXTarget}.
+ *
+ * A target should contain at most one of this build phase.
+ */
+public class PBXSourcesBuildPhase extends PBXBuildPhase {
+ @Override
+ public String isa() {
+ return "PBXSourcesBuildPhase";
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTarget.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTarget.java
new file mode 100644
index 0000000000..0dc599832c
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTarget.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Information for building a specific artifact (a library, binary, or test).
+ */
+public abstract class PBXTarget extends PBXProjectItem {
+ public enum ProductType {
+ STATIC_LIBRARY("com.apple.product-type.library.static"),
+ DYNAMIC_LIBRARY("com.apple.product-type.library.dynamic"),
+ TOOL("com.apple.product-type.tool"),
+ BUNDLE("com.apple.product-type.bundle"),
+ FRAMEWORK("com.apple.product-type.framework"),
+ STATIC_FRAMEWORK("com.apple.product-type.framework.static"),
+ APPLICATION("com.apple.product-type.application"),
+ UNIT_TEST("com.apple.product-type.bundle.unit-test"),
+ IN_APP_PURCHASE_CONTENT("com.apple.product-type.in-app-purchase-content"),
+ APP_EXTENSION("com.apple.product-type.app-extension");
+
+ public final String identifier;
+ private ProductType(String identifier) {
+ this.identifier = identifier;
+ }
+
+ @Override
+ public String toString() {
+ return identifier;
+ }
+ }
+
+ private final String name;
+ private final ProductType productType;
+ private final List<PBXTargetDependency> dependencies;
+ private final List<PBXBuildPhase> buildPhases;
+ private final XCConfigurationList buildConfigurationList;
+ @Nullable private String productName;
+ @Nullable private PBXFileReference productReference;
+
+ public PBXTarget(String name, ProductType productType) {
+ this.name = Preconditions.checkNotNull(name);
+ this.productType = Preconditions.checkNotNull(productType);
+ this.dependencies = Lists.newArrayList();
+ this.buildPhases = Lists.newArrayList();
+ this.buildConfigurationList = new XCConfigurationList();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ProductType getProductType() {
+ return productType;
+ }
+
+ public List<PBXTargetDependency> getDependencies() {
+ return dependencies;
+ }
+
+ public List<PBXBuildPhase> getBuildPhases() {
+ return buildPhases;
+ }
+
+ public XCConfigurationList getBuildConfigurationList() {
+ return buildConfigurationList;
+ }
+
+ @Nullable
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ @Nullable
+ public PBXFileReference getProductReference() {
+ return productReference;
+ }
+
+ public void setProductReference(PBXFileReference v) {
+ productReference = v;
+ }
+
+ @Override
+ public String isa() {
+ return "PBXTarget";
+ }
+
+ @Override
+ public int stableHash() {
+ return name.hashCode();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("name", name);
+ if (productType != null) {
+ s.addField("productType", productType.toString());
+ }
+ if (productName != null) {
+ s.addField("productName", productName);
+ }
+ if (productReference != null) {
+ s.addField("productReference", productReference);
+ }
+ s.addField("dependencies", dependencies);
+ s.addField("buildPhases", buildPhases);
+ if (buildConfigurationList != null) {
+ s.addField("buildConfigurationList", buildConfigurationList);
+ }
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTargetDependency.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTargetDependency.java
new file mode 100644
index 0000000000..164e196248
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXTargetDependency.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Preconditions;
+
+/**
+ * Element of the {@link PBXTarget#dependencies}. Represents a dependency of one target upon another
+ * target.
+ */
+public class PBXTargetDependency extends PBXProjectItem {
+ private final PBXContainerItemProxy targetProxy;
+
+ public PBXTargetDependency(PBXContainerItemProxy targetProxy) {
+ this.targetProxy = Preconditions.checkNotNull(targetProxy);
+ }
+
+ @Override
+ public String isa() {
+ return "PBXTargetDependency";
+ }
+
+ public PBXContainerItemProxy getTargetProxy() {
+ return targetProxy;
+ }
+
+ @Override
+ public int stableHash() {
+ return targetProxy.stableHash();
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ s.addField("targetProxy", getTargetProxy());
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXVariantGroup.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXVariantGroup.java
new file mode 100644
index 0000000000..b1e351aeb9
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/PBXVariantGroup.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+
+public class PBXVariantGroup extends PBXGroup {
+
+ private final LoadingCache<VirtualNameAndSourceTreePath, PBXFileReference>
+ variantFileReferencesByNameAndSourceTreePath;
+
+ public PBXVariantGroup(String name, @Nullable String path, SourceTree sourceTree) {
+ super(name, path, sourceTree);
+
+ variantFileReferencesByNameAndSourceTreePath = CacheBuilder.newBuilder().build(
+ new CacheLoader<VirtualNameAndSourceTreePath, PBXFileReference>() {
+ @Override
+ public PBXFileReference load(VirtualNameAndSourceTreePath key) throws Exception {
+ PBXFileReference ref = new PBXFileReference(
+ key.getVirtualName(),
+ key.getSourceTreePath().getPath().toString(),
+ key.getSourceTreePath().getSourceTree());
+ getChildren().add(ref);
+ return ref;
+ }
+ });
+ }
+
+ public PBXFileReference getOrCreateVariantFileReferenceByNameAndSourceTreePath(
+ String virtualName,
+ SourceTreePath sourceTreePath) {
+ VirtualNameAndSourceTreePath key =
+ new VirtualNameAndSourceTreePath(virtualName, sourceTreePath);
+ return variantFileReferencesByNameAndSourceTreePath.getUnchecked(key);
+ }
+
+ @Override
+ public String isa() {
+ return "PBXVariantGroup";
+ }
+
+ private static class VirtualNameAndSourceTreePath {
+ private final String virtualName;
+ private final SourceTreePath sourceTreePath;
+
+ public VirtualNameAndSourceTreePath(String virtualName, SourceTreePath sourceTreePath) {
+ this.virtualName = Preconditions.checkNotNull(virtualName);
+ this.sourceTreePath = Preconditions.checkNotNull(sourceTreePath);
+ }
+
+ public String getVirtualName() {
+ return virtualName;
+ }
+
+ public SourceTreePath getSourceTreePath() {
+ return sourceTreePath;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof VirtualNameAndSourceTreePath)) {
+ return false;
+ }
+
+ VirtualNameAndSourceTreePath that = (VirtualNameAndSourceTreePath) other;
+ return Objects.equals(this.virtualName, that.virtualName) &&
+ Objects.equals(this.sourceTreePath, that.sourceTreePath);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(virtualName, sourceTreePath);
+ }
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/SourceTreePath.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/SourceTreePath.java
new file mode 100644
index 0000000000..dc49f76bb8
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/SourceTreePath.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.google.common.base.Preconditions;
+
+import java.nio.file.Path;
+import java.util.Objects;
+
+/**
+ * Utility class representing a tuple of (SourceTree, Path) used for uniquely describing a file
+ * reference in a group.
+ */
+public class SourceTreePath {
+ private final PBXReference.SourceTree sourceTree;
+ private final Path path;
+
+ public SourceTreePath(PBXReference.SourceTree sourceTree, Path path) {
+ this.sourceTree = Preconditions.checkNotNull(sourceTree);
+ Preconditions.checkState(
+ path != null && path.toString().length() > 0,
+ "A path to a file cannot be null or empty");
+ path = path.normalize();
+ Preconditions.checkState(path.toString().length() > 0, "A path to a file cannot be empty");
+ this.path = path;
+ }
+
+ public PBXReference.SourceTree getSourceTree() {
+ return sourceTree;
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sourceTree, path);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !(other instanceof SourceTreePath)) {
+ return false;
+ }
+
+ SourceTreePath that = (SourceTreePath) other;
+ return Objects.equals(this.sourceTree, that.sourceTree) &&
+ Objects.equals(this.path, that.path);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCBuildConfiguration.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCBuildConfiguration.java
new file mode 100644
index 0000000000..f55ccfc933
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCBuildConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import javax.annotation.Nullable;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+
+/**
+ * Build configuration containing a file reference ton an xcconfig file and additional inline
+ * settings.
+ */
+public class XCBuildConfiguration extends PBXBuildStyle {
+ @Nullable private PBXFileReference baseConfigurationReference;
+
+ public XCBuildConfiguration(String name) {
+ super(name);
+ }
+
+ @Nullable
+ public PBXFileReference getBaseConfigurationReference() {
+ return baseConfigurationReference;
+ }
+ public void setBaseConfigurationReference(PBXFileReference v) {
+ baseConfigurationReference = v;
+ }
+
+ @Override
+ public String isa() {
+ return "XCBuildConfiguration";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ if (baseConfigurationReference != null) {
+ s.addField("baseConfigurationReference", baseConfigurationReference);
+ }
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCConfigurationList.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCConfigurationList.java
new file mode 100644
index 0000000000..048ffa7aeb
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCConfigurationList.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Lists;
+
+import java.util.Comparator;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * List of build configurations.
+ */
+public class XCConfigurationList extends PBXProjectItem {
+ private List<XCBuildConfiguration> buildConfigurations;
+ private Optional<String> defaultConfigurationName;
+ private boolean defaultConfigurationIsVisible;
+
+ private final LoadingCache<String, XCBuildConfiguration> buildConfigurationsByName;
+
+ public XCConfigurationList() {
+ buildConfigurations = Lists.newArrayList();
+ defaultConfigurationName = Optional.absent();
+ defaultConfigurationIsVisible = false;
+
+ buildConfigurationsByName = CacheBuilder.newBuilder().build(
+ new CacheLoader<String, XCBuildConfiguration>() {
+ @Override
+ public XCBuildConfiguration load(String key) throws Exception {
+ XCBuildConfiguration configuration = new XCBuildConfiguration(key);
+ buildConfigurations.add(configuration);
+ return configuration;
+ }
+ });
+ }
+
+ public LoadingCache<String, XCBuildConfiguration> getBuildConfigurationsByName() {
+ return buildConfigurationsByName;
+ }
+
+ @Override
+ public String isa() {
+ return "XCConfigurationList";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ Collections.sort(buildConfigurations, new Comparator<XCBuildConfiguration>() {
+ @Override
+ public int compare(XCBuildConfiguration o1, XCBuildConfiguration o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ s.addField("buildConfigurations", buildConfigurations);
+
+ if (defaultConfigurationName.isPresent()) {
+ s.addField("defaultConfigurationName", defaultConfigurationName.get());
+ }
+ s.addField("defaultConfigurationIsVisible", defaultConfigurationIsVisible);
+ }
+}
diff --git a/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCVersionGroup.java b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCVersionGroup.java
new file mode 100644
index 0000000000..acd8458a97
--- /dev/null
+++ b/third_party/java/buck-ios-support/java/com/facebook/buck/apple/xcode/xcodeproj/XCVersionGroup.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2013-present Facebook, Inc.
+ *
+ * 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.facebook.buck.apple.xcode.xcodeproj;
+
+import com.facebook.buck.apple.xcode.XcodeprojSerializer;
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class XCVersionGroup extends PBXReference {
+ private static final ImmutableMap<String, String> FILE_EXTENSION_TO_UTI = ImmutableMap.of(
+ "xcdatamodeld", "wrapper.xcdatamodel");
+
+ private Optional<PBXFileReference> currentVersion;
+
+ private final List<PBXFileReference> children;
+
+ private final LoadingCache<SourceTreePath, PBXFileReference> fileReferencesBySourceTreePath;
+
+ public XCVersionGroup(String name, String path, SourceTree sourceTree) {
+ super(name, path, sourceTree);
+ children = Lists.newArrayList();
+
+ fileReferencesBySourceTreePath = CacheBuilder.newBuilder().build(
+ new CacheLoader<SourceTreePath, PBXFileReference>() {
+ @Override
+ public PBXFileReference load(SourceTreePath key) throws Exception {
+ PBXFileReference ref = new PBXFileReference(
+ key.getPath().getFileName().toString(),
+ key.getPath().toString(),
+ key.getSourceTree());
+ children.add(ref);
+ return ref;
+ }
+ });
+
+ currentVersion = Optional.absent();
+ }
+
+ /**
+ * The file type of the version group, which is the type of each file. If the current version is
+ * set, then this method returns the type of the item that is the current version. Otherwise, it
+ * attempts to autodetect the type based on the name, or {@link Optional#absent()} if it could
+ * not be autodetected.
+ */
+ public Optional<String> getVersionGroupType() {
+ if (currentVersion.isPresent()) {
+ return currentVersion.get().getExplicitFileType();
+ }
+ return Optional.fromNullable(FILE_EXTENSION_TO_UTI.get(Files.getFileExtension(getName())));
+ }
+
+ public Optional<PBXFileReference> getCurrentVersion() { return currentVersion; }
+
+ public void setCurrentVersion(Optional<PBXFileReference> v) { currentVersion = v; }
+
+ public List<PBXFileReference> getChildren() {
+ return children;
+ }
+
+ public PBXFileReference getOrCreateFileReferenceBySourceTreePath(SourceTreePath sourceTreePath) {
+ return fileReferencesBySourceTreePath.getUnchecked(sourceTreePath);
+ }
+
+ @Override
+ public String isa() {
+ return "XCVersionGroup";
+ }
+
+ @Override
+ public void serializeInto(XcodeprojSerializer s) {
+ super.serializeInto(s);
+
+ Collections.sort(children, new Comparator<PBXReference>() {
+ @Override
+ public int compare(PBXReference o1, PBXReference o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ s.addField("children", children);
+
+
+ if (currentVersion.isPresent()) {
+ s.addField("currentVersion", currentVersion.get());
+ }
+
+ Optional<String> versionGroupType = getVersionGroupType();
+ if (versionGroupType.isPresent()) {
+ s.addField("versionGroupType", versionGroupType.get());
+ }
+ }
+}