Title: [275313] trunk/Tools
Revision
275313
Author
bb...@apple.com
Date
2021-03-31 16:05:02 -0700 (Wed, 31 Mar 2021)

Log Message

Style checker should warn about use of future OS versions in WK_API_AVAILABLE
https://bugs.webkit.org/show_bug.cgi?id=223881

Reviewed by Jonathan Bedard.

Add some more brains to the WK_API_AVAILABLE style checker. It is now more
fussy and won't allow anything except a valid version string or a TBA macro.
There is also a mechanism to prevent adding version numbers that exceed the
publicly available SDK version for the relevant OS.

* Scripts/webkitpy/common/version_name_map.py:
(VersionNameMap.mapping_for_platform): Add 'macos' as an alias for 'mac'.
(VersionNameMap.max_public_version): Added.

* Scripts/webkitpy/style/checkers/cpp.py:
(check_arguments_for_wk_api_available):
(check_arguments_for_wk_api_available.max_version_for_platform):
(check_arguments_for_wk_api_available.check_version_string):
(check_style):
(check_min_versions_of_wk_api_available): Deleted.
* Scripts/webkitpy/style/checkers/cpp_unittest.py:
(WebKitStyleTest):

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (275312 => 275313)


--- trunk/Tools/ChangeLog	2021-03-31 22:36:17 UTC (rev 275312)
+++ trunk/Tools/ChangeLog	2021-03-31 23:05:02 UTC (rev 275313)
@@ -1,3 +1,28 @@
+2021-03-31  BJ Burg  <bb...@apple.com>
+
+        Style checker should warn about use of future OS versions in WK_API_AVAILABLE
+        https://bugs.webkit.org/show_bug.cgi?id=223881
+
+        Reviewed by Jonathan Bedard.
+
+        Add some more brains to the WK_API_AVAILABLE style checker. It is now more
+        fussy and won't allow anything except a valid version string or a TBA macro.
+        There is also a mechanism to prevent adding version numbers that exceed the
+        publicly available SDK version for the relevant OS.
+
+        * Scripts/webkitpy/common/version_name_map.py:
+        (VersionNameMap.mapping_for_platform): Add 'macos' as an alias for 'mac'.
+        (VersionNameMap.max_public_version): Added.
+
+        * Scripts/webkitpy/style/checkers/cpp.py:
+        (check_arguments_for_wk_api_available):
+        (check_arguments_for_wk_api_available.max_version_for_platform):
+        (check_arguments_for_wk_api_available.check_version_string):
+        (check_style):
+        (check_min_versions_of_wk_api_available): Deleted.
+        * Scripts/webkitpy/style/checkers/cpp_unittest.py:
+        (WebKitStyleTest):
+
 2021-03-31  Aakash Jain  <aakash_j...@apple.com>
 
         EWS should stress test newly added tests

Modified: trunk/Tools/Scripts/webkitpy/common/version_name_map.py (275312 => 275313)


--- trunk/Tools/Scripts/webkitpy/common/version_name_map.py	2021-03-31 22:36:17 UTC (rev 275312)
+++ trunk/Tools/Scripts/webkitpy/common/version_name_map.py	2021-03-31 23:05:02 UTC (rev 275313)
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 Apple Inc. All rights reserved.
+# Copyright (C) 2017-2021 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -107,6 +107,14 @@
                 closest_match = (os_name, os_version)
         return closest_match[0]
 
+    def max_public_version(self, platform=None):
+        found_max_version = None
+        for os_name, os_version in self.mapping_for_platform(platform, PUBLIC_TABLE).items():
+            if os_version > found_max_version:
+                found_max_version = os_version
+
+        return found_max_version
+
     @staticmethod
     def strip_name_formatting(name):
         # <OS> major.minor.tiny should map to <OS> major
@@ -149,6 +157,11 @@
         return sorted(names, key=lambda os_name: mapping[os_name])
 
     def mapping_for_platform(self, platform=None, table=PUBLIC_TABLE):
