diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 4eefbdf2856d2cd9e7aa3fe3ce2640b6983a646a..b63075d521d6f8fb6d3cef8f76658e6d4cf35e98 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,6 +2,10 @@ <project version="4"> <component name="CompilerConfiguration"> <bytecodeTargetLevel> + <module name="com.android.metalava.main" target="1.8" /> + <module name="com.android.metalava.test" target="1.8" /> + <module name="metalava.stub-annotations.main" target="1.8" /> + <module name="metalava.stub-annotations.test" target="1.8" /> <module name="metalava_main" target="1.8" /> <module name="metalava_test" target="1.8" /> <module name="stub-annotations_main" target="1.8" /> diff --git a/.idea/dictionaries/metalava.xml b/.idea/dictionaries/metalava.xml index f4d43e6b71c24d320e4b3d0eb020554d1d406200..5e8d3c56afeeb36e82748b556aac6b551a5732cd 100644 --- a/.idea/dictionaries/metalava.xml +++ b/.idea/dictionaries/metalava.xml @@ -2,30 +2,42 @@ <dictionary name="metalava"> <words> <w>androidx</w> + <w>anim</w> <w>apidocsdir</w> + <w>apis</w> <w>argnum</w> <w>bootclasspath</w> <w>bytecode</w> <w>canonicalized</w> + <w>cherrypick</w> + <w>clinit</w> <w>codebases</w> <w>compat</w> <w>ctor</w> <w>dataname</w> <w>devsite</w> + <w>dimen</w> <w>doclava</w> <w>doclet</w> <w>docletpath</w> <w>doconly</w> <w>dokka</w> + <w>droiddoc</w> <w>federationapi</w> + <w>filenames</w> <w>gcmref</w> + <w>genrule</w> <w>gitiles</w> + <w>gradle</w> <w>htmldir</w> <w>ide</w> <w>ident</w> <w>includeable</w> <w>inheritdoc</w> <w>initializers</w> + <w>inlined</w> + <w>innerclass</w> + <w>instanceof</w> <w>interop</w> <w>intra</w> <w>jaif</w> @@ -37,6 +49,7 @@ <w>lerror</w> <w>libcore</w> <w>libraryroot</w> + <w>loggable</w> <w>metalava</w> <w>mmodule</w> <w>navtree</w> @@ -47,7 +60,9 @@ <w>nullness</w> <w>offlinemode</w> <w>parsecomments</w> + <w>prebuilts</w> <w>proguard</w> + <w>quickfix</w> <w>realtime</w> <w>referenceonly</w> <w>resourcesdir</w> @@ -60,23 +75,30 @@ <w>skipnative</w> <w>skippable</w> <w>snackbar</w> + <w>soong</w> <w>sourcepath</w> + <w>spannable</w> + <w>srcjar</w> <w>staticonly</w> <w>strippable</w> <w>stubimportpackages</w> <w>stubpackages</w> <w>stubsourceonly</w> + <w>styleable</w> <w>templatedir</w> <w>throwables</w> <w>toroot</w> <w>typelist</w> <w>typemap</w> + <w>unescape</w> <w>unhide</w> + <w>uninstantiable</w> <w>unshorten</w> + <w>usecase</w> <w>werror</w> <w>xmlfile</w> <w>yaml</w> <w>zipfile</w> </words> </dictionary> -</component> +</component> \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 42f9f3aa07739e4c8dffc0469320abc5470fdf57..63de93b07485eacb7c8ad18a8fb1962365cfa5d7 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,6 +1,7 @@ <component name="InspectionProjectProfileManager"> <profile version="1.0"> <option name="myName" value="Project Default" /> + <inspection_tool class="GroovyAssignabilityCheck" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="KotlinUnusedImport" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="LoopToCallChain" enabled="false" level="INFO" enabled_by_default="false" /> <inspection_tool class="RedundantSemicolon" enabled="true" level="ERROR" enabled_by_default="true" /> diff --git a/build.gradle b/build.gradle index 0e03028fdeea96686556b5fc0bfbaab4295a0ada..f2acfee811b88b3bc7d8c019b0d3e296b50d23e1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { - ext.gradle_version = '3.3.0-beta01' - ext.studio_version = '26.3.0-beta01' + ext.gradle_version = '3.2.1' + ext.studio_version = '26.2.1' ext.kotlin_version = '1.3.0' repositories { google() diff --git a/gradle.properties b/gradle.properties index 8998b2fd452762caf948d6be88d6f275299e5c14..e1841e4e83bcdb571bb4a8808292197999631faf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,4 @@ +# suppress inspection "UnusedProperty" for whole file org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m org.gradle.daemon=true kotlin.incremental.usePreciseJavaTracking=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index de4abd613518744ba3911370ba1a68990f44b9b9..7e98c337e7d3b987786c1e9498d294ccdc673c90 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,5 @@ #Sat Jan 13 09:12:34 PST 2018 +# suppress inspection "UnusedProperty" for whole file distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/com/android/tools/metalava/AnnotationStatistics.kt b/src/main/java/com/android/tools/metalava/AnnotationStatistics.kt index a93e8b50fba497db0c62af7d305edb241fb7e752..b6b7b197af7573325898d134fcc0767300696abb 100644 --- a/src/main/java/com/android/tools/metalava/AnnotationStatistics.kt +++ b/src/main/java/com/android/tools/metalava/AnnotationStatistics.kt @@ -320,7 +320,7 @@ class AnnotationStatistics(val api: Codebase) { { val member = it as MemberItem "${member.containingClass().simpleName()}.${member.name()}${if (member is MethodItem) "(${member.parameters().joinToString { - it.type().toSimpleType() + parameter -> parameter.type().toSimpleType() }})" else ""}" }, { used[it]!! }, diff --git a/src/main/java/com/android/tools/metalava/ApiAnalyzer.kt b/src/main/java/com/android/tools/metalava/ApiAnalyzer.kt index 306af7664260c49eaec870513aeaad166aa0579f..96a62957941431538693de3c47dfdad8e6e3fb05 100644 --- a/src/main/java/com/android/tools/metalava/ApiAnalyzer.kt +++ b/src/main/java/com/android/tools/metalava/ApiAnalyzer.kt @@ -496,6 +496,7 @@ class ApiAnalyzer( // The documentation may use relative references to classes in import statements // in the original class, so expand the documentation to be fully qualified. + @Suppress("ConstantConditionIf") if (!EXPAND_DOCUMENTATION) { method.documentation = it.fullyQualifiedDocumentation() } @@ -544,12 +545,10 @@ class ApiAnalyzer( private fun propagateHiddenRemovedAndDocOnly(includingFields: Boolean) { packages.accept(object : ItemVisitor(visitConstructorsAsMethods = true, nestInnerClasses = true) { override fun visitPackage(pkg: PackageItem) { - if (options.hidePackages.contains(pkg.qualifiedName())) { - pkg.hidden = true - } else if (pkg.modifiers.hasShowAnnotation()) { - pkg.hidden = false - } else if (pkg.modifiers.hasHideAnnotations()) { - pkg.hidden = true + when { + options.hidePackages.contains(pkg.qualifiedName()) -> pkg.hidden = true + pkg.modifiers.hasShowAnnotation() -> pkg.hidden = false + pkg.modifiers.hasHideAnnotations() -> pkg.hidden = true } val containingPackage = pkg.containingPackage() if (containingPackage != null) { diff --git a/src/main/java/com/android/tools/metalava/NullablityAnnotationsValidator.kt b/src/main/java/com/android/tools/metalava/NullabilityAnnotationsValidator.kt similarity index 99% rename from src/main/java/com/android/tools/metalava/NullablityAnnotationsValidator.kt rename to src/main/java/com/android/tools/metalava/NullabilityAnnotationsValidator.kt index 5f974028009ad33bb7c1e5a1524bcfef5649c046..b3033f27e7df1c6bd336eaded179c5d96499dc58 100644 --- a/src/main/java/com/android/tools/metalava/NullablityAnnotationsValidator.kt +++ b/src/main/java/com/android/tools/metalava/NullabilityAnnotationsValidator.kt @@ -33,7 +33,7 @@ private const val RETURN_LABEL = "return value" /** * Class that validates nullability annotations in the codebase. */ -class NullablityAnnotationsValidator() { +class NullabilityAnnotationsValidator { private enum class ErrorType { MULTIPLE, diff --git a/src/main/java/com/android/tools/metalava/Options.kt b/src/main/java/com/android/tools/metalava/Options.kt index 30eb25d9962a325b6f3ea67d8633d94a33fef9fe..2608553e779486469ff5560e2799781303143842 100644 --- a/src/main/java/com/android/tools/metalava/Options.kt +++ b/src/main/java/com/android/tools/metalava/Options.kt @@ -181,7 +181,7 @@ class Options( /** * Validator for nullability annotations, if validation is enabled. */ - var nullabilityAnnotationsValidator: NullablityAnnotationsValidator? = null + var nullabilityAnnotationsValidator: NullabilityAnnotationsValidator? = null /** * Whether nullability validation errors should be considered fatal. @@ -386,7 +386,7 @@ class Options( var migrateNullsFrom: File? = null /** Private backing list for [compatibilityChecks]] */ - private var mutableCompatibilityChecks: MutableList<CheckRequest> = mutableListOf<CheckRequest>() + private var mutableCompatibilityChecks: MutableList<CheckRequest> = mutableListOf() /** The list of compatibility checks to run */ val compatibilityChecks: List<CheckRequest> = mutableCompatibilityChecks @@ -563,7 +563,7 @@ class Options( ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS -> { validateNullabilityFromMergedStubs = true nullabilityAnnotationsValidator = - nullabilityAnnotationsValidator ?: NullablityAnnotationsValidator() + nullabilityAnnotationsValidator ?: NullabilityAnnotationsValidator() } ARG_NULLABILITY_WARNINGS_TXT -> nullabilityWarningsTxt = stringToNewFile(getValue(args, ++index)) diff --git a/src/main/java/com/android/tools/metalava/Reporter.kt b/src/main/java/com/android/tools/metalava/Reporter.kt index 6367a9156dff307c3636aa79896236ba9467ce57..39147f2e9afec95e14a396ffe73002fd2f035de8 100644 --- a/src/main/java/com/android/tools/metalava/Reporter.kt +++ b/src/main/java/com/android/tools/metalava/Reporter.kt @@ -210,7 +210,7 @@ open class Reporter(private val rootFolder: File? = null) { } else { getLineNumber(psiFile.text, range.startOffset) + 1 } - return "$path:$lineNumber" + return if (lineNumber > 0) "$path:$lineNumber" else path } /** Returns the 0-based line number */ diff --git a/src/main/java/com/android/tools/metalava/StubWriter.kt b/src/main/java/com/android/tools/metalava/StubWriter.kt index a4588fc7f6e1360658708f1035503ca9fccbb104..dfe4730ddcc9126af07d39ef18dbdd687ad1e8ea 100644 --- a/src/main/java/com/android/tools/metalava/StubWriter.kt +++ b/src/main/java/com/android/tools/metalava/StubWriter.kt @@ -207,6 +207,7 @@ class StubWriter( writer.println() } + @Suppress("ConstantConditionIf") if (EXPAND_DOCUMENTATION) { compilationUnit?.getImportStatements(filterReference)?.let { for (item in it) { diff --git a/src/main/java/com/android/tools/metalava/apilevels/AndroidJarReader.java b/src/main/java/com/android/tools/metalava/apilevels/AndroidJarReader.java index c0e833e193503722228a53a77778db1abdf58308..59f467baac7c03bacbfe1a1f54413ed2538aa1d9 100644 --- a/src/main/java/com/android/tools/metalava/apilevels/AndroidJarReader.java +++ b/src/main/java/com/android/tools/metalava/apilevels/AndroidJarReader.java @@ -120,12 +120,6 @@ class AndroidJarReader { if (name.endsWith(".class")) { byte[] bytes = ByteStreams.toByteArray(zis); - if (bytes == null) { - System.err.println("Warning: Couldn't read " + name); - entry = zis.getNextEntry(); - continue; - } - ClassReader reader = new ClassReader(bytes); ClassNode classNode = new ClassNode(Opcodes.ASM5); reader.accept(classNode, 0 /*flags*/); diff --git a/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java b/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java index 7547080a175ab2cc07991c1837417a7f51230a5f..a8e11dd7f95a903a0966ec681efd0ba73f5cc141 100644 --- a/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java +++ b/src/main/java/com/android/tools/metalava/doclava1/ApiFile.java @@ -283,7 +283,6 @@ public class ApiFile { throw new ApiParseException("Did you forget to supply --input-kotlin-nulls? Found Kotlin-style null type suffix when parser was not configured " + "to interpret signature file that way: " + type); } - //noinspection unchecked return new Pair<>(type, annotations); } @@ -381,7 +380,6 @@ public class ApiFile { if (returnTypeString.contains("@") && (returnTypeString.indexOf('<') == -1 || returnTypeString.indexOf('@') < returnTypeString.indexOf('<'))) { - //noinspection StringConcatenationInLoop returnTypeString += " " + token; token = tokenizer.requireToken(); } @@ -581,51 +579,61 @@ public class ApiFile { private static Object parseValue(String type, String val) { if (val != null) { - if ("boolean".equals(type)) { - return "true".equals(val) ? Boolean.TRUE : Boolean.FALSE; - } else if ("byte".equals(type)) { - return Integer.valueOf(val); - } else if ("short".equals(type)) { - return Integer.valueOf(val); - } else if ("int".equals(type)) { - return Integer.valueOf(val); - } else if ("long".equals(type)) { - return Long.valueOf(val.substring(0, val.length() - 1)); - } else if ("float".equals(type)) { - if ("(1.0f/0.0f)".equals(val) || "(1.0f / 0.0f)".equals(val)) { - return Float.POSITIVE_INFINITY; - } else if ("(-1.0f/0.0f)".equals(val) || "(-1.0f / 0.0f)".equals(val)) { - return Float.NEGATIVE_INFINITY; - } else if ("(0.0f/0.0f)".equals(val) || "(0.0f / 0.0f)".equals(val)) { - return Float.NaN; - } else { - return Float.valueOf(val); - } - } else if ("double".equals(type)) { - if ("(1.0/0.0)".equals(val) || "(1.0 / 0.0)".equals(val)) { - return Double.POSITIVE_INFINITY; - } else if ("(-1.0/0.0)".equals(val) || "(-1.0 / 0.0)".equals(val)) { - return Double.NEGATIVE_INFINITY; - } else if ("(0.0/0.0)".equals(val) || "(0.0 / 0.0)".equals(val)) { - return Double.NaN; - } else { - return Double.valueOf(val); - } - } else if ("char".equals(type)) { - return (char) Integer.parseInt(val); - } else if (JAVA_LANG_STRING.equals(type) || "String".equals(type)) { - if ("null".equals(val)) { + switch (type) { + case "boolean": + return "true".equals(val) ? Boolean.TRUE : Boolean.FALSE; + case "byte": + return Integer.valueOf(val); + case "short": + return Integer.valueOf(val); + case "int": + return Integer.valueOf(val); + case "long": + return Long.valueOf(val.substring(0, val.length() - 1)); + case "float": + switch (val) { + case "(1.0f/0.0f)": + case "(1.0f / 0.0f)": + return Float.POSITIVE_INFINITY; + case "(-1.0f/0.0f)": + case "(-1.0f / 0.0f)": + return Float.NEGATIVE_INFINITY; + case "(0.0f/0.0f)": + case "(0.0f / 0.0f)": + return Float.NaN; + default: + return Float.valueOf(val); + } + case "double": + switch (val) { + case "(1.0/0.0)": + case "(1.0 / 0.0)": + return Double.POSITIVE_INFINITY; + case "(-1.0/0.0)": + case "(-1.0 / 0.0)": + return Double.NEGATIVE_INFINITY; + case "(0.0/0.0)": + case "(0.0 / 0.0)": + return Double.NaN; + default: + return Double.valueOf(val); + } + case "char": + return (char) Integer.parseInt(val); + case JAVA_LANG_STRING: + case "String": + if ("null".equals(val)) { + return null; + } else { + return javaUnescapeString(val.substring(1, val.length() - 1)); + } + case "null": return null; - } else { - return javaUnescapeString(val.substring(1, val.length() - 1)); - } + default: + return val; } } - if ("null".equals(val)) { - return null; - } else { - return val; - } + return null; } private static void parseProperty(TextCodebase api, Tokenizer tokenizer, TextClassItem cl, String token) diff --git a/src/main/java/com/android/tools/metalava/doclava1/ApiParseException.java b/src/main/java/com/android/tools/metalava/doclava1/ApiParseException.java index ff1ba9d2c4e8411389999135871a36729968f0f8..0b3a6589499a2344d07d4aa9a288208f16e5ca64 100644 --- a/src/main/java/com/android/tools/metalava/doclava1/ApiParseException.java +++ b/src/main/java/com/android/tools/metalava/doclava1/ApiParseException.java @@ -58,7 +58,7 @@ public final class ApiParseException extends Exception { sb.append(file).append(':'); } if (line > 0) { - sb.append(Integer.toString(line)).append(':'); + sb.append(line).append(':'); } if (sb.length() > 0) { sb.append(' '); diff --git a/src/main/java/com/android/tools/metalava/doclava1/Errors.java b/src/main/java/com/android/tools/metalava/doclava1/Errors.java index 37fce50907fbf4ac4abc6488b4f02fc9716015e9..c7dd573331377e0790ac1d82b0a475829ed9227a 100644 --- a/src/main/java/com/android/tools/metalava/doclava1/Errors.java +++ b/src/main/java/com/android/tools/metalava/doclava1/Errors.java @@ -40,11 +40,11 @@ public class Errors { public static class Error { public final int code; @Nullable - public String fieldName; + String fieldName; private Severity level; private final Severity defaultLevel; - public boolean setByUser; + boolean setByUser; /** * The name of this error if known diff --git a/src/main/java/com/android/tools/metalava/model/AnnotationTarget.kt b/src/main/java/com/android/tools/metalava/model/AnnotationTarget.kt index b0c4b63aea43706bc9ed5783cf9ffcdeecbed086..82671f035f802d179f1d270a7c1e7672699a8ffe 100644 --- a/src/main/java/com/android/tools/metalava/model/AnnotationTarget.kt +++ b/src/main/java/com/android/tools/metalava/model/AnnotationTarget.kt @@ -41,7 +41,7 @@ val NO_ANNOTATION_TARGETS = setOf(AnnotationTarget.NONE) /** * Annotation is API significant: write it into the signature file and stub source code. * This would normally be the case for all (API significant) class-retention annotations, - * but unfortunately due to apt (the annotation proessor) attempting to load all + * but unfortunately due to apt (the annotation processor) attempting to load all * classes for annotation references that it comes across, that means we cannot * compile the stubs with the androidx annotations and leave those in the SDK; apt * would also need to have androidx on the classpath. So instead we put all these diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiBasedCodebase.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiBasedCodebase.kt index 78ea9ac3db041e7ee606f0ff716b67b87f731b4a..54fa0fbd350867b282893481142432a8a964ee18 100644 --- a/src/main/java/com/android/tools/metalava/model/psi/PsiBasedCodebase.kt +++ b/src/main/java/com/android/tools/metalava/model/psi/PsiBasedCodebase.kt @@ -123,7 +123,7 @@ open class PsiBasedCodebase(location: File, override var description: String = " packageClasses = HashMap(PACKAGE_ESTIMATE) packageClasses[""] = ArrayList() this.methodMap = HashMap(METHOD_ESTIMATE) - topLevelClassesFromSource = ArrayList<ClassItem>(CLASS_ESTIMATE) + topLevelClassesFromSource = ArrayList(CLASS_ESTIMATE) for (unit in units) { tick() // show progress @@ -297,7 +297,7 @@ open class PsiBasedCodebase(location: File, override var description: String = " ) packageToClasses[""] = ArrayList() // ensure we construct one for the default package - topLevelClassesFromSource = ArrayList<ClassItem>(CLASS_ESTIMATE) + topLevelClassesFromSource = ArrayList(CLASS_ESTIMATE) try { ZipFile(jarFile).use { jar -> diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiItem.kt index b108e0aeb2329a52baa5c4ea4de50a5be3480d6d..a8251a51307fa4815767959359deee5c7c99d97b 100644 --- a/src/main/java/com/android/tools/metalava/model/psi/PsiItem.kt +++ b/src/main/java/com/android/tools/metalava/model/psi/PsiItem.kt @@ -35,6 +35,7 @@ abstract class PsiItem( override var documentation: String ) : DefaultItem() { + @Suppress("LeakingThis") override var deprecated: Boolean = modifiers.isDeprecated() @Suppress("LeakingThis") // Documentation can change, but we don't want to pick up subsequent @docOnly mutations diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties index d6dbb769ce36da48d560e1bf5a9dea8dbac0c55a..428de2fc4d16de8cbae5978d7fbce847e1ea1e61 100644 --- a/src/main/resources/version.properties +++ b/src/main/resources/version.properties @@ -1,4 +1,5 @@ +# suppress inspection "UnusedProperty" for whole file # Version definition # This file is read by gradle build scripts, but also packaged with metalava # as a resource for the Version classes to read. -metalavaVersion=1.1.6 +metalavaVersion=1.1.7 diff --git a/src/test/java/com/android/tools/metalava/ApiFileTest.kt b/src/test/java/com/android/tools/metalava/ApiFileTest.kt index 8fb3c4e448efb078a388297443327e394a152a0d..47d6de56cffff7c9831e545436e24ad120cfdae2 100644 --- a/src/test/java/com/android/tools/metalava/ApiFileTest.kt +++ b/src/test/java/com/android/tools/metalava/ApiFileTest.kt @@ -2397,9 +2397,9 @@ class ApiFileTest : DriverTest() { Ltest/pkg/Child;-><init>()V src/test/pkg/Child.java:2 Ltest/pkg/Child;->hiddenApi()V - src/test/pkg/Child.java:13 + src/test/pkg/Child.java:16 Ltest/pkg/Child;->toString()Ljava/lang/String; - src/test/pkg/Child.java:4 + src/test/pkg/Child.java:8 Ltest/pkg/Parent;-><init>()V src/test/pkg/Parent.java:2 Ltest/pkg/Parent;->toString()Ljava/lang/String; diff --git a/src/test/java/com/android/tools/metalava/DriverTest.kt b/src/test/java/com/android/tools/metalava/DriverTest.kt index eba725757dd8b94fda982fcb3ae0ab44a8b6e4a7..4272ec7680dfee087c4ed14b50e36ff1a30c3667 100644 --- a/src/test/java/com/android/tools/metalava/DriverTest.kt +++ b/src/test/java/com/android/tools/metalava/DriverTest.kt @@ -1057,7 +1057,7 @@ abstract class DriverTest { "Using $ARG_NULLABILITY_WARNINGS_TXT but $validateNullabilityTxt was not created", validateNullabilityTxt.isFile ) - var actualReport = + val actualReport = Files.asCharSource(validateNullabilityTxt, Charsets.UTF_8).readLines().map(String::trim).toSet() assertEquals(validateNullability, actualReport) }