diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt index f9f89031f1a..cbd8a90e27e 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/AbstractKotlinLintTest.kt @@ -16,9 +16,12 @@ package org.jetbrains.kotlin.android.lint +import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl +import com.intellij.util.PathUtil import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase import org.jetbrains.kotlin.android.KotlinAndroidTestCase import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes import java.io.File @@ -26,9 +29,9 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() { override fun setUp() { super.setUp() - ConfigLibraryUtil.configureKotlinRuntime(myModule) AndroidLintInspectionBase.invalidateInspectionShortName2IssueMap() - // needs access to .class files in kotlin runtime jar + (myFixture as CodeInsightTestFixtureImpl).setVirtualFileFilter { false } // Allow access to tree elements. + ConfigLibraryUtil.configureKotlinRuntime(myModule) } override fun tearDown() { @@ -36,9 +39,11 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() { super.tearDown() } - fun doTest(filename: String) { - val ktFile = File(filename) - val mainInspectionClassName = findStringWithPrefixes(ktFile.readText(), "// INSPECTION_CLASS: ") ?: error("Empty class name") + fun doTest(path: String) { + val ktFile = File(path) + val fileText = ktFile.readText() + val mainInspectionClassName = findStringWithPrefixes(fileText, "// INSPECTION_CLASS: ") ?: error("Empty class name") + val dependency = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// DEPENDENCY: ") val inspectionClassNames = mutableListOf(mainInspectionClassName) for (i in 2..100) { @@ -63,9 +68,14 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() { } } - val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/" + getTestName(true) + ".kt") + val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/${PathUtil.getFileName(path)}") myFixture.configureFromExistingVirtualFile(virtualFile) + if (dependency != null) { + val (dependencyFile, dependencyTargetPath) = dependency.split(" -> ").map(String::trim) + myFixture.copyFileToProject("${PathUtil.getParentPath(path)}/$dependencyFile", "src/$dependencyTargetPath") + } + myFixture.checkHighlighting(true, false, false) } } \ No newline at end of file diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java index e1c0526f94a..657f086f8d6 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/lint/KotlinLintTestGenerated.java @@ -138,6 +138,12 @@ public class KotlinLintTestGenerated extends AbstractKotlinLintTest { doTest(fileName); } + @TestMetadata("supportAnnotation.kt") + public void testSupportAnnotation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/supportAnnotation.kt"); + doTest(fileName); + } + @TestMetadata("systemServices.kt") public void testSystemServices() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lint/systemServices.kt"); diff --git a/idea/testData/android/lint/IntRange.java b/idea/testData/android/lint/IntRange.java new file mode 100644 index 00000000000..d489acb57fa --- /dev/null +++ b/idea/testData/android/lint/IntRange.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 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 android.support.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * Denotes that the annotated element should be an int or long in the given range + *

+ * Example: + *


+ *  @IntRange(from=0,to=255)
+ *  public int getAlpha() {
+ *      ...
+ *  }
+ * 
+ */ +@Retention(CLASS) +@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE}) +public @interface IntRange { + /** Smallest value, inclusive */ + long from() default Long.MIN_VALUE; + /** Largest value, inclusive */ + long to() default Long.MAX_VALUE; +} \ No newline at end of file diff --git a/idea/testData/android/lint/supportAnnotation.kt b/idea/testData/android/lint/supportAnnotation.kt new file mode 100644 index 00000000000..4f10424aa66 --- /dev/null +++ b/idea/testData/android/lint/supportAnnotation.kt @@ -0,0 +1,16 @@ +// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintSupportAnnotationUsageInspection +// DEPENDENCY: IntRange.java -> android/support/annotation/IntRange.java + +import android.support.annotation.IntRange +import android.view.View + +const val constantVal = 0L + +@IntRange(from = 10, to = 0) +fun invalidRange1a(): Int = 5 + +@IntRange(from = constantVal, to = 10) // ok +fun invalidRange0b(): Int = 5 + +@IntRange(from = 10, to = constantVal) +fun invalidRange1b(): Int = 5 \ No newline at end of file diff --git a/license/README.md b/license/README.md index 7a42a1f0a70..2947be9aa48 100644 --- a/license/README.md +++ b/license/README.md @@ -105,6 +105,10 @@ any distributions of the compiler, libraries or plugin: - Path: idea/testData/android/lintQuickfix/requiresApi/RequiresApi.java - License: Apache 2 (license/third_party/aosp_license.txt) - Origin: Copyright (C) 2011-15 The Android Open Source Project + + - Path: idea/testData/android/lint/IntRange.java + - License: Apache 2 (license/third_party/aosp_license.txt) + - Origin: Copyright (C) 2011-15 The Android Open Source Project - Path: libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/allOpenSpring/src/org/springframework/stereotype/Component.java - License: Apache 2 (license/third_party/testdata/spring_license.txt) diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java index 99a602ca2bd..b6d86506dcb 100644 --- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/ConstantEvaluator.java @@ -862,7 +862,7 @@ public class ConstantEvaluator { } } return operandValue; - } else if (node instanceof UReferenceExpression) { + } else if (mContext != null && node instanceof UReferenceExpression) { PsiElement resolved = ((UReferenceExpression) node).resolve(); if (resolved instanceof PsiVariable) { PsiVariable variable = (PsiVariable) resolved;