Repository: detekt/detekt
Issue: UselessPostfixExpression: Postfix on field in return

detekt marks the postfix expressions in the following case as useless. However the value of the field will be updated and affects the next call of the function.

```
class Test {
    private var runningId: Long = 0

    fun getId(): Long {
        return runningId++
    }
}
```

Changed files:
detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt
detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt

diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt
index 6bf686276f..fc71df417a 100644
--- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt
+++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpression.kt
@@ -6,21 +6,37 @@ import io.gitlab.arturbosch.detekt.api.Entity
 import io.gitlab.arturbosch.detekt.api.Issue
 import io.gitlab.arturbosch.detekt.api.Rule
 import io.gitlab.arturbosch.detekt.api.Severity
+import io.gitlab.arturbosch.detekt.rules.collectByType
 import org.jetbrains.kotlin.psi.KtBinaryExpression
+import org.jetbrains.kotlin.psi.KtClass
 import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.kotlin.psi.KtNamedFunction
 import org.jetbrains.kotlin.psi.KtPostfixExpression
+import org.jetbrains.kotlin.psi.KtProperty
 import org.jetbrains.kotlin.psi.KtReturnExpression
+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
 
 class UselessPostfixExpression(config: Config = Config.empty) : Rule(config) {
 
 	override val issue: Issue = Issue("UselessPostfixExpression", Severity.Defect,
 			"The incremented or decremented value is unused. This value is replaced with the original value.")
 
+	var properties = setOf<String?>()
+
+	override fun visitClass(klass: KtClass) {
+		properties = klass.getProperties()
+				.map { it.name }
+				.toSet()
+		super.visitClass(klass)
+	}
+
 	override fun visitReturnExpression(expression: KtReturnExpression) {
 		val postfixExpression = expression.returnedExpression as? KtPostfixExpression
-		if (postfixExpression != null) {
+
+		if (postfixExpression != null && postfixExpression.shouldBeReported()) {
 			report(postfixExpression)
 		}
+
 		getPostfixExpressionChilds(expression.returnedExpression)
 				?.forEach { report(it) }
 	}
@@ -39,6 +55,20 @@ class UselessPostfixExpression(config: Config = Config.empty) : Rule(config) {
 		}
 	}
 
+	private fun KtPostfixExpression.shouldBeReported(): Boolean {
+		val functionProperties = this.getNonStrictParentOfType(KtNamedFunction::class.java)
+				?.collectByType<KtProperty>()
+				?.map { it.name }
+				?.toSet()
+		val postfixReceiverName = this.baseExpression?.text
+
+		if (functionProperties != null && functionProperties.contains(postfixReceiverName)) {
+			return true
+		}
+		return !properties.contains(postfixReceiverName)
+
+	}
+
 	private fun report(postfixExpression: KtPostfixExpression) {
 		report(CodeSmell(issue, Entity.from(postfixExpression)))
 	}
diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt
index 28bc2b1a2c..f28da7dd04 100644
--- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt
+++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UselessPostfixExpressionSpec.kt
@@ -1,10 +1,10 @@
 package io.gitlab.arturbosch.detekt.rules.bugs
 
 import io.gitlab.arturbosch.detekt.test.lint
+import org.assertj.core.api.Assertions.assertThat
 import org.jetbrains.spek.api.dsl.describe
 import org.jetbrains.spek.api.dsl.it
 import org.jetbrains.spek.subject.SubjectSpek
-import org.assertj.core.api.Assertions.assertThat
 
 class UselessPostfixExpressionSpec : SubjectSpek<UselessPostfixExpression>({
 	subject { UselessPostfixExpression() }
@@ -33,5 +33,36 @@ class UselessPostfixExpressionSpec : SubjectSpek<UselessPostfixExpression>({
 				}"""
 			assertThat(subject.lint(code)).hasSize(2)
 		}
+
+		it("should not report field increments") {
+			val code = """
+				class Test {
+					private var runningId: Long = 0
+
+					fun increment() {
+						runningId++
+					}
+
+					fun getId(): Long {
+						return runningId++
+					}
+				}
+				"""
+			assertThat(subject.lint(code)).isEmpty()
+		}
+
+		it("should detect properties shadowing fields that are incremented") {
+			val code = """
+				class Test {
+					private var runningId: Long = 0
+
+					fun getId(): Long {
+						val runningId: Long = 0
+						return runningId++
+					}
+				}
+				"""
+			assertThat(subject.lint(code)).hasSize(1)
+		}
 	}
 })