Loading ravenwood/scripts/pta-framework.sh 0 → 100755 +91 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright (C) 2024 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. # # Use "ravehleper pta" to create a shell script which: # - Reads the text "policy" files # - Convert to java annotations (using sed) # set -e # Uncomment it to always build ravenhelper (slow) # ${BUILD_CMD:-m} ravenhelper # Get the target directory. Default to $ANDROID_BUILD_TOP. TARGET_DIR="${TARGET_DIR:-${ANDROID_BUILD_TOP?\$ANDROID_BUILD_TOP must be set}}" echo "Target dir=$TARGET_DIR" cd "$TARGET_DIR" # Add -v or -d as needed. extra_args="$@" OUT_SCRIPT="${OUT_SCRIPT:-/tmp/pta.sh}" rm -f "$OUT_SCRIPT" # If you want to run on other files, run this script with the following # env vars predefined. POLICIES="${POLICIES:- frameworks/base/ravenwood/texts/ravenwood-common-policies.txt frameworks/base/ravenwood/texts/ravenwood-framework-policies.txt }" SOURCES="${SOURCES:- frameworks/base/core/java/ frameworks/base/graphics/java/ }" AAC="${AAC:-frameworks/base/ravenwood/texts/ravenwood-annotation-allowed-classes.txt}" with_flag() { local flag="$1" shift for arg in "$@"; do echo "$flag $arg" done } run() { echo "Running: $*" "$@" } run_pta() { local extra_args="$@" run ${RAVENHELPER_CMD:-ravenhelper pta} \ --output-script $OUT_SCRIPT \ --annotation-allowed-classes-file $AAC \ $(with_flag --policy-override-file $POLICIES) \ $(with_flag --src $SOURCES) \ $extra_args if ! [[ -f $OUT_SCRIPT ]] ; then # no operations generated. exit 0 fi echo echo "Created script at $OUT_SCRIPT. Run it with: sh $OUT_SCRIPT" return 0 } run_pta "$extra_args" No newline at end of file ravenwood/texts/ravenwood-common-policies.txt +5 −2 Original line number Diff line number Diff line # Ravenwood "policy" that should apply to all code. # The "no-pta" marker is used to exclude the lines from "ravenhelper pta", # which tries to convert policies to annotations. # Keep all AIDL interfaces class :aidl keepclass Loading @@ -13,8 +16,8 @@ class :sysprops keepclass class :r keepclass # Support APIs not available in standard JRE class java.io.FileDescriptor keep class java.io.FileDescriptor # no-pta method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$ method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$ class java.util.LinkedHashMap keep class java.util.LinkedHashMap # no-pta method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest ravenwood/texts/ravenwood-framework-policies.txt +38 −35 Original line number Diff line number Diff line # Ravenwood "policy" file for framework-minus-apex. # The "no-pta" marker is used to exclude the lines from "ravenhelper pta", # which tries to convert policies to annotations. # To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes. # Note: The "rename" directive must use slashes (/) as a package name separator. rename com/.*/nano/ devicenano/ rename android/.*/nano/ devicenano/ # StatsD auto-generated class com.android.internal.util.FrameworkStatsLog keepclass class com.android.internal.util.FrameworkStatsLog keepclass # no-pta # Exported to Mainline modules; cannot use annotations class com.android.internal.util.FastXmlSerializer keepclass class com.android.internal.util.FileRotator keepclass class com.android.internal.util.HexDump keepclass class com.android.internal.util.IndentingPrintWriter keepclass class com.android.internal.util.LocalLog keepclass class com.android.internal.util.MessageUtils keepclass class com.android.internal.util.TokenBucket keepclass class android.os.HandlerExecutor keepclass class android.util.BackupUtils keepclass class android.util.IndentingPrintWriter keepclass class android.util.LocalLog keepclass class android.util.Pair keepclass class android.util.Rational keepclass class com.android.internal.util.FastXmlSerializer keepclass # no-pta class com.android.internal.util.FileRotator keepclass # no-pta class com.android.internal.util.HexDump keepclass # no-pta class com.android.internal.util.IndentingPrintWriter keepclass # no-pta class com.android.internal.util.LocalLog keepclass # no-pta class com.android.internal.util.MessageUtils keepclass # no-pta class com.android.internal.util.TokenBucket keepclass # no-pta class android.os.HandlerExecutor keepclass # no-pta class android.util.BackupUtils keepclass # no-pta class android.util.IndentingPrintWriter keepclass # no-pta class android.util.LocalLog keepclass # no-pta class android.util.Pair keepclass # no-pta class android.util.Rational keepclass # no-pta # From modules-utils; cannot use annotations class com.android.internal.util.Preconditions keepclass class com.android.internal.logging.InstanceId keepclass class com.android.internal.logging.InstanceIdSequence keepclass class com.android.internal.logging.UiEvent keepclass class com.android.internal.logging.UiEventLogger keepclass class com.android.internal.util.Preconditions keepclass # no-pta class com.android.internal.logging.InstanceId keepclass # no-pta class com.android.internal.logging.InstanceIdSequence keepclass # no-pta class com.android.internal.logging.UiEvent keepclass # no-pta class com.android.internal.logging.UiEventLogger keepclass # no-pta # From modules-utils; cannot use annotations class com.android.modules.utils.BinaryXmlPullParser keepclass class com.android.modules.utils.BinaryXmlSerializer keepclass class com.android.modules.utils.FastDataInput keepclass class com.android.modules.utils.FastDataOutput keepclass class com.android.modules.utils.ModifiedUtf8 keepclass class com.android.modules.utils.TypedXmlPullParser keepclass class com.android.modules.utils.TypedXmlSerializer keepclass class com.android.modules.utils.BinaryXmlPullParser keepclass # no-pta class com.android.modules.utils.BinaryXmlSerializer keepclass # no-pta class com.android.modules.utils.FastDataInput keepclass # no-pta class com.android.modules.utils.FastDataOutput keepclass # no-pta class com.android.modules.utils.ModifiedUtf8 keepclass # no-pta class com.android.modules.utils.TypedXmlPullParser keepclass # no-pta class com.android.modules.utils.TypedXmlSerializer keepclass # no-pta # Uri class android.net.Uri keepclass class android.net.UriCodec keepclass class android.net.Uri keepclass # no-pta class android.net.UriCodec keepclass # no-pta # Telephony class android.telephony.PinResult keepclass class android.telephony.PinResult keepclass # no-pta # Just enough to support mocking, no further functionality class android.content.BroadcastReceiver keep class android.content.BroadcastReceiver keep # no-pta method <init> ()V keep class android.content.Context keep class android.content.Context keep # no-pta method <init> ()V keep method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep class android.content.pm.PackageManager method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep # no-pta class android.content.pm.PackageManager # no-pta method <init> ()V keep class android.text.ClipboardManager keep class android.text.ClipboardManager keep # no-pta method <init> ()V keep # Just enough to allow ResourcesManager to run class android.hardware.display.DisplayManagerGlobal keep class android.hardware.display.DisplayManagerGlobal keep # no-pta method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore ravenwood/texts/ravenwood-services-policies.txt +12 −9 Original line number Diff line number Diff line # Ravenwood "policy" file for services.core. # The "no-pta" marker is used to exclude the lines from "ravenhelper pta", # which tries to convert policies to annotations. # Auto-generated from XSD class com.android.server.compat.config.Change keepclass class com.android.server.compat.config.Config keepclass class com.android.server.compat.config.XmlParser keepclass class com.android.server.compat.overrides.ChangeOverrides keepclass class com.android.server.compat.overrides.OverrideValue keepclass class com.android.server.compat.overrides.Overrides keepclass class com.android.server.compat.overrides.RawOverrideValue keepclass class com.android.server.compat.overrides.XmlParser keepclass class com.android.server.compat.overrides.XmlWriter keepclass No newline at end of file class com.android.server.compat.config.Change keepclass # no-pta class com.android.server.compat.config.Config keepclass # no-pta class com.android.server.compat.config.XmlParser keepclass # no-pta class com.android.server.compat.overrides.ChangeOverrides keepclass # no-pta class com.android.server.compat.overrides.OverrideValue keepclass # no-pta class com.android.server.compat.overrides.Overrides keepclass # no-pta class com.android.server.compat.overrides.RawOverrideValue keepclass # no-pta class com.android.server.compat.overrides.XmlParser keepclass # no-pta class com.android.server.compat.overrides.XmlWriter keepclass # no-pta No newline at end of file ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt +17 −10 Original line number Diff line number Diff line Loading @@ -69,9 +69,9 @@ interface PolicyFileProcessor { fun onRename(pattern: Pattern, prefix: String) /** "class" directive. */ fun onSimpleClassStart(className: String) fun onClassStart(className: String) fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) fun onSimpleClassEnd(className: String) fun onClassEnd(className: String) fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason) fun onRedirectionClass(fromClassName: String, toClassName: String) Loading Loading @@ -162,10 +162,10 @@ class TextFileFilterPolicyBuilder( ) } override fun onSimpleClassStart(className: String) { override fun onClassStart(className: String) { } override fun onSimpleClassEnd(className: String) { override fun onClassEnd(className: String) { } override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) { Loading Loading @@ -273,20 +273,23 @@ class TextFileFilterPolicyParser { private var rFilePolicy: FilterPolicyWithReason? = null /** Name of the file that's currently being processed. */ var filename: String? = null var filename: String = "" private set /** 1-based line number in the current file */ var lineNumber = -1 private set /** Current line */ var currentLineText = "" private set /** * Parse a given "policy" file. */ fun parse(reader: Reader, inputName: String, processor: PolicyFileProcessor) { filename = inputName log.i("Parsing text policy file $inputName ...") this.processor = processor BufferedReader(reader).use { rd -> lineNumber = 0 Loading @@ -297,6 +300,7 @@ class TextFileFilterPolicyParser { break } lineNumber++ currentLineText = line line = normalizeTextLine(line) // Remove comment and trim. if (line.isEmpty()) { continue Loading @@ -312,7 +316,7 @@ class TextFileFilterPolicyParser { private fun finishLastClass() { currentClassName?.let { className -> processor.onSimpleClassEnd(className) processor.onClassEnd(className) currentClassName = null } } Loading Loading @@ -416,7 +420,7 @@ class TextFileFilterPolicyParser { if (fields.size <= 1) { throw ParseException("Class ('c') expects 1 or 2 fields.") } val className = fields[1] val className = fields[1].toHumanReadableClassName() // superClass is set when the class name starts with a "*". val superClass = resolveExtendingClass(className) Loading @@ -436,6 +440,8 @@ class TextFileFilterPolicyParser { // It's a redirection class. val toClass = policyStr.substring(1) currentClassName = className processor.onClassStart(className) processor.onRedirectionClass(className, toClass) } else if (policyStr.startsWith("~")) { if (classType != SpecialClass.NotSpecial) { Loading @@ -447,6 +453,8 @@ class TextFileFilterPolicyParser { // It's a class-load hook val callback = policyStr.substring(1) currentClassName = className processor.onClassStart(className) processor.onClassLoadHook(className, callback) } else { // Special case: if it's a class directive with no policy, then it encloses Loading @@ -455,7 +463,6 @@ class TextFileFilterPolicyParser { if (policyStr == "") { if (classType == SpecialClass.NotSpecial && superClass == null) { currentClassName = className processor.onSimpleClassStart(className) return } throw ParseException("Special class or subclass directive must have a policy") Loading @@ -471,7 +478,7 @@ class TextFileFilterPolicyParser { // TODO: Duplicate check, etc if (superClass == null) { currentClassName = className processor.onSimpleClassStart(className) processor.onClassStart(className) processor.onSimpleClassPolicy(className, policy.withReason(FILTER_REASON)) } else { processor.onSubClassPolicy( Loading Loading
ravenwood/scripts/pta-framework.sh 0 → 100755 +91 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright (C) 2024 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. # # Use "ravehleper pta" to create a shell script which: # - Reads the text "policy" files # - Convert to java annotations (using sed) # set -e # Uncomment it to always build ravenhelper (slow) # ${BUILD_CMD:-m} ravenhelper # Get the target directory. Default to $ANDROID_BUILD_TOP. TARGET_DIR="${TARGET_DIR:-${ANDROID_BUILD_TOP?\$ANDROID_BUILD_TOP must be set}}" echo "Target dir=$TARGET_DIR" cd "$TARGET_DIR" # Add -v or -d as needed. extra_args="$@" OUT_SCRIPT="${OUT_SCRIPT:-/tmp/pta.sh}" rm -f "$OUT_SCRIPT" # If you want to run on other files, run this script with the following # env vars predefined. POLICIES="${POLICIES:- frameworks/base/ravenwood/texts/ravenwood-common-policies.txt frameworks/base/ravenwood/texts/ravenwood-framework-policies.txt }" SOURCES="${SOURCES:- frameworks/base/core/java/ frameworks/base/graphics/java/ }" AAC="${AAC:-frameworks/base/ravenwood/texts/ravenwood-annotation-allowed-classes.txt}" with_flag() { local flag="$1" shift for arg in "$@"; do echo "$flag $arg" done } run() { echo "Running: $*" "$@" } run_pta() { local extra_args="$@" run ${RAVENHELPER_CMD:-ravenhelper pta} \ --output-script $OUT_SCRIPT \ --annotation-allowed-classes-file $AAC \ $(with_flag --policy-override-file $POLICIES) \ $(with_flag --src $SOURCES) \ $extra_args if ! [[ -f $OUT_SCRIPT ]] ; then # no operations generated. exit 0 fi echo echo "Created script at $OUT_SCRIPT. Run it with: sh $OUT_SCRIPT" return 0 } run_pta "$extra_args" No newline at end of file
ravenwood/texts/ravenwood-common-policies.txt +5 −2 Original line number Diff line number Diff line # Ravenwood "policy" that should apply to all code. # The "no-pta" marker is used to exclude the lines from "ravenhelper pta", # which tries to convert policies to annotations. # Keep all AIDL interfaces class :aidl keepclass Loading @@ -13,8 +16,8 @@ class :sysprops keepclass class :r keepclass # Support APIs not available in standard JRE class java.io.FileDescriptor keep class java.io.FileDescriptor # no-pta method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$ method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$ class java.util.LinkedHashMap keep class java.util.LinkedHashMap # no-pta method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest
ravenwood/texts/ravenwood-framework-policies.txt +38 −35 Original line number Diff line number Diff line # Ravenwood "policy" file for framework-minus-apex. # The "no-pta" marker is used to exclude the lines from "ravenhelper pta", # which tries to convert policies to annotations. # To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes. # Note: The "rename" directive must use slashes (/) as a package name separator. rename com/.*/nano/ devicenano/ rename android/.*/nano/ devicenano/ # StatsD auto-generated class com.android.internal.util.FrameworkStatsLog keepclass class com.android.internal.util.FrameworkStatsLog keepclass # no-pta # Exported to Mainline modules; cannot use annotations class com.android.internal.util.FastXmlSerializer keepclass class com.android.internal.util.FileRotator keepclass class com.android.internal.util.HexDump keepclass class com.android.internal.util.IndentingPrintWriter keepclass class com.android.internal.util.LocalLog keepclass class com.android.internal.util.MessageUtils keepclass class com.android.internal.util.TokenBucket keepclass class android.os.HandlerExecutor keepclass class android.util.BackupUtils keepclass class android.util.IndentingPrintWriter keepclass class android.util.LocalLog keepclass class android.util.Pair keepclass class android.util.Rational keepclass class com.android.internal.util.FastXmlSerializer keepclass # no-pta class com.android.internal.util.FileRotator keepclass # no-pta class com.android.internal.util.HexDump keepclass # no-pta class com.android.internal.util.IndentingPrintWriter keepclass # no-pta class com.android.internal.util.LocalLog keepclass # no-pta class com.android.internal.util.MessageUtils keepclass # no-pta class com.android.internal.util.TokenBucket keepclass # no-pta class android.os.HandlerExecutor keepclass # no-pta class android.util.BackupUtils keepclass # no-pta class android.util.IndentingPrintWriter keepclass # no-pta class android.util.LocalLog keepclass # no-pta class android.util.Pair keepclass # no-pta class android.util.Rational keepclass # no-pta # From modules-utils; cannot use annotations class com.android.internal.util.Preconditions keepclass class com.android.internal.logging.InstanceId keepclass class com.android.internal.logging.InstanceIdSequence keepclass class com.android.internal.logging.UiEvent keepclass class com.android.internal.logging.UiEventLogger keepclass class com.android.internal.util.Preconditions keepclass # no-pta class com.android.internal.logging.InstanceId keepclass # no-pta class com.android.internal.logging.InstanceIdSequence keepclass # no-pta class com.android.internal.logging.UiEvent keepclass # no-pta class com.android.internal.logging.UiEventLogger keepclass # no-pta # From modules-utils; cannot use annotations class com.android.modules.utils.BinaryXmlPullParser keepclass class com.android.modules.utils.BinaryXmlSerializer keepclass class com.android.modules.utils.FastDataInput keepclass class com.android.modules.utils.FastDataOutput keepclass class com.android.modules.utils.ModifiedUtf8 keepclass class com.android.modules.utils.TypedXmlPullParser keepclass class com.android.modules.utils.TypedXmlSerializer keepclass class com.android.modules.utils.BinaryXmlPullParser keepclass # no-pta class com.android.modules.utils.BinaryXmlSerializer keepclass # no-pta class com.android.modules.utils.FastDataInput keepclass # no-pta class com.android.modules.utils.FastDataOutput keepclass # no-pta class com.android.modules.utils.ModifiedUtf8 keepclass # no-pta class com.android.modules.utils.TypedXmlPullParser keepclass # no-pta class com.android.modules.utils.TypedXmlSerializer keepclass # no-pta # Uri class android.net.Uri keepclass class android.net.UriCodec keepclass class android.net.Uri keepclass # no-pta class android.net.UriCodec keepclass # no-pta # Telephony class android.telephony.PinResult keepclass class android.telephony.PinResult keepclass # no-pta # Just enough to support mocking, no further functionality class android.content.BroadcastReceiver keep class android.content.BroadcastReceiver keep # no-pta method <init> ()V keep class android.content.Context keep class android.content.Context keep # no-pta method <init> ()V keep method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep class android.content.pm.PackageManager method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep # no-pta class android.content.pm.PackageManager # no-pta method <init> ()V keep class android.text.ClipboardManager keep class android.text.ClipboardManager keep # no-pta method <init> ()V keep # Just enough to allow ResourcesManager to run class android.hardware.display.DisplayManagerGlobal keep class android.hardware.display.DisplayManagerGlobal keep # no-pta method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
ravenwood/texts/ravenwood-services-policies.txt +12 −9 Original line number Diff line number Diff line # Ravenwood "policy" file for services.core. # The "no-pta" marker is used to exclude the lines from "ravenhelper pta", # which tries to convert policies to annotations. # Auto-generated from XSD class com.android.server.compat.config.Change keepclass class com.android.server.compat.config.Config keepclass class com.android.server.compat.config.XmlParser keepclass class com.android.server.compat.overrides.ChangeOverrides keepclass class com.android.server.compat.overrides.OverrideValue keepclass class com.android.server.compat.overrides.Overrides keepclass class com.android.server.compat.overrides.RawOverrideValue keepclass class com.android.server.compat.overrides.XmlParser keepclass class com.android.server.compat.overrides.XmlWriter keepclass No newline at end of file class com.android.server.compat.config.Change keepclass # no-pta class com.android.server.compat.config.Config keepclass # no-pta class com.android.server.compat.config.XmlParser keepclass # no-pta class com.android.server.compat.overrides.ChangeOverrides keepclass # no-pta class com.android.server.compat.overrides.OverrideValue keepclass # no-pta class com.android.server.compat.overrides.Overrides keepclass # no-pta class com.android.server.compat.overrides.RawOverrideValue keepclass # no-pta class com.android.server.compat.overrides.XmlParser keepclass # no-pta class com.android.server.compat.overrides.XmlWriter keepclass # no-pta No newline at end of file
ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt +17 −10 Original line number Diff line number Diff line Loading @@ -69,9 +69,9 @@ interface PolicyFileProcessor { fun onRename(pattern: Pattern, prefix: String) /** "class" directive. */ fun onSimpleClassStart(className: String) fun onClassStart(className: String) fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) fun onSimpleClassEnd(className: String) fun onClassEnd(className: String) fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason) fun onRedirectionClass(fromClassName: String, toClassName: String) Loading Loading @@ -162,10 +162,10 @@ class TextFileFilterPolicyBuilder( ) } override fun onSimpleClassStart(className: String) { override fun onClassStart(className: String) { } override fun onSimpleClassEnd(className: String) { override fun onClassEnd(className: String) { } override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) { Loading Loading @@ -273,20 +273,23 @@ class TextFileFilterPolicyParser { private var rFilePolicy: FilterPolicyWithReason? = null /** Name of the file that's currently being processed. */ var filename: String? = null var filename: String = "" private set /** 1-based line number in the current file */ var lineNumber = -1 private set /** Current line */ var currentLineText = "" private set /** * Parse a given "policy" file. */ fun parse(reader: Reader, inputName: String, processor: PolicyFileProcessor) { filename = inputName log.i("Parsing text policy file $inputName ...") this.processor = processor BufferedReader(reader).use { rd -> lineNumber = 0 Loading @@ -297,6 +300,7 @@ class TextFileFilterPolicyParser { break } lineNumber++ currentLineText = line line = normalizeTextLine(line) // Remove comment and trim. if (line.isEmpty()) { continue Loading @@ -312,7 +316,7 @@ class TextFileFilterPolicyParser { private fun finishLastClass() { currentClassName?.let { className -> processor.onSimpleClassEnd(className) processor.onClassEnd(className) currentClassName = null } } Loading Loading @@ -416,7 +420,7 @@ class TextFileFilterPolicyParser { if (fields.size <= 1) { throw ParseException("Class ('c') expects 1 or 2 fields.") } val className = fields[1] val className = fields[1].toHumanReadableClassName() // superClass is set when the class name starts with a "*". val superClass = resolveExtendingClass(className) Loading @@ -436,6 +440,8 @@ class TextFileFilterPolicyParser { // It's a redirection class. val toClass = policyStr.substring(1) currentClassName = className processor.onClassStart(className) processor.onRedirectionClass(className, toClass) } else if (policyStr.startsWith("~")) { if (classType != SpecialClass.NotSpecial) { Loading @@ -447,6 +453,8 @@ class TextFileFilterPolicyParser { // It's a class-load hook val callback = policyStr.substring(1) currentClassName = className processor.onClassStart(className) processor.onClassLoadHook(className, callback) } else { // Special case: if it's a class directive with no policy, then it encloses Loading @@ -455,7 +463,6 @@ class TextFileFilterPolicyParser { if (policyStr == "") { if (classType == SpecialClass.NotSpecial && superClass == null) { currentClassName = className processor.onSimpleClassStart(className) return } throw ParseException("Special class or subclass directive must have a policy") Loading @@ -471,7 +478,7 @@ class TextFileFilterPolicyParser { // TODO: Duplicate check, etc if (superClass == null) { currentClassName = className processor.onSimpleClassStart(className) processor.onClassStart(className) processor.onSimpleClassPolicy(className, policy.withReason(FILTER_REASON)) } else { processor.onSubClassPolicy( Loading