Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1706)

Side by Side Diff: pylib/gyp/xcodeproj_file.py

Issue 739303003: Cleanup pylint errors (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: Fix mac Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pylib/gyp/xcode_emulation.py ('k') | test/lib/TestWin.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Xcode project file generator. 5 """Xcode project file generator.
6 6
7 This module is both an Xcode project file generator and a documentation of the 7 This module is both an Xcode project file generator and a documentation of the
8 Xcode project file format. Knowledge of the project file format was gained 8 Xcode project file format. Knowledge of the project file format was gained
9 based on extensive experience with Xcode, and by making changes to projects in 9 based on extensive experience with Xcode, and by making changes to projects in
10 Xcode.app and observing the resultant changes in the associated project files. 10 Xcode.app and observing the resultant changes in the associated project files.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 # Strings that match this pattern are quoted regardless of what _unquoted says. 166 # Strings that match this pattern are quoted regardless of what _unquoted says.
167 # Oddly, Xcode will quote any string with a run of three or more underscores. 167 # Oddly, Xcode will quote any string with a run of three or more underscores.
168 _quoted = re.compile('___') 168 _quoted = re.compile('___')
169 169
170 # This pattern should match any character that needs to be escaped by 170 # This pattern should match any character that needs to be escaped by
171 # XCObject._EncodeString. See that function. 171 # XCObject._EncodeString. See that function.
172 _escaped = re.compile('[\\\\"]|[\x00-\x1f]') 172 _escaped = re.compile('[\\\\"]|[\x00-\x1f]')
173 173
174 174
175 # Used by SourceTreeAndPathFromPath 175 # Used by SourceTreeAndPathFromPath
176 _path_leading_variable = re.compile('^\$\((.*?)\)(/(.*))?$') 176 _path_leading_variable = re.compile(r'^\$\((.*?)\)(/(.*))?$')
177 177
178 def SourceTreeAndPathFromPath(input_path): 178 def SourceTreeAndPathFromPath(input_path):
179 """Given input_path, returns a tuple with sourceTree and path values. 179 """Given input_path, returns a tuple with sourceTree and path values.
180 180
181 Examples: 181 Examples:
182 input_path (source_tree, output_path) 182 input_path (source_tree, output_path)
183 '$(VAR)/path' ('VAR', 'path') 183 '$(VAR)/path' ('VAR', 'path')
184 '$(VAR)' ('VAR', None) 184 '$(VAR)' ('VAR', None)
185 'path' (None, 'path') 185 'path' (None, 'path')
186 """ 186 """
187 187
188 source_group_match = _path_leading_variable.match(input_path) 188 source_group_match = _path_leading_variable.match(input_path)
189 if source_group_match: 189 if source_group_match:
190 source_tree = source_group_match.group(1) 190 source_tree = source_group_match.group(1)
191 output_path = source_group_match.group(3) # This may be None. 191 output_path = source_group_match.group(3) # This may be None.
192 else: 192 else:
193 source_tree = None 193 source_tree = None
194 output_path = input_path 194 output_path = input_path
195 195
196 return (source_tree, output_path) 196 return (source_tree, output_path)
197 197
198 def ConvertVariablesToShellSyntax(input_string): 198 def ConvertVariablesToShellSyntax(input_string):
199 return re.sub('\$\((.*?)\)', '${\\1}', input_string) 199 return re.sub(r'\$\((.*?)\)', '${\\1}', input_string)
200 200
201 class XCObject(object): 201 class XCObject(object):
202 """The abstract base of all class types used in Xcode project files. 202 """The abstract base of all class types used in Xcode project files.
203 203
204 Class variables: 204 Class variables:
205 _schema: A dictionary defining the properties of this class. The keys to 205 _schema: A dictionary defining the properties of this class. The keys to
206 _schema are string property keys as used in project files. Values 206 _schema are string property keys as used in project files. Values
207 are a list of four or five elements: 207 are a list of four or five elements:
208 [ is_list, property_type, is_strong, is_required, default ] 208 [ is_list, property_type, is_strong, is_required, default ]
209 is_list: True if the property described is a list, as opposed 209 is_list: True if the property described is a list, as opposed
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 that._properties[key] = [] 334 that._properties[key] = []
335 for item in value: 335 for item in value:
336 new_item = item.Copy() 336 new_item = item.Copy()
337 new_item.parent = that 337 new_item.parent = that
338 that._properties[key].append(new_item) 338 that._properties[key].append(new_item)
339 else: 339 else:
340 that._properties[key] = value[:] 340 that._properties[key] = value[:]
341 elif isinstance(value, dict): 341 elif isinstance(value, dict):
342 # dicts are never strong. 342 # dicts are never strong.
343 if is_strong: 343 if is_strong:
344 raise TypeError, 'Strong dict for key ' + key + ' in ' + \ 344 raise TypeError('Strong dict for key ' + key + ' in ' + \
345 self.__class__.__name__ 345 self.__class__.__name__)
346 else: 346 else:
347 that._properties[key] = value.copy() 347 that._properties[key] = value.copy()
348 else: 348 else:
349 raise TypeError, 'Unexpected type ' + value.__class__.__name__ + \ 349 raise TypeError('Unexpected type ' + value.__class__.__name__ + \
350 ' for key ' + key + ' in ' + self.__class__.__name__ 350 ' for key ' + key + ' in ' + self.__class__.__name__)
351 351
352 return that 352 return that
353 353
354 def Name(self): 354 def Name(self):
355 """Return the name corresponding to an object. 355 """Return the name corresponding to an object.
356 356
357 Not all objects necessarily need to be nameable, and not all that do have 357 Not all objects necessarily need to be nameable, and not all that do have
358 a "name" property. Override as needed. 358 a "name" property. Override as needed.
359 """ 359 """
360 360
361 # If the schema indicates that "name" is required, try to access the 361 # If the schema indicates that "name" is required, try to access the
362 # property even if it doesn't exist. This will result in a KeyError 362 # property even if it doesn't exist. This will result in a KeyError
363 # being raised for the property that should be present, which seems more 363 # being raised for the property that should be present, which seems more
364 # appropriate than NotImplementedError in this case. 364 # appropriate than NotImplementedError in this case.
365 if 'name' in self._properties or \ 365 if 'name' in self._properties or \
366 ('name' in self._schema and self._schema['name'][3]): 366 ('name' in self._schema and self._schema['name'][3]):
367 return self._properties['name'] 367 return self._properties['name']
368 368
369 raise NotImplementedError, \ 369 raise NotImplementedError(self.__class__.__name__ + ' must implement Name')
370 self.__class__.__name__ + ' must implement Name'
371 370
372 def Comment(self): 371 def Comment(self):
373 """Return a comment string for the object. 372 """Return a comment string for the object.
374 373
375 Most objects just use their name as the comment, but PBXProject uses 374 Most objects just use their name as the comment, but PBXProject uses
376 different values. 375 different values.
377 376
378 The returned comment is not escaped and does not have any comment marker 377 The returned comment is not escaped and does not have any comment marker
379 strings applied to it. 378 strings applied to it.
380 """ 379 """
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 458
460 def EnsureNoIDCollisions(self): 459 def EnsureNoIDCollisions(self):
461 """Verifies that no two objects have the same ID. Checks all descendants. 460 """Verifies that no two objects have the same ID. Checks all descendants.
462 """ 461 """
463 462
464 ids = {} 463 ids = {}
465 descendants = self.Descendants() 464 descendants = self.Descendants()
466 for descendant in descendants: 465 for descendant in descendants:
467 if descendant.id in ids: 466 if descendant.id in ids:
468 other = ids[descendant.id] 467 other = ids[descendant.id]
469 raise KeyError, \ 468 raise KeyError(
470 'Duplicate ID %s, objects "%s" and "%s" in "%s"' % \ 469 'Duplicate ID %s, objects "%s" and "%s" in "%s"' % \
471 (descendant.id, str(descendant._properties), 470 (descendant.id, str(descendant._properties),
472 str(other._properties), self._properties['rootObject'].Name()) 471 str(other._properties), self._properties['rootObject'].Name()))
473 ids[descendant.id] = descendant 472 ids[descendant.id] = descendant
474 473
475 def Children(self): 474 def Children(self):
476 """Returns a list of all of this object's owned (strong) children.""" 475 """Returns a list of all of this object's owned (strong) children."""
477 476
478 children = [] 477 children = []
479 for property, attributes in self._schema.iteritems(): 478 for property, attributes in self._schema.iteritems():
480 (is_list, property_type, is_strong) = attributes[0:3] 479 (is_list, property_type, is_strong) = attributes[0:3]
481 if is_strong and property in self._properties: 480 if is_strong and property in self._properties:
482 if not is_list: 481 if not is_list:
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 printable += end_tabs + ')' 622 printable += end_tabs + ')'
624 elif isinstance(value, dict): 623 elif isinstance(value, dict):
625 printable = '{' + sep 624 printable = '{' + sep
626 for item_key, item_value in sorted(value.iteritems()): 625 for item_key, item_value in sorted(value.iteritems()):
627 printable += element_tabs + \ 626 printable += element_tabs + \
628 self._XCPrintableValue(tabs + 1, item_key, flatten_list) + ' = ' + \ 627 self._XCPrintableValue(tabs + 1, item_key, flatten_list) + ' = ' + \
629 self._XCPrintableValue(tabs + 1, item_value, flatten_list) + ';' + \ 628 self._XCPrintableValue(tabs + 1, item_value, flatten_list) + ';' + \
630 sep 629 sep
631 printable += end_tabs + '}' 630 printable += end_tabs + '}'
632 else: 631 else:
633 raise TypeError, "Can't make " + value.__class__.__name__ + ' printable' 632 raise TypeError("Can't make " + value.__class__.__name__ + ' printable')
634 633
635 if comment != None: 634 if comment != None:
636 printable += ' ' + self._EncodeComment(comment) 635 printable += ' ' + self._EncodeComment(comment)
637 636
638 return printable 637 return printable
639 638
640 def _XCKVPrint(self, file, tabs, key, value): 639 def _XCKVPrint(self, file, tabs, key, value):
641 """Prints a key and value, members of an XCObject's _properties dictionary, 640 """Prints a key and value, members of an XCObject's _properties dictionary,
642 to file. 641 to file.
643 642
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 strong-owned XCObjects in lists will be copied instead of having their 748 strong-owned XCObjects in lists will be copied instead of having their
750 references added. 749 references added.
751 """ 750 """
752 751
753 if properties is None: 752 if properties is None:
754 return 753 return
755 754
756 for property, value in properties.iteritems(): 755 for property, value in properties.iteritems():
757 # Make sure the property is in the schema. 756 # Make sure the property is in the schema.
758 if not property in self._schema: 757 if not property in self._schema:
759 raise KeyError, property + ' not in ' + self.__class__.__name__ 758 raise KeyError(property + ' not in ' + self.__class__.__name__)
760 759
761 # Make sure the property conforms to the schema. 760 # Make sure the property conforms to the schema.
762 (is_list, property_type, is_strong) = self._schema[property][0:3] 761 (is_list, property_type, is_strong) = self._schema[property][0:3]
763 if is_list: 762 if is_list:
764 if value.__class__ != list: 763 if value.__class__ != list:
765 raise TypeError, \ 764 raise TypeError(
766 property + ' of ' + self.__class__.__name__ + \ 765 property + ' of ' + self.__class__.__name__ + \
767 ' must be list, not ' + value.__class__.__name__ 766 ' must be list, not ' + value.__class__.__name__)
768 for item in value: 767 for item in value:
769 if not isinstance(item, property_type) and \ 768 if not isinstance(item, property_type) and \
770 not (item.__class__ == unicode and property_type == str): 769 not (item.__class__ == unicode and property_type == str):
771 # Accept unicode where str is specified. str is treated as 770 # Accept unicode where str is specified. str is treated as
772 # UTF-8-encoded. 771 # UTF-8-encoded.
773 raise TypeError, \ 772 raise TypeError(
774 'item of ' + property + ' of ' + self.__class__.__name__ + \ 773 'item of ' + property + ' of ' + self.__class__.__name__ + \
775 ' must be ' + property_type.__name__ + ', not ' + \ 774 ' must be ' + property_type.__name__ + ', not ' + \
776 item.__class__.__name__ 775 item.__class__.__name__)
777 elif not isinstance(value, property_type) and \ 776 elif not isinstance(value, property_type) and \
778 not (value.__class__ == unicode and property_type == str): 777 not (value.__class__ == unicode and property_type == str):
779 # Accept unicode where str is specified. str is treated as 778 # Accept unicode where str is specified. str is treated as
780 # UTF-8-encoded. 779 # UTF-8-encoded.
781 raise TypeError, \ 780 raise TypeError(
782 property + ' of ' + self.__class__.__name__ + ' must be ' + \ 781 property + ' of ' + self.__class__.__name__ + ' must be ' + \
783 property_type.__name__ + ', not ' + value.__class__.__name__ 782 property_type.__name__ + ', not ' + value.__class__.__name__)
784 783
785 # Checks passed, perform the assignment. 784 # Checks passed, perform the assignment.
786 if do_copy: 785 if do_copy:
787 if isinstance(value, XCObject): 786 if isinstance(value, XCObject):
788 if is_strong: 787 if is_strong:
789 self._properties[property] = value.Copy() 788 self._properties[property] = value.Copy()
790 else: 789 else:
791 self._properties[property] = value 790 self._properties[property] = value
792 elif isinstance(value, str) or isinstance(value, unicode) or \ 791 elif isinstance(value, str) or isinstance(value, unicode) or \
793 isinstance(value, int): 792 isinstance(value, int):
794 self._properties[property] = value 793 self._properties[property] = value
795 elif isinstance(value, list): 794 elif isinstance(value, list):
796 if is_strong: 795 if is_strong:
797 # If is_strong is True, each element is an XCObject, so it's safe 796 # If is_strong is True, each element is an XCObject, so it's safe
798 # to call Copy. 797 # to call Copy.
799 self._properties[property] = [] 798 self._properties[property] = []
800 for item in value: 799 for item in value:
801 self._properties[property].append(item.Copy()) 800 self._properties[property].append(item.Copy())
802 else: 801 else:
803 self._properties[property] = value[:] 802 self._properties[property] = value[:]
804 elif isinstance(value, dict): 803 elif isinstance(value, dict):
805 self._properties[property] = value.copy() 804 self._properties[property] = value.copy()
806 else: 805 else:
807 raise TypeError, "Don't know how to copy a " + \ 806 raise TypeError("Don't know how to copy a " + \
808 value.__class__.__name__ + ' object for ' + \ 807 value.__class__.__name__ + ' object for ' + \
809 property + ' in ' + self.__class__.__name__ 808 property + ' in ' + self.__class__.__name__)
810 else: 809 else:
811 self._properties[property] = value 810 self._properties[property] = value
812 811
813 # Set up the child's back-reference to this object. Don't use |value| 812 # Set up the child's back-reference to this object. Don't use |value|
814 # any more because it may not be right if do_copy is true. 813 # any more because it may not be right if do_copy is true.
815 if is_strong: 814 if is_strong:
816 if not is_list: 815 if not is_list:
817 self._properties[property].parent = self 816 self._properties[property].parent = self
818 else: 817 else:
819 for item in self._properties[property]: 818 for item in self._properties[property]:
(...skipping 10 matching lines...) Expand all
830 829
831 def DelProperty(self, key): 830 def DelProperty(self, key):
832 if key in self._properties: 831 if key in self._properties:
833 del self._properties[key] 832 del self._properties[key]
834 833
835 def AppendProperty(self, key, value): 834 def AppendProperty(self, key, value):
836 # TODO(mark): Support ExtendProperty too (and make this call that)? 835 # TODO(mark): Support ExtendProperty too (and make this call that)?
837 836
838 # Schema validation. 837 # Schema validation.
839 if not key in self._schema: 838 if not key in self._schema:
840 raise KeyError, key + ' not in ' + self.__class__.__name__ 839 raise KeyError(key + ' not in ' + self.__class__.__name__)
841 840
842 (is_list, property_type, is_strong) = self._schema[key][0:3] 841 (is_list, property_type, is_strong) = self._schema[key][0:3]
843 if not is_list: 842 if not is_list:
844 raise TypeError, key + ' of ' + self.__class__.__name__ + ' must be list' 843 raise TypeError(key + ' of ' + self.__class__.__name__ + ' must be list')
845 if not isinstance(value, property_type): 844 if not isinstance(value, property_type):
846 raise TypeError, 'item of ' + key + ' of ' + self.__class__.__name__ + \ 845 raise TypeError('item of ' + key + ' of ' + self.__class__.__name__ + \
847 ' must be ' + property_type.__name__ + ', not ' + \ 846 ' must be ' + property_type.__name__ + ', not ' + \
848 value.__class__.__name__ 847 value.__class__.__name__)
849 848
850 # If the property doesn't exist yet, create a new empty list to receive the 849 # If the property doesn't exist yet, create a new empty list to receive the
851 # item. 850 # item.
852 if not key in self._properties: 851 if not key in self._properties:
853 self._properties[key] = [] 852 self._properties[key] = []
854 853
855 # Set up the ownership link. 854 # Set up the ownership link.
856 if is_strong: 855 if is_strong:
857 value.parent = self 856 value.parent = self
858 857
859 # Store the item. 858 # Store the item.
860 self._properties[key].append(value) 859 self._properties[key].append(value)
861 860
862 def VerifyHasRequiredProperties(self): 861 def VerifyHasRequiredProperties(self):
863 """Ensure that all properties identified as required by the schema are 862 """Ensure that all properties identified as required by the schema are
864 set. 863 set.
865 """ 864 """
866 865
867 # TODO(mark): A stronger verification mechanism is needed. Some 866 # TODO(mark): A stronger verification mechanism is needed. Some
868 # subclasses need to perform validation beyond what the schema can enforce. 867 # subclasses need to perform validation beyond what the schema can enforce.
869 for property, attributes in self._schema.iteritems(): 868 for property, attributes in self._schema.iteritems():
870 (is_list, property_type, is_strong, is_required) = attributes[0:4] 869 (is_list, property_type, is_strong, is_required) = attributes[0:4]
871 if is_required and not property in self._properties: 870 if is_required and not property in self._properties:
872 raise KeyError, self.__class__.__name__ + ' requires ' + property 871 raise KeyError(self.__class__.__name__ + ' requires ' + property)
873 872
874 def _SetDefaultsFromSchema(self): 873 def _SetDefaultsFromSchema(self):
875 """Assign object default values according to the schema. This will not 874 """Assign object default values according to the schema. This will not
876 overwrite properties that have already been set.""" 875 overwrite properties that have already been set."""
877 876
878 defaults = {} 877 defaults = {}
879 for property, attributes in self._schema.iteritems(): 878 for property, attributes in self._schema.iteritems():
880 (is_list, property_type, is_strong, is_required) = attributes[0:4] 879 (is_list, property_type, is_strong, is_required) = attributes[0:4]
881 if is_required and len(attributes) >= 5 and \ 880 if is_required and len(attributes) >= 5 and \
882 not property in self._properties: 881 not property in self._properties:
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 def HashablesForChild(self): 1135 def HashablesForChild(self):
1137 # To avoid a circular reference the hashables used to compute a child id do 1136 # To avoid a circular reference the hashables used to compute a child id do
1138 # not include the child names. 1137 # not include the child names.
1139 return XCHierarchicalElement.Hashables(self) 1138 return XCHierarchicalElement.Hashables(self)
1140 1139
1141 def _AddChildToDicts(self, child): 1140 def _AddChildToDicts(self, child):
1142 # Sets up this PBXGroup object's dicts to reference the child properly. 1141 # Sets up this PBXGroup object's dicts to reference the child properly.
1143 child_path = child.PathFromSourceTreeAndPath() 1142 child_path = child.PathFromSourceTreeAndPath()
1144 if child_path: 1143 if child_path:
1145 if child_path in self._children_by_path: 1144 if child_path in self._children_by_path:
1146 raise ValueError, 'Found multiple children with path ' + child_path 1145 raise ValueError('Found multiple children with path ' + child_path)
1147 self._children_by_path[child_path] = child 1146 self._children_by_path[child_path] = child
1148 1147
1149 if isinstance(child, PBXVariantGroup): 1148 if isinstance(child, PBXVariantGroup):
1150 child_name = child._properties.get('name', None) 1149 child_name = child._properties.get('name', None)
1151 key = (child_name, child_path) 1150 key = (child_name, child_path)
1152 if key in self._variant_children_by_name_and_path: 1151 if key in self._variant_children_by_name_and_path:
1153 raise ValueError, 'Found multiple PBXVariantGroup children with ' + \ 1152 raise ValueError('Found multiple PBXVariantGroup children with ' + \
1154 'name ' + str(child_name) + ' and path ' + \ 1153 'name ' + str(child_name) + ' and path ' + \
1155 str(child_path) 1154 str(child_path))
1156 self._variant_children_by_name_and_path[key] = child 1155 self._variant_children_by_name_and_path[key] = child
1157 1156
1158 def AppendChild(self, child): 1157 def AppendChild(self, child):
1159 # Callers should use this instead of calling 1158 # Callers should use this instead of calling
1160 # AppendProperty('children', child) directly because this function 1159 # AppendProperty('children', child) directly because this function
1161 # maintains the group's dicts. 1160 # maintains the group's dicts.
1162 self.AppendProperty('children', child) 1161 self.AppendProperty('children', child)
1163 self._AddChildToDicts(child) 1162 self._AddChildToDicts(child)
1164 1163
1165 def GetChildByName(self, name): 1164 def GetChildByName(self, name):
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 def Name(self): 1600 def Name(self):
1602 return 'Build configuration list for ' + \ 1601 return 'Build configuration list for ' + \
1603 self.parent.__class__.__name__ + ' "' + self.parent.Name() + '"' 1602 self.parent.__class__.__name__ + ' "' + self.parent.Name() + '"'
1604 1603
1605 def ConfigurationNamed(self, name): 1604 def ConfigurationNamed(self, name):
1606 """Convenience accessor to obtain an XCBuildConfiguration by name.""" 1605 """Convenience accessor to obtain an XCBuildConfiguration by name."""
1607 for configuration in self._properties['buildConfigurations']: 1606 for configuration in self._properties['buildConfigurations']:
1608 if configuration._properties['name'] == name: 1607 if configuration._properties['name'] == name:
1609 return configuration 1608 return configuration
1610 1609
1611 raise KeyError, name 1610 raise KeyError(name)
1612 1611
1613 def DefaultConfiguration(self): 1612 def DefaultConfiguration(self):
1614 """Convenience accessor to obtain the default XCBuildConfiguration.""" 1613 """Convenience accessor to obtain the default XCBuildConfiguration."""
1615 return self.ConfigurationNamed(self._properties['defaultConfigurationName']) 1614 return self.ConfigurationNamed(self._properties['defaultConfigurationName'])
1616 1615
1617 def HasBuildSetting(self, key): 1616 def HasBuildSetting(self, key):
1618 """Determines the state of a build setting in all XCBuildConfiguration 1617 """Determines the state of a build setting in all XCBuildConfiguration
1619 child objects. 1618 child objects.
1620 1619
1621 If all child objects have key in their build settings, and the value is the 1620 If all child objects have key in their build settings, and the value is the
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 # TODO(mark): This is wrong for build settings that are lists. The list 1657 # TODO(mark): This is wrong for build settings that are lists. The list
1659 # contents should be compared (and a list copy returned?) 1658 # contents should be compared (and a list copy returned?)
1660 1659
1661 value = None 1660 value = None
1662 for configuration in self._properties['buildConfigurations']: 1661 for configuration in self._properties['buildConfigurations']:
1663 configuration_value = configuration.GetBuildSetting(key) 1662 configuration_value = configuration.GetBuildSetting(key)
1664 if value is None: 1663 if value is None:
1665 value = configuration_value 1664 value = configuration_value
1666 else: 1665 else:
1667 if value != configuration_value: 1666 if value != configuration_value:
1668 raise ValueError, 'Variant values for ' + key 1667 raise ValueError('Variant values for ' + key)
1669 1668
1670 return value 1669 return value
1671 1670
1672 def SetBuildSetting(self, key, value): 1671 def SetBuildSetting(self, key, value):
1673 """Sets the build setting for key to value in all child 1672 """Sets the build setting for key to value in all child
1674 XCBuildConfiguration objects. 1673 XCBuildConfiguration objects.
1675 """ 1674 """
1676 1675
1677 for configuration in self._properties['buildConfigurations']: 1676 for configuration in self._properties['buildConfigurations']:
1678 configuration.SetBuildSetting(key, value) 1677 configuration.SetBuildSetting(key, value)
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 self._files_by_xcfilelikeelement = {} 1764 self._files_by_xcfilelikeelement = {}
1766 for pbxbuildfile in self._properties.get('files', []): 1765 for pbxbuildfile in self._properties.get('files', []):
1767 self._AddBuildFileToDicts(pbxbuildfile) 1766 self._AddBuildFileToDicts(pbxbuildfile)
1768 1767
1769 def FileGroup(self, path): 1768 def FileGroup(self, path):
1770 # Subclasses must override this by returning a two-element tuple. The 1769 # Subclasses must override this by returning a two-element tuple. The
1771 # first item in the tuple should be the PBXGroup to which "path" should be 1770 # first item in the tuple should be the PBXGroup to which "path" should be
1772 # added, either as a child or deeper descendant. The second item should 1771 # added, either as a child or deeper descendant. The second item should
1773 # be a boolean indicating whether files should be added into hierarchical 1772 # be a boolean indicating whether files should be added into hierarchical
1774 # groups or one single flat group. 1773 # groups or one single flat group.
1775 raise NotImplementedError, \ 1774 raise NotImplementedError(
1776 self.__class__.__name__ + ' must implement FileGroup' 1775 self.__class__.__name__ + ' must implement FileGroup')
1777 1776
1778 def _AddPathToDict(self, pbxbuildfile, path): 1777 def _AddPathToDict(self, pbxbuildfile, path):
1779 """Adds path to the dict tracking paths belonging to this build phase. 1778 """Adds path to the dict tracking paths belonging to this build phase.
1780 1779
1781 If the path is already a member of this build phase, raises an exception. 1780 If the path is already a member of this build phase, raises an exception.
1782 """ 1781 """
1783 1782
1784 if path in self._files_by_path: 1783 if path in self._files_by_path:
1785 raise ValueError, 'Found multiple build files with path ' + path 1784 raise ValueError('Found multiple build files with path ' + path)
1786 self._files_by_path[path] = pbxbuildfile 1785 self._files_by_path[path] = pbxbuildfile
1787 1786
1788 def _AddBuildFileToDicts(self, pbxbuildfile, path=None): 1787 def _AddBuildFileToDicts(self, pbxbuildfile, path=None):
1789 """Maintains the _files_by_path and _files_by_xcfilelikeelement dicts. 1788 """Maintains the _files_by_path and _files_by_xcfilelikeelement dicts.
1790 1789
1791 If path is specified, then it is the path that is being added to the 1790 If path is specified, then it is the path that is being added to the
1792 phase, and pbxbuildfile must contain either a PBXFileReference directly 1791 phase, and pbxbuildfile must contain either a PBXFileReference directly
1793 referencing that path, or it must contain a PBXVariantGroup that itself 1792 referencing that path, or it must contain a PBXVariantGroup that itself
1794 contains a PBXFileReference referencing the path. 1793 contains a PBXFileReference referencing the path.
1795 1794
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 # Add the paths first, because if something's going to raise, the 1829 # Add the paths first, because if something's going to raise, the
1831 # messages provided by _AddPathToDict are more useful owing to its 1830 # messages provided by _AddPathToDict are more useful owing to its
1832 # having access to a real pathname and not just an object's Name(). 1831 # having access to a real pathname and not just an object's Name().
1833 for a_path in paths: 1832 for a_path in paths:
1834 self._AddPathToDict(pbxbuildfile, a_path) 1833 self._AddPathToDict(pbxbuildfile, a_path)
1835 1834
1836 # If another PBXBuildFile references this XCFileLikeElement, there's a 1835 # If another PBXBuildFile references this XCFileLikeElement, there's a
1837 # problem. 1836 # problem.
1838 if xcfilelikeelement in self._files_by_xcfilelikeelement and \ 1837 if xcfilelikeelement in self._files_by_xcfilelikeelement and \
1839 self._files_by_xcfilelikeelement[xcfilelikeelement] != pbxbuildfile: 1838 self._files_by_xcfilelikeelement[xcfilelikeelement] != pbxbuildfile:
1840 raise ValueError, 'Found multiple build files for ' + \ 1839 raise ValueError('Found multiple build files for ' + \
1841 xcfilelikeelement.Name() 1840 xcfilelikeelement.Name())
1842 self._files_by_xcfilelikeelement[xcfilelikeelement] = pbxbuildfile 1841 self._files_by_xcfilelikeelement[xcfilelikeelement] = pbxbuildfile
1843 1842
1844 def AppendBuildFile(self, pbxbuildfile, path=None): 1843 def AppendBuildFile(self, pbxbuildfile, path=None):
1845 # Callers should use this instead of calling 1844 # Callers should use this instead of calling
1846 # AppendProperty('files', pbxbuildfile) directly because this function 1845 # AppendProperty('files', pbxbuildfile) directly because this function
1847 # maintains the object's dicts. Better yet, callers can just call AddFile 1846 # maintains the object's dicts. Better yet, callers can just call AddFile
1848 # with a pathname and not worry about building their own PBXBuildFile 1847 # with a pathname and not worry about building their own PBXBuildFile
1849 # objects. 1848 # objects.
1850 self.AppendProperty('files', pbxbuildfile) 1849 self.AppendProperty('files', pbxbuildfile)
1851 self._AddBuildFileToDicts(pbxbuildfile, path) 1850 self._AddBuildFileToDicts(pbxbuildfile, path)
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 # The path starts with an unrecognized Xcode variable 1994 # The path starts with an unrecognized Xcode variable
1996 # name like $(SRCROOT). Xcode will still handle this 1995 # name like $(SRCROOT). Xcode will still handle this
1997 # as an "absolute path" that starts with the variable. 1996 # as an "absolute path" that starts with the variable.
1998 subfolder = 0 1997 subfolder = 0
1999 relative_path = path 1998 relative_path = path
2000 elif path.startswith('/'): 1999 elif path.startswith('/'):
2001 # Special case. Absolute paths are in dstSubfolderSpec 0. 2000 # Special case. Absolute paths are in dstSubfolderSpec 0.
2002 subfolder = 0 2001 subfolder = 0
2003 relative_path = path[1:] 2002 relative_path = path[1:]
2004 else: 2003 else:
2005 raise ValueError, 'Can\'t use path %s in a %s' % \ 2004 raise ValueError('Can\'t use path %s in a %s' % \
2006 (path, self.__class__.__name__) 2005 (path, self.__class__.__name__))
2007 2006
2008 self._properties['dstPath'] = relative_path 2007 self._properties['dstPath'] = relative_path
2009 self._properties['dstSubfolderSpec'] = subfolder 2008 self._properties['dstSubfolderSpec'] = subfolder
2010 2009
2011 2010
2012 class PBXBuildRule(XCObject): 2011 class PBXBuildRule(XCObject):
2013 _schema = XCObject._schema.copy() 2012 _schema = XCObject._schema.copy()
2014 _schema.update({ 2013 _schema.update({
2015 'compilerSpec': [0, str, 0, 1], 2014 'compilerSpec': [0, str, 0, 1],
2016 'filePatterns': [0, str, 0, 0], 2015 'filePatterns': [0, str, 0, 0],
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 for target in other_pbxproject._properties['targets']: 2799 for target in other_pbxproject._properties['targets']:
2801 if not isinstance(target, PBXNativeTarget): 2800 if not isinstance(target, PBXNativeTarget):
2802 continue 2801 continue
2803 remote_products.append(target._properties['productReference']) 2802 remote_products.append(target._properties['productReference'])
2804 2803
2805 # Sort the PBXReferenceProxy children according to the list of remote 2804 # Sort the PBXReferenceProxy children according to the list of remote
2806 # products. 2805 # products.
2807 product_group = ref_dict['ProductGroup'] 2806 product_group = ref_dict['ProductGroup']
2808 product_group._properties['children'] = sorted( 2807 product_group._properties['children'] = sorted(
2809 product_group._properties['children'], 2808 product_group._properties['children'],
2810 cmp=lambda x, y: CompareProducts(x, y, remote_products)) 2809 cmp=lambda x, y, rp=remote_products: CompareProducts(x, y, rp))
2811 2810
2812 2811
2813 class XCProjectFile(XCObject): 2812 class XCProjectFile(XCObject):
2814 _schema = XCObject._schema.copy() 2813 _schema = XCObject._schema.copy()
2815 _schema.update({ 2814 _schema.update({
2816 'archiveVersion': [0, int, 0, 1, 1], 2815 'archiveVersion': [0, int, 0, 1, 1],
2817 'classes': [0, dict, 0, 1, {}], 2816 'classes': [0, dict, 0, 1, {}],
2818 'objectVersion': [0, int, 0, 1, 45], 2817 'objectVersion': [0, int, 0, 1, 45],
2819 'rootObject': [0, PBXProject, 1, 1], 2818 'rootObject': [0, PBXProject, 1, 1],
2820 }) 2819 })
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2884 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') 2883 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n')
2885 for object in sorted(objects_by_class[class_name], 2884 for object in sorted(objects_by_class[class_name],
2886 cmp=lambda x, y: cmp(x.id, y.id)): 2885 cmp=lambda x, y: cmp(x.id, y.id)):
2887 object.Print(file) 2886 object.Print(file)
2888 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') 2887 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n')
2889 2888
2890 if self._should_print_single_line: 2889 if self._should_print_single_line:
2891 self._XCPrint(file, 0, '}; ') 2890 self._XCPrint(file, 0, '}; ')
2892 else: 2891 else:
2893 self._XCPrint(file, 1, '};\n') 2892 self._XCPrint(file, 1, '};\n')
OLDNEW
« no previous file with comments | « pylib/gyp/xcode_emulation.py ('k') | test/lib/TestWin.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698