diff options
author | Han-Wen Nienhuys <hanwen@google.com> | 2015-02-25 16:45:20 +0100 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@google.com> | 2015-02-25 16:45:20 +0100 |
commit | d08b27fa9701fecfdb69e1b0d1ac2459efc2129b (patch) | |
tree | 5d50963026239ca5aebfb47ea5b8db7e814e57c8 /third_party/java/buck-ios-support |
Update from Google.
--
MOE_MIGRATED_REVID=85702957
Diffstat (limited to 'third_party/java/buck-ios-support')
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()); + } + } +} |