+        # Alias macos to mac here. Adding a separate entry to the table
+        # would cause from_name() to return either 'mac' or 'macos'.
+        if platform == 'macos':
+            platform = 'mac'
+
         """return proper os_name: os_version mapping for platform"""
         platform = self.default_system_platform if platform is None else platform
         return self.mapping.get(table, {}).get(platform, {})

Modified: trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py (275312 => 275313)


--- trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py	2021-03-31 22:36:17 UTC (rev 275312)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cpp.py	2021-03-31 23:05:02 UTC (rev 275313)
@@ -2,7 +2,7 @@
 #
 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved.
 # Copyright (C) 2009 Torch Mobile Inc.
-# Copyright (C) 2009-2020 Apple Inc. All rights reserved.
+# Copyright (C) 2009-2021 Apple Inc. All rights reserved.
 # Copyright (C) 2010 Chris Jerdonek (cjerdo...@webkit.org)
 #
 # Redistribution and use in source and binary forms, with or without
@@ -45,10 +45,11 @@
 import string
 import unicodedata
 
-from webkitcorepy import unicode
+from webkitcorepy import unicode, Version
 
 from webkitpy.style.checkers.common import match, search, sub, subn
 from webkitpy.common.memoized import memoized
+from webkitpy.common.version_name_map import VersionNameMap
 
 # The key to use to provide a class to fake loading a header file.
 INCLUDE_IO_INJECTION_KEY = 'include_header_io'
@@ -3296,8 +3297,8 @@
     return len(line)
 
 
-def check_min_versions_of_wk_api_available(clean_lines, line_number, error):
-    """Checks the min version numbers of WK_API_AVAILABLE
+def check_arguments_for_wk_api_available(clean_lines, line_number, error):
+    """Checks the allowable arguments of WK_API_AVAILABLE
 
     Args:
       clean_lines: A CleansedLines instance containing the file.
@@ -3305,35 +3306,61 @@
       error: The function to call with any errors found.
     """
 
+    @memoized
+    def max_version_for_platform(platform_name):
+        return VersionNameMap.map().max_public_version(platform=platform_name)
+
+    def check_version_string(version_string, platform_name):
+        mapping = {
+            'macos': 'WK_MAC_TBA',
+            'ios': 'WK_IOS_TBA',
+        }
+
+        platform_tba_macro = mapping.get(platform_name)
+        if version_string == platform_tba_macro:
+            return
+
+        try:
+            version = Version.from_string(version_string)
+        except ValueError:
+            error(line_number, 'build/wk_api_available', 5, '%s(%s) is invalid; expected %s or a major.minor version' % (platform_name, version_string, platform_tba_macro))
+            return
+
+        if not version_string.count('.'):
+            error(line_number, 'build/wk_api_available', 5, '%s(%s) is invalid; version number should have one decimal' % (platform_name, version_string))
+            return
+
+        max_version = max_version_for_platform(platform_name)
+        if version > max_version:
+            error(line_number, 'build/wk_api_available', 5, '%s(%s) is invalid; version number should not exceed %s' % (platform_name, version_string, max_version))
+            return
+
     line = clean_lines.elided[line_number]  # Get rid of comments and strings.
 
     wk_api_available = search(r'WK_API_AVAILABLE\(macosx\(', line)
     if wk_api_available:
         error(line_number, 'build/wk_api_available', 5, 'macosx() is deprecated; use macos() instead')
+        return
 
-    # FIXME: This should support any order.
     wk_api_available = search(r'WK_API_AVAILABLE\(macos\(([^\)]+)\), ios\(([^\)]+)\)\)', line)
     if wk_api_available:
-        macosMinVersion = wk_api_available.group(1)
-        if not match(r'^([\d\.]+|WK_MAC_TBA)$', macosMinVersion):
-            error(line_number, 'build/wk_api_available', 5, 'macos(%s) is invalid; expected WK_MAC_TBA or a number' % macosMinVersion)
+        check_version_string(wk_api_available.group(1), "macos")
+        check_version_string(wk_api_available.group(2), "ios")
 
-        iosMinVersion = wk_api_available.group(2)
-        if not match(r'^([\d\.]+|WK_IOS_TBA)$', iosMinVersion):
-            error(line_number, 'build/wk_api_available', 5, 'ios(%s) is invalid; expected WK_IOS_TBA or a number' % iosMinVersion)
+    wk_api_available = search(r'WK_API_AVAILABLE\(ios\(([^\)]+)\), macos\(([^\)]+)\)\)', line)
+    if wk_api_available:
+        check_version_string(wk_api_available.group(1), "ios")
+        check_version_string(wk_api_available.group(2), "macos")
 
     wk_api_available = search(r'WK_API_AVAILABLE\(macos\(([^\)]+)\)\)', line)
     if wk_api_available:
-        macosMinVersion = wk_api_available.group(1)
-        if not match(r'^([\d\.]+|WK_MAC_TBA)$', macosMinVersion):
-            error(line_number, 'build/wk_api_available', 5, 'macos(%s) is invalid; expected WK_MAC_TBA or a number' % macosMinVersion)
+        check_version_string(wk_api_available.group(1), "macos")
 
     wk_api_available = search(r'WK_API_AVAILABLE\(ios\(([^\)]+)\)\)', line)
     if wk_api_available:
-        iosMinVersion = wk_api_available.group(1)
-        if not match(r'^([\d\.]+|WK_IOS_TBA)$', iosMinVersion):
-            error(line_number, 'build/wk_api_available', 5, 'ios(%s) is invalid; expected WK_IOS_TBA or a number' % iosMinVersion)
+        check_version_string(wk_api_available.group(1), "ios")
 
+
 def check_style(clean_lines, line_number, file_extension, class_state, file_state, enum_state, error):
     """Checks rules from the 'C++ style rules' section of cppguide.html.
 
