Merge changes from topic "may26-dab" into sc-dev

* changes:
  Clean up "Deprecated at Birth" APIs.
  Set all references to SipDelegateImsConfiguration as @removed
  Reintroduce "Deprecated at Birth" linter.
This commit is contained in:
Jeff Sharkey
2021-05-26 21:07:07 +00:00
committed by Android (Google) Code Review
9 changed files with 397 additions and 82 deletions

View File

@@ -4930,10 +4930,6 @@ package android.location {
field @Deprecated public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
}
public final class LocationDeviceConfig {
field public static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist";
}
public class LocationManager {
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void addProviderRequestChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.provider.ProviderRequest.ChangedListener);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
@@ -4946,7 +4942,6 @@ package android.location {
method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@NonNull String);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@Nullable String, @NonNull String);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@Nullable String, @NonNull String, @Nullable String);
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.UPDATE_APP_OPS_STATS}) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.GnssMeasurementsEvent.Callback);
@@ -12843,7 +12838,6 @@ package android.telephony.ims {
method public void onCreated(@NonNull android.telephony.ims.stub.SipDelegate, @Nullable java.util.Set<android.telephony.ims.FeatureTagState>);
method public void onDestroyed(int);
method public void onFeatureTagRegistrationChanged(@NonNull android.telephony.ims.DelegateRegistrationState);
method @Deprecated public void onImsConfigurationChanged(@NonNull android.telephony.ims.SipDelegateImsConfiguration);
}
public final class FeatureTagState implements android.os.Parcelable {
@@ -13664,67 +13658,6 @@ package android.telephony.ims {
method public void sendMessage(@NonNull android.telephony.ims.SipMessage, long);
}
@Deprecated public final class SipDelegateImsConfiguration implements android.os.Parcelable {
method @Deprecated public boolean containsKey(@NonNull String);
method @Deprecated @NonNull public android.os.PersistableBundle copyBundle();
method @Deprecated public int describeContents();
method @Deprecated public boolean getBoolean(@NonNull String, boolean);
method @Deprecated public int getInt(@NonNull String, int);
method @Deprecated @Nullable public String getString(@NonNull String);
method @Deprecated public long getVersion();
method @Deprecated public void writeToParcel(@NonNull android.os.Parcel, int);
field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.SipDelegateImsConfiguration> CREATOR;
field @Deprecated public static final String IPTYPE_IPV4 = "IPV4";
field @Deprecated public static final String IPTYPE_IPV6 = "IPV6";
field @Deprecated public static final String KEY_SIP_CONFIG_AUTHENTICATION_HEADER_STRING = "sip_config_auhentication_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_AUTHENTICATION_NONCE_STRING = "sip_config_authentication_nonce_string";
field @Deprecated public static final String KEY_SIP_CONFIG_CELLULAR_NETWORK_INFO_HEADER_STRING = "sip_config_cellular_network_info_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_HOME_DOMAIN_STRING = "sip_config_home_domain_string";
field @Deprecated public static final String KEY_SIP_CONFIG_IMEI_STRING = "sip_config_imei_string";
field @Deprecated public static final String KEY_SIP_CONFIG_IPTYPE_STRING = "sip_config_iptype_string";
field @Deprecated public static final String KEY_SIP_CONFIG_IS_COMPACT_FORM_ENABLED_BOOL = "sip_config_is_compact_form_enabled_bool";
field @Deprecated public static final String KEY_SIP_CONFIG_IS_GRUU_ENABLED_BOOL = "sip_config_is_gruu_enabled_bool";
field @Deprecated public static final String KEY_SIP_CONFIG_IS_IPSEC_ENABLED_BOOL = "sip_config_is_ipsec_enabled_bool";
field @Deprecated public static final String KEY_SIP_CONFIG_IS_KEEPALIVE_ENABLED_BOOL = "sip_config_is_keepalive_enabled_bool";
field @Deprecated public static final String KEY_SIP_CONFIG_IS_NAT_ENABLED_BOOL = "sip_config_is_nat_enabled_bool";
field @Deprecated public static final String KEY_SIP_CONFIG_MAX_PAYLOAD_SIZE_ON_UDP_INT = "sip_config_udp_max_payload_size_int";
field @Deprecated public static final String KEY_SIP_CONFIG_PATH_HEADER_STRING = "sip_config_path_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_P_ACCESS_NETWORK_INFO_HEADER_STRING = "sip_config_p_access_network_info_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_P_ASSOCIATED_URI_HEADER_STRING = "sip_config_p_associated_uri_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_P_LAST_ACCESS_NETWORK_INFO_HEADER_STRING = "sip_config_p_last_access_network_info_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_SECURITY_VERIFY_HEADER_STRING = "sip_config_security_verify_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_SERVER_DEFAULT_IPADDRESS_STRING = "sip_config_server_default_ipaddress_string";
field @Deprecated public static final String KEY_SIP_CONFIG_SERVER_DEFAULT_PORT_INT = "sip_config_server_default_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_SERVER_IPSEC_CLIENT_PORT_INT = "sip_config_server_ipsec_client_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_SERVER_IPSEC_OLD_CLIENT_PORT_INT = "sip_config_server_ipsec_old_client_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_SERVER_IPSEC_SERVER_PORT_INT = "sip_config_server_ipsec_server_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_SERVICE_ROUTE_HEADER_STRING = "sip_config_service_route_header_string";
field @Deprecated public static final String KEY_SIP_CONFIG_TRANSPORT_TYPE_STRING = "sip_config_protocol_type_string";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_DEFAULT_IPADDRESS_STRING = "sip_config_ue_default_ipaddress_string";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_DEFAULT_PORT_INT = "sip_config_ue_default_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_IPSEC_CLIENT_PORT_INT = "sip_config_ue_ipsec_client_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_IPSEC_OLD_CLIENT_PORT_INT = "sip_config_ue_ipsec_old_client_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_IPSEC_SERVER_PORT_INT = "sip_config_ue_ipsec_server_port_int";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_PRIVATE_USER_ID_STRING = "sip_config_ue_private_user_id_string";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_PUBLIC_GRUU_STRING = "sip_config_ue_public_gruu_string";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_PUBLIC_IPADDRESS_WITH_NAT_STRING = "sip_config_ue_public_ipaddress_with_nat_string";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_PUBLIC_PORT_WITH_NAT_INT = "sip_config_ue_public_port_with_nat_int";
field @Deprecated public static final String KEY_SIP_CONFIG_UE_PUBLIC_USER_ID_STRING = "sip_config_ue_public_user_id_string";
field @Deprecated public static final String KEY_SIP_CONFIG_URI_USER_PART_STRING = "sip_config_uri_user_part_string";
field @Deprecated public static final String KEY_SIP_CONFIG_USER_AGENT_HEADER_STRING = "sip_config_sip_user_agent_header_string";
field @Deprecated public static final String SIP_TRANSPORT_TCP = "TCP";
field @Deprecated public static final String SIP_TRANSPORT_UDP = "UDP";
}
@Deprecated public static final class SipDelegateImsConfiguration.Builder {
ctor @Deprecated public SipDelegateImsConfiguration.Builder(int);
ctor @Deprecated public SipDelegateImsConfiguration.Builder(@NonNull android.telephony.ims.SipDelegateImsConfiguration);
method @Deprecated @NonNull public android.telephony.ims.SipDelegateImsConfiguration.Builder addBoolean(@NonNull String, boolean);
method @Deprecated @NonNull public android.telephony.ims.SipDelegateImsConfiguration.Builder addInt(@NonNull String, int);
method @Deprecated @NonNull public android.telephony.ims.SipDelegateImsConfiguration.Builder addString(@NonNull String, @NonNull String);
method @Deprecated @NonNull public android.telephony.ims.SipDelegateImsConfiguration build();
}
public class SipDelegateManager {
method @RequiresPermission(android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void createSipDelegate(@NonNull android.telephony.ims.DelegateRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.stub.DelegateConnectionStateCallback, @NonNull android.telephony.ims.stub.DelegateConnectionMessageCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void destroySipDelegate(@NonNull android.telephony.ims.SipDelegateConnection, int);
@@ -13892,11 +13825,10 @@ package android.telephony.ims.stub {
}
public interface DelegateConnectionStateCallback {
method public default void onConfigurationChanged(@NonNull android.telephony.ims.SipDelegateConfiguration);
method public void onConfigurationChanged(@NonNull android.telephony.ims.SipDelegateConfiguration);
method public void onCreated(@NonNull android.telephony.ims.SipDelegateConnection);
method public void onDestroyed(int);
method public void onFeatureTagStatusChanged(@NonNull android.telephony.ims.DelegateRegistrationState, @NonNull java.util.Set<android.telephony.ims.FeatureTagState>);
method @Deprecated public default void onImsConfigurationChanged(@NonNull android.telephony.ims.SipDelegateImsConfiguration);
}
public class ImsCallSessionImplBase implements java.lang.AutoCloseable {

View File

@@ -135,6 +135,7 @@ package android.location {
public class LocationManager {
method @Deprecated public boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@Nullable String, @NonNull String);
method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(String);
@@ -231,6 +232,83 @@ package android.telephony.data {
}
package android.telephony.ims {
public interface DelegateStateCallback {
method @Deprecated public void onImsConfigurationChanged(@NonNull android.telephony.ims.SipDelegateImsConfiguration);
}
@Deprecated public final class SipDelegateImsConfiguration implements android.os.Parcelable {
method public boolean containsKey(@NonNull String);
method @NonNull public android.os.PersistableBundle copyBundle();
method public int describeContents();
method public boolean getBoolean(@NonNull String, boolean);
method public int getInt(@NonNull String, int);
method @Nullable public String getString(@NonNull String);
method public long getVersion();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.SipDelegateImsConfiguration> CREATOR;
field public static final String IPTYPE_IPV4 = "IPV4";
field public static final String IPTYPE_IPV6 = "IPV6";
field public static final String KEY_SIP_CONFIG_AUTHENTICATION_HEADER_STRING = "sip_config_auhentication_header_string";
field public static final String KEY_SIP_CONFIG_AUTHENTICATION_NONCE_STRING = "sip_config_authentication_nonce_string";
field public static final String KEY_SIP_CONFIG_CELLULAR_NETWORK_INFO_HEADER_STRING = "sip_config_cellular_network_info_header_string";
field public static final String KEY_SIP_CONFIG_HOME_DOMAIN_STRING = "sip_config_home_domain_string";
field public static final String KEY_SIP_CONFIG_IMEI_STRING = "sip_config_imei_string";
field public static final String KEY_SIP_CONFIG_IPTYPE_STRING = "sip_config_iptype_string";
field public static final String KEY_SIP_CONFIG_IS_COMPACT_FORM_ENABLED_BOOL = "sip_config_is_compact_form_enabled_bool";
field public static final String KEY_SIP_CONFIG_IS_GRUU_ENABLED_BOOL = "sip_config_is_gruu_enabled_bool";
field public static final String KEY_SIP_CONFIG_IS_IPSEC_ENABLED_BOOL = "sip_config_is_ipsec_enabled_bool";
field public static final String KEY_SIP_CONFIG_IS_KEEPALIVE_ENABLED_BOOL = "sip_config_is_keepalive_enabled_bool";
field public static final String KEY_SIP_CONFIG_IS_NAT_ENABLED_BOOL = "sip_config_is_nat_enabled_bool";
field public static final String KEY_SIP_CONFIG_MAX_PAYLOAD_SIZE_ON_UDP_INT = "sip_config_udp_max_payload_size_int";
field public static final String KEY_SIP_CONFIG_PATH_HEADER_STRING = "sip_config_path_header_string";
field public static final String KEY_SIP_CONFIG_P_ACCESS_NETWORK_INFO_HEADER_STRING = "sip_config_p_access_network_info_header_string";
field public static final String KEY_SIP_CONFIG_P_ASSOCIATED_URI_HEADER_STRING = "sip_config_p_associated_uri_header_string";
field public static final String KEY_SIP_CONFIG_P_LAST_ACCESS_NETWORK_INFO_HEADER_STRING = "sip_config_p_last_access_network_info_header_string";
field public static final String KEY_SIP_CONFIG_SECURITY_VERIFY_HEADER_STRING = "sip_config_security_verify_header_string";
field public static final String KEY_SIP_CONFIG_SERVER_DEFAULT_IPADDRESS_STRING = "sip_config_server_default_ipaddress_string";
field public static final String KEY_SIP_CONFIG_SERVER_DEFAULT_PORT_INT = "sip_config_server_default_port_int";
field public static final String KEY_SIP_CONFIG_SERVER_IPSEC_CLIENT_PORT_INT = "sip_config_server_ipsec_client_port_int";
field public static final String KEY_SIP_CONFIG_SERVER_IPSEC_OLD_CLIENT_PORT_INT = "sip_config_server_ipsec_old_client_port_int";
field public static final String KEY_SIP_CONFIG_SERVER_IPSEC_SERVER_PORT_INT = "sip_config_server_ipsec_server_port_int";
field public static final String KEY_SIP_CONFIG_SERVICE_ROUTE_HEADER_STRING = "sip_config_service_route_header_string";
field public static final String KEY_SIP_CONFIG_TRANSPORT_TYPE_STRING = "sip_config_protocol_type_string";
field public static final String KEY_SIP_CONFIG_UE_DEFAULT_IPADDRESS_STRING = "sip_config_ue_default_ipaddress_string";
field public static final String KEY_SIP_CONFIG_UE_DEFAULT_PORT_INT = "sip_config_ue_default_port_int";
field public static final String KEY_SIP_CONFIG_UE_IPSEC_CLIENT_PORT_INT = "sip_config_ue_ipsec_client_port_int";
field public static final String KEY_SIP_CONFIG_UE_IPSEC_OLD_CLIENT_PORT_INT = "sip_config_ue_ipsec_old_client_port_int";
field public static final String KEY_SIP_CONFIG_UE_IPSEC_SERVER_PORT_INT = "sip_config_ue_ipsec_server_port_int";
field public static final String KEY_SIP_CONFIG_UE_PRIVATE_USER_ID_STRING = "sip_config_ue_private_user_id_string";
field public static final String KEY_SIP_CONFIG_UE_PUBLIC_GRUU_STRING = "sip_config_ue_public_gruu_string";
field public static final String KEY_SIP_CONFIG_UE_PUBLIC_IPADDRESS_WITH_NAT_STRING = "sip_config_ue_public_ipaddress_with_nat_string";
field public static final String KEY_SIP_CONFIG_UE_PUBLIC_PORT_WITH_NAT_INT = "sip_config_ue_public_port_with_nat_int";
field public static final String KEY_SIP_CONFIG_UE_PUBLIC_USER_ID_STRING = "sip_config_ue_public_user_id_string";
field public static final String KEY_SIP_CONFIG_URI_USER_PART_STRING = "sip_config_uri_user_part_string";
field public static final String KEY_SIP_CONFIG_USER_AGENT_HEADER_STRING = "sip_config_sip_user_agent_header_string";
field public static final String SIP_TRANSPORT_TCP = "TCP";
field public static final String SIP_TRANSPORT_UDP = "UDP";
}
public static final class SipDelegateImsConfiguration.Builder {
ctor public SipDelegateImsConfiguration.Builder(int);
ctor public SipDelegateImsConfiguration.Builder(@NonNull android.telephony.ims.SipDelegateImsConfiguration);
method @NonNull public android.telephony.ims.SipDelegateImsConfiguration.Builder addBoolean(@NonNull String, boolean);
method @NonNull public android.telephony.ims.SipDelegateImsConfiguration.Builder addInt(@NonNull String, int);
method @NonNull public android.telephony.ims.SipDelegateImsConfiguration.Builder addString(@NonNull String, @NonNull String);
method @NonNull public android.telephony.ims.SipDelegateImsConfiguration build();
}
}
package android.telephony.ims.stub {
public interface DelegateConnectionStateCallback {
method @Deprecated public default void onImsConfigurationChanged(@NonNull android.telephony.ims.SipDelegateImsConfiguration);
}
}
package android.view.translation {
public final class UiTranslationManager {

View File

@@ -1360,10 +1360,6 @@ package android.location {
method public void setType(int);
}
public final class LocationDeviceConfig {
field public static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist";
}
public class LocationManager {
method @NonNull public String[] getBackgroundThrottlingWhitelist();
method @NonNull public android.os.PackageTagsList getIgnoreSettingsAllowlist();

View File

@@ -16,16 +16,11 @@
package android.location;
import android.annotation.SystemApi;
import android.annotation.TestApi;
/**
* DeviceConfig keys within the location namespace.
*
* @hide
*/
@SystemApi
@TestApi
public final class LocationDeviceConfig {
/**

View File

@@ -1823,6 +1823,7 @@ public class LocationManager {
* @deprecated Use {@link #isProviderPackage(String, String, String)} instead.
*
* @hide
* @removed
*/
@Deprecated
@SystemApi

View File

@@ -79,7 +79,7 @@ public interface DelegateStateCallback {
* messages routing should be delayed until the {@link SipDelegate} sends the IMS configuration
* change event to reduce conditions where the remote application is using a stale IMS
* configuration.
* @deprecated This is being removed from API surface, Use
* @removed This is being removed from API surface, Use
* {@link #onConfigurationChanged(SipDelegateConfiguration)} instead.
*/
@Deprecated

View File

@@ -34,7 +34,7 @@ import java.net.InetSocketAddress;
/**
* @hide
* @deprecated Use {@link SipDelegateConfiguration} instead.
* @removed Use {@link SipDelegateConfiguration} instead.
*/
@Deprecated
@SystemApi

View File

@@ -136,7 +136,7 @@ public interface DelegateConnectionStateCallback {
* not compleed yet.
*
* @param registeredSipConfig The configuration of the IMS stack registered on the IMS network.
* @deprecated Will not be in final API, use
* @removed Will not be in final API, use
* {@link #onConfigurationChanged(SipDelegateConfiguration)} instead}.
*/
@Deprecated
@@ -161,7 +161,7 @@ public interface DelegateConnectionStateCallback {
*
* @param registeredSipConfig The configuration of the IMS stack registered on the IMS network.
*/
default void onConfigurationChanged(@NonNull SipDelegateConfiguration registeredSipConfig) {}
void onConfigurationChanged(@NonNull SipDelegateConfiguration registeredSipConfig);
/**
* The previously created {@link SipDelegateConnection} instance delivered via

View File

@@ -0,0 +1,313 @@
#!/usr/bin/env python
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Usage: deprecated_at_birth.py path/to/next/ path/to/previous/
Usage: deprecated_at_birth.py prebuilts/sdk/31/public/api/ prebuilts/sdk/30/public/api/
"""
import re, sys, os, collections, traceback, argparse
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False):
# manually derived from http://en.wikipedia.org/wiki/ANSI_escape_code#Codes
codes = []
if reset: codes.append("0")
else:
if not fg is None: codes.append("3%d" % (fg))
if not bg is None:
if not bright: codes.append("4%d" % (bg))
else: codes.append("10%d" % (bg))
if bold: codes.append("1")
elif dim: codes.append("2")
else: codes.append("22")
return "\033[%sm" % (";".join(codes))
def ident(raw):
"""Strips superficial signature changes, giving us a strong key that
can be used to identify members across API levels."""
raw = raw.replace(" deprecated ", " ")
raw = raw.replace(" synchronized ", " ")
raw = raw.replace(" final ", " ")
raw = re.sub("<.+?>", "", raw)
raw = re.sub("@[A-Za-z]+ ", "", raw)
raw = re.sub("@[A-Za-z]+\(.+?\) ", "", raw)
if " throws " in raw:
raw = raw[:raw.index(" throws ")]
return raw
class Field():
def __init__(self, clazz, line, raw, blame):
self.clazz = clazz
self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
raw = raw.split()
self.split = list(raw)
raw = [ r for r in raw if not r.startswith("@") ]
for r in ["method", "field", "public", "protected", "static", "final", "abstract", "default", "volatile", "transient"]:
while r in raw: raw.remove(r)
self.typ = raw[0]
self.name = raw[1].strip(";")
if len(raw) >= 4 and raw[2] == "=":
self.value = raw[3].strip(';"')
else:
self.value = None
self.ident = ident(self.raw)
def __hash__(self):
return hash(self.raw)
def __repr__(self):
return self.raw
class Method():
def __init__(self, clazz, line, raw, blame):
self.clazz = clazz
self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
# drop generics for now
raw = re.sub("<.+?>", "", raw)
raw = re.split("[\s(),;]+", raw)
for r in ["", ";"]:
while r in raw: raw.remove(r)
self.split = list(raw)
raw = [ r for r in raw if not r.startswith("@") ]
for r in ["method", "field", "public", "protected", "static", "final", "abstract", "default", "volatile", "transient"]:
while r in raw: raw.remove(r)
self.typ = raw[0]
self.name = raw[1]
self.args = []
self.throws = []
target = self.args
for r in raw[2:]:
if r == "throws": target = self.throws
else: target.append(r)
self.ident = ident(self.raw)
def __hash__(self):
return hash(self.raw)
def __repr__(self):
return self.raw
class Class():
def __init__(self, pkg, line, raw, blame):
self.pkg = pkg
self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
self.ctors = []
self.fields = []
self.methods = []
raw = raw.split()
self.split = list(raw)
if "class" in raw:
self.fullname = raw[raw.index("class")+1]
elif "enum" in raw:
self.fullname = raw[raw.index("enum")+1]
elif "interface" in raw:
self.fullname = raw[raw.index("interface")+1]
elif "@interface" in raw:
self.fullname = raw[raw.index("@interface")+1]
else:
raise ValueError("Funky class type %s" % (self.raw))
if "extends" in raw:
self.extends = raw[raw.index("extends")+1]
self.extends_path = self.extends.split(".")
else:
self.extends = None
self.extends_path = []
self.fullname = self.pkg.name + "." + self.fullname
self.fullname_path = self.fullname.split(".")
self.name = self.fullname[self.fullname.rindex(".")+1:]
def __hash__(self):
return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods)))
def __repr__(self):
return self.raw
class Package():
def __init__(self, line, raw, blame):
self.line = line
self.raw = raw.strip(" {;")
self.blame = blame
raw = raw.split()
self.name = raw[raw.index("package")+1]
self.name_path = self.name.split(".")
def __repr__(self):
return self.raw
def _parse_stream(f, api={}):
line = 0
pkg = None
clazz = None
blame = None
re_blame = re.compile("^([a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
for raw in f:
line += 1
raw = raw.rstrip()
match = re_blame.match(raw)
if match is not None:
blame = match.groups()[0:2]
raw = match.groups()[2]
else:
blame = None
if raw.startswith("package"):
pkg = Package(line, raw, blame)
elif raw.startswith(" ") and raw.endswith("{"):
clazz = Class(pkg, line, raw, blame)
api[clazz.fullname] = clazz
elif raw.startswith(" ctor"):
clazz.ctors.append(Method(clazz, line, raw, blame))
elif raw.startswith(" method"):
clazz.methods.append(Method(clazz, line, raw, blame))
elif raw.startswith(" field"):
clazz.fields.append(Field(clazz, line, raw, blame))
return api
def _parse_stream_path(path):
api = {}
print "Parsing", path
for f in os.listdir(path):
f = os.path.join(path, f)
if not os.path.isfile(f): continue
if not f.endswith(".txt"): continue
if f.endswith("removed.txt"): continue
print "\t", f
with open(f) as s:
api = _parse_stream(s, api)
print "Parsed", len(api), "APIs"
print
return api
class Failure():
def __init__(self, sig, clazz, detail, error, rule, msg):
self.sig = sig
self.error = error
self.rule = rule
self.msg = msg
if error:
self.head = "Error %s" % (rule) if rule else "Error"
dump = "%s%s:%s %s" % (format(fg=RED, bg=BLACK, bold=True), self.head, format(reset=True), msg)
else:
self.head = "Warning %s" % (rule) if rule else "Warning"
dump = "%s%s:%s %s" % (format(fg=YELLOW, bg=BLACK, bold=True), self.head, format(reset=True), msg)
self.line = clazz.line
blame = clazz.blame
if detail is not None:
dump += "\n in " + repr(detail)
self.line = detail.line
blame = detail.blame
dump += "\n in " + repr(clazz)
dump += "\n in " + repr(clazz.pkg)
dump += "\n at line " + repr(self.line)
if blame is not None:
dump += "\n last modified by %s in %s" % (blame[1], blame[0])
self.dump = dump
def __repr__(self):
return self.dump
failures = {}
def _fail(clazz, detail, error, rule, msg):
"""Records an API failure to be processed later."""
global failures
sig = "%s-%s-%s" % (clazz.fullname, repr(detail), msg)
sig = sig.replace(" deprecated ", " ")
failures[sig] = Failure(sig, clazz, detail, error, rule, msg)
def warn(clazz, detail, rule, msg):
_fail(clazz, detail, False, rule, msg)
def error(clazz, detail, rule, msg):
_fail(clazz, detail, True, rule, msg)
if __name__ == "__main__":
next_path = sys.argv[1]
prev_path = sys.argv[2]
next_api = _parse_stream_path(next_path)
prev_api = _parse_stream_path(prev_path)
# Remove all existing things so we're left with new
for prev_clazz in prev_api.values():
if prev_clazz.fullname not in next_api: continue
cur_clazz = next_api[prev_clazz.fullname]
sigs = { i.ident: i for i in prev_clazz.ctors }
cur_clazz.ctors = [ i for i in cur_clazz.ctors if i.ident not in sigs ]
sigs = { i.ident: i for i in prev_clazz.methods }
cur_clazz.methods = [ i for i in cur_clazz.methods if i.ident not in sigs ]
sigs = { i.ident: i for i in prev_clazz.fields }
cur_clazz.fields = [ i for i in cur_clazz.fields if i.ident not in sigs ]
# Forget about class entirely when nothing new
if len(cur_clazz.ctors) == 0 and len(cur_clazz.methods) == 0 and len(cur_clazz.fields) == 0:
del next_api[prev_clazz.fullname]
for clazz in next_api.values():
if "@Deprecated " in clazz.raw and not clazz.fullname in prev_api:
error(clazz, None, None, "Found API deprecation at birth")
if "@Deprecated " in clazz.raw: continue
for i in clazz.ctors + clazz.methods + clazz.fields:
if "@Deprecated " in i.raw:
error(clazz, i, None, "Found API deprecation at birth " + i.ident)
print "%s Deprecated at birth %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True),
format(reset=True)))
for f in sorted(failures):
print failures[f]
print