From 11c37085510fe48d6071abfd94594608bf7cca28 Mon Sep 17 00:00:00 2001 From: Ashley Rose Date: Mon, 25 Feb 2019 18:02:17 -0500 Subject: Add @InspectableProperty annotation This is a drop-in replacement for the platform's @InspectableProperty annotation without any platform dependencies. Test: ./gradlew annotation:build Bug: 126246418 Change-Id: I4e3455c08cd257d6233ccaf7409382f9cd89cfce --- annotations/api/1.1.0-alpha02.txt | 29 ++++ annotations/api/current.txt | 29 ++++ .../androidx/annotation/InspectableProperty.java | 191 +++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 annotations/src/main/java/androidx/annotation/InspectableProperty.java (limited to 'annotations') diff --git a/annotations/api/1.1.0-alpha02.txt b/annotations/api/1.1.0-alpha02.txt index d66f9f581bf..7226b137ff4 100644 --- a/annotations/api/1.1.0-alpha02.txt +++ b/annotations/api/1.1.0-alpha02.txt @@ -81,6 +81,35 @@ package androidx.annotation { @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface IdRes { } + @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface InspectableProperty { + method public abstract int attributeId() default 0; + method public abstract androidx.annotation.InspectableProperty.EnumMap[] enumMapping() default {}; + method public abstract androidx.annotation.InspectableProperty.FlagMap[] flagMapping() default {}; + method public abstract boolean hasAttributeId() default true; + method public abstract String name() default ""; + method public abstract androidx.annotation.InspectableProperty.ValueType valueType() default androidx.annotation.InspectableProperty.ValueType.INFERRED; + } + + @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface InspectableProperty.EnumMap { + method public abstract String name(); + method public abstract int value(); + } + + @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface InspectableProperty.FlagMap { + method public abstract int mask() default 0; + method public abstract String name(); + method public abstract int target(); + } + + public enum InspectableProperty.ValueType { + enum_constant public static final androidx.annotation.InspectableProperty.ValueType COLOR; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType GRAVITY; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType INFERRED; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType INT_ENUM; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType INT_FLAG; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType NONE; + } + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.ANNOTATION_TYPE}) public @interface IntDef { method public abstract boolean flag() default false; method public abstract boolean open() default false; diff --git a/annotations/api/current.txt b/annotations/api/current.txt index d66f9f581bf..7226b137ff4 100644 --- a/annotations/api/current.txt +++ b/annotations/api/current.txt @@ -81,6 +81,35 @@ package androidx.annotation { @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface IdRes { } + @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface InspectableProperty { + method public abstract int attributeId() default 0; + method public abstract androidx.annotation.InspectableProperty.EnumMap[] enumMapping() default {}; + method public abstract androidx.annotation.InspectableProperty.FlagMap[] flagMapping() default {}; + method public abstract boolean hasAttributeId() default true; + method public abstract String name() default ""; + method public abstract androidx.annotation.InspectableProperty.ValueType valueType() default androidx.annotation.InspectableProperty.ValueType.INFERRED; + } + + @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface InspectableProperty.EnumMap { + method public abstract String name(); + method public abstract int value(); + } + + @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface InspectableProperty.FlagMap { + method public abstract int mask() default 0; + method public abstract String name(); + method public abstract int target(); + } + + public enum InspectableProperty.ValueType { + enum_constant public static final androidx.annotation.InspectableProperty.ValueType COLOR; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType GRAVITY; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType INFERRED; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType INT_ENUM; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType INT_FLAG; + enum_constant public static final androidx.annotation.InspectableProperty.ValueType NONE; + } + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.ANNOTATION_TYPE}) public @interface IntDef { method public abstract boolean flag() default false; method public abstract boolean open() default false; diff --git a/annotations/src/main/java/androidx/annotation/InspectableProperty.java b/annotations/src/main/java/androidx/annotation/InspectableProperty.java new file mode 100644 index 00000000000..634210f2651 --- /dev/null +++ b/annotations/src/main/java/androidx/annotation/InspectableProperty.java @@ -0,0 +1,191 @@ +/* + * Copyright 2019 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. + */ + +package androidx.annotation; + + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Denotes that the annotated method is the getter for a resources-backed property that should be + * shown in Android Studio's inspection tools. + */ +@Target({METHOD}) +@Retention(SOURCE) +public @interface InspectableProperty { + /** + * The name of the property. + * + * If left empty (the default), the property name will be inferred from the name of the getter + * method. + * + * @return The name of the property. + */ + String name() default ""; + + /** + * If the property is inflated from XML, the resource ID of its XML attribute. + * + * If left as the default, and {@link #hasAttributeId()} is true, the attribute ID will be + * inferred from {@link #name()}. + * + * @return The attribute ID of the property or the default null resource ID + */ + int attributeId() default 0; + + /** + * If this property has an attribute ID. + * + * Set to false if the annotated property does not have an attribute ID, that is, it is not + * inflated from an XML attribute. This will prevent the automatic inference of the attribute. + * + * @return Whether to infer an attribute ID if not supplied + */ + boolean hasAttributeId() default true; + + /** + * Specify how to interpret a value type packed into a primitive integer. + * + * @return A {@link ValueType} + */ + ValueType valueType() default ValueType.INFERRED; + + /** + * For enumerations packed into primitive {int} properties, map the values to string names. + * + * Note that {@code #enumMapping()} cannot be used simultaneously with {@link #flagMapping()}. + * + * @return An array of {@link EnumMap}, empty if not applicable + */ + EnumMap[] enumMapping() default {}; + + /** + * For flags packed into primitive {int} properties, model the string names of the flags. + * + * Note that {@code #flagMapping()} cannot be used simultaneously with {@link #enumMapping()}. + * + * @return An array of {@link FlagMap}, empty if not applicable + */ + FlagMap[] flagMapping() default {}; + + + /** + * One entry in an enumeration packed into a primitive {int}. + */ + @Target({TYPE}) + @Retention(SOURCE) + @interface EnumMap { + /** + * The string name of this enumeration value. + * + * @return A string name + */ + String name(); + + /** + * The integer value of this enumeration value. + * + * @return An integer value + */ + int value(); + } + + /** + * One flag value of many that may be packed into a primitive {int}. + */ + @Target({TYPE}) + @Retention(SOURCE) + @interface FlagMap { + /** + * The string name of this flag. + * + * @return A string name + */ + String name(); + + /** + * A target value that the property's value must equal after masking. + * + * If a mask is not supplied (i.e., {@link #mask()} is 0), the target will be reused as the + * mask. This handles the common case where no flags mutually exclude each other. + * + * @return The target value to compare against + */ + int target(); + + /** + * A mask that the property will be bitwise anded with before comparing to the target. + * + * If set to 0 (the default), the value of {@link #target()} will be used as a mask. Zero + * was chosen as the default since bitwise and with zero is always zero. + * + * @return A mask, or 0 to use the target as a mask + */ + int mask() default 0; + } + + /** + * The type of value packed into a primitive {int}. + */ + enum ValueType { + /** + * No special handling, property is considered to be a numeric value. + */ + NONE, + + /** + * The default the annotation processor infers the value type from context. + */ + INFERRED, + + /** + * Value packs an enumeration. + * + * This is inferred if {@link #enumMapping()} is specified. + * + * @see EnumMap + */ + INT_ENUM, + + /** + * Value packs flags, of which many may be enabled at once. + * + * This is inferred if {@link #flagMapping()} is specified. + * + * @see FlagMap + */ + INT_FLAG, + + /** + * Value packs color information. + * + * This is inferred from {@link ColorInt}, or {@link ColorLong} on the getter method. + */ + COLOR, + + /** + * Value packs gravity information. + * + * This type is not inferred and is non-trivial to represent using {@link FlagMap}. + */ + GRAVITY + } +} -- cgit v1.2.3