@@ -3415,7 +3442,7 @@
     check_indentation_amount(clean_lines, line_number, error)
     check_enum_casing(clean_lines, line_number, enum_state, error)
     check_once_flag(clean_lines, line_number, file_state, error)
-    check_min_versions_of_wk_api_available(clean_lines, line_number, error)
+    check_arguments_for_wk_api_available(clean_lines, line_number, error)
 
 
 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#(?:include|import) +"[^/]+\.h"')

Modified: trunk/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py (275312 => 275313)


--- trunk/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py	2021-03-31 22:36:17 UTC (rev 275312)
+++ trunk/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py	2021-03-31 23:05:02 UTC (rev 275313)
@@ -48,6 +48,12 @@
 from webkitpy.style.checkers.cpp import CppChecker, _split_identifier_into_words
 from webkitpy.style.filter import FilterConfiguration
 
+# Enable this if you need to see the full diff when debugging failures.
+# https://stackoverflow.com/questions/43842675/how-to-prevent-truncating-of-string-in-unit-test-python
+if False:
+    if 'unittest.util' in __import__('sys').modules:
+        # Show full diff in self.assertEqual.
+        __import__('sys').modules['unittest.util']._MAX_LENGTH = 999999999
 
 # This class works as an error collector and replaces cpp_style.Error
 # function for the unit tests.  We also verify each category we see
@@ -6385,20 +6391,25 @@
 
         self.assert_lint('MYMACRO(a ? b() : c);', '')
 
-    def test_min_versions_of_wk_api_available(self):
-        self.assert_lint('WK_API_AVAILABLE(macosx(1.2.3))', 'macosx() is deprecated; use macos() instead  [build/wk_api_available] [5]')
+    def test_arguments_for_wk_api_available(self):
+        self.assert_lint('WK_API_AVAILABLE(macosx(10.2.3))', 'macosx() is deprecated; use macos() instead  [build/wk_api_available] [5]')
         self.assert_lint('WK_API_AVAILABLE(macosx(WK_MAC_TBA))', 'macosx() is deprecated; use macos() instead  [build/wk_api_available] [5]')
