diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UastLintUtils.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UastLintUtils.java new file mode 100644 index 00000000000..c0d0bba54b4 --- /dev/null +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/UastLintUtils.java @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * 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 com.android.tools.klint.client.api; + +import com.android.annotations.NonNull; +import org.jetbrains.uast.*; + +public class UastLintUtils { + + public static boolean isChildOfExpression( + @NonNull UExpression child, + @NonNull UExpression parent) { + UElement current = child; + while (current != null) { + if (current.equals(parent)) { + return true; + } else if (!(current instanceof UExpression)) { + return false; + } + + current = current.getParent(); + } + + return false; + } + +} diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java index eef080fc64a..9660cfad904 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java @@ -17,6 +17,7 @@ package com.android.tools.klint.checks; import com.android.annotations.NonNull; +import com.android.tools.klint.client.api.UastLintUtils; import com.android.tools.klint.detector.api.Category; import com.android.tools.klint.detector.api.Context; import com.android.tools.klint.detector.api.Detector; @@ -124,7 +125,7 @@ public class ToastDetector extends Detector implements UastScanner { @Override public boolean visitCallExpression(@NotNull UCallExpression node) { - if (node == mTarget) { + if (node.equals(mTarget)) { mSeenTarget = true; } else if (mSeenTarget && node.matchesFunctionName("show")) { //$NON-NLS-1$ // TODO: Do more flow analysis to see whether we're really calling show @@ -132,7 +133,7 @@ public class ToastDetector extends Detector implements UastScanner { mFound = true; } - return true; + return super.visitCallExpression(node); } @Override @@ -141,16 +142,16 @@ public class ToastDetector extends Detector implements UastScanner { mSeenTarget = true; } - return false; + return super.visitQualifiedExpression(node); } @Override public boolean visitReturnExpression(@NotNull UReturnExpression node) { - if (mTarget.equals(node.getReturnExpression())) { + if (UastLintUtils.isChildOfExpression(mTarget, node.getReturnExpression())) { mFound = true; } - return false; + return super.visitReturnExpression(node); } boolean isShowCalled() { diff --git a/plugins/uast-kotlin/testData/lint/toast.kt b/plugins/uast-kotlin/testData/lint/toast.kt index a84df0e6b32..6df0c2a896c 100644 --- a/plugins/uast-kotlin/testData/lint/toast.kt +++ b/plugins/uast-kotlin/testData/lint/toast.kt @@ -10,6 +10,23 @@ class ToastTest(context: Context) : Activity() { // Don't warn here return Toast.makeText(context, "foo", Toast.LENGTH_LONG) } + + private fun insideRunnable(context: Context) { + Runnable { + Toast.makeText(context, "foo", Toast.LENGTH_LONG).show() + } + + Runnable { + val toast = Toast.makeText(context, "foo", Toast.LENGTH_LONG) + if (5 > 3) { + toast.show() + } + } + + Runnable { + Toast.makeText(context, "foo", Toast.LENGTH_LONG) + } + } private fun showToast(context: Context) { // Don't warn here