-        self.assert_lint('WK_API_AVAILABLE(macos(1.2.3), ios(3.4.5))', '')  # version numbers are OK.
+
+        self.assert_lint('WK_API_AVAILABLE(macos(11.0))', '')  # version numbers are OK.
+        self.assert_lint('WK_API_AVAILABLE(ios(11.0))', '')  # version numbers are OK.
+        self.assert_lint('WK_API_AVAILABLE(macos(10.2.3))', '')  # Extended version numbers are OK.
+        self.assert_lint('WK_API_AVAILABLE(ios(10.1.1))', ''),  # Extended version numbers are OK.
+
+        self.assert_lint('WK_API_AVAILABLE(macos(11))', 'macos(11) is invalid; version number should have one decimal  [build/wk_api_available] [5]')
+        self.assert_lint('WK_API_AVAILABLE(macos(11.))', 'macos(11.) is invalid; expected WK_MAC_TBA or a major.minor version  [build/wk_api_available] [5]')
+        self.assert_lint('WK_API_AVAILABLE(ios(10.))', 'ios(10.) is invalid; expected WK_IOS_TBA or a major.minor version  [build/wk_api_available] [5]')
+
+        self.assert_lint('WK_API_AVAILABLE(ios(WK_IOS_TBA))', '')  # WK_IOS_TBA is OK.
+        self.assert_lint('WK_API_AVAILABLE(macos(WK_MAC_TBA))', '')  # WK_MAC_TBA is OK.
         self.assert_lint('WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))', '')  # WK_MAC_TBA and WK_IOS_TBA are OK.
-        self.assert_lint('WK_API_AVAILABLE(macos(WK_IOS_TBA), ios(3.4.5))', 'macos(WK_IOS_TBA) is invalid; expected WK_MAC_TBA or a number  [build/wk_api_available] [5]')
-        self.assert_lint('WK_API_AVAILABLE(macos(1.2.3), ios(WK_MAC_TBA))', 'ios(WK_MAC_TBA) is invalid; expected WK_IOS_TBA or a number  [build/wk_api_available] [5]')
-        self.assert_lint('WK_API_AVAILABLE(macos(1.2.3))', '')  # version numbers are OK.
-        self.assert_lint('WK_API_AVAILABLE(macos(WK_MAC_TBA))', '')  # WK_MAC_TBA is OK.
-        self.assert_lint('WK_API_AVAILABLE(ios(3.4.5))', '')  # version numbers are OK.
-        self.assert_lint('WK_API_AVAILABLE(ios(WK_IOS_TBA))', '')  # WK_IOS_TBA is OK.
-        self.assert_lint('WK_API_AVAILABLE(macos(WK_IOS_TBA))', 'macos(WK_IOS_TBA) is invalid; expected WK_MAC_TBA or a number  [build/wk_api_available] [5]')
-        self.assert_lint('WK_API_AVAILABLE(macos(WK_IOS_TBA))', 'macos(WK_IOS_TBA) is invalid; expected WK_MAC_TBA or a number  [build/wk_api_available] [5]')
-        self.assert_lint('WK_API_AVAILABLE(ios(WK_MAC_TBA))', 'ios(WK_MAC_TBA) is invalid; expected WK_IOS_TBA or a number  [build/wk_api_available] [5]')
+        self.assert_lint('WK_API_AVAILABLE(ios(WK_IOS_TBA), macos(WK_MAC_TBA))', '')  # WK_MAC_TBA and WK_IOS_TBA are OK, backwards.
+        self.assert_lint('WK_API_AVAILABLE(macos(WK_IOS_TBA))', 'macos(WK_IOS_TBA) is invalid; expected WK_MAC_TBA or a major.minor version  [build/wk_api_available] [5]')
+        self.assert_lint('WK_API_AVAILABLE(ios(WK_MAC_TBA))', 'ios(WK_MAC_TBA) is invalid; expected WK_IOS_TBA or a major.minor version  [build/wk_api_available] [5]')
 
     def test_os_version_checks(self):
         self.assert_lint('#if PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000', 'Misplaced OS version check. Please use a named macro in one of headers in the wtf/Platform.h suite of files or an appropriate internal file.  [build/version_check] [5]')
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to