Added IfThenUtils
This commit is contained in:
committed by
Zalim Bashorov
parent
fcbd7b357a
commit
6b5e46da50
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 org.jetbrains.jet.plugin.intentions.branchedTransformations
|
||||
|
||||
import org.jetbrains.jet.lang.psi.JetExpression
|
||||
import org.jetbrains.jet.lang.psi.JetBlockExpression
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression
|
||||
import org.jetbrains.jet.lang.psi.JetIfExpression
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.jet.plugin.refactoring.introduceVariable.JetIntroduceVariableHandler
|
||||
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.plugin.refactoring.inline.KotlinInlineValHandler
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration
|
||||
|
||||
fun JetBinaryExpression.comparesNonNullToNull(): Boolean {
|
||||
val operationToken = this.getOperationToken()
|
||||
val rhs = this.getRight()
|
||||
val lhs = this.getLeft()
|
||||
if (rhs == null || lhs == null) return false
|
||||
|
||||
val rightIsNull = rhs.isNullExpression()
|
||||
val leftIsNull = lhs.isNullExpression()
|
||||
return leftIsNull != rightIsNull && (operationToken == JetTokens.EQEQ || operationToken == JetTokens.EXCLEQ)
|
||||
}
|
||||
|
||||
fun JetExpression.extractExpressionIfSingle(): JetExpression? {
|
||||
val innerExpression = JetPsiUtil.deparenthesize(this)
|
||||
if (innerExpression is JetBlockExpression) {
|
||||
return if (innerExpression.getStatements().size() == 1)
|
||||
JetPsiUtil.deparenthesize(innerExpression.getStatements().first as? JetExpression)
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
return innerExpression
|
||||
}
|
||||
|
||||
fun JetSafeQualifiedExpression.isStatement(): Boolean {
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(this)
|
||||
|
||||
val expectedType = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, this);
|
||||
val isUnit = expectedType != null && KotlinBuiltIns.getInstance().isUnit(expectedType);
|
||||
|
||||
// Some "statements" are actually expressions returned from lambdas, their expected types are non-null
|
||||
val isStatement = context.get(BindingContext.STATEMENT, this) == true && expectedType == null;
|
||||
|
||||
return isStatement || isUnit
|
||||
}
|
||||
|
||||
fun JetBinaryExpression.getNonNullExpression(): JetExpression? = when {
|
||||
this.getLeft()?.isNullExpression() == false ->
|
||||
this.getLeft()
|
||||
this.getRight()?.isNullExpression() == false ->
|
||||
this.getRight()
|
||||
else ->
|
||||
null
|
||||
}
|
||||
|
||||
fun JetExpression.isNullExpression(): Boolean = this.extractExpressionIfSingle()?.getText() == "null"
|
||||
|
||||
fun JetExpression.isNullExpressionOrEmptyBlock(): Boolean = this.isNullExpression() || this is JetBlockExpression && this.getStatements().empty
|
||||
|
||||
fun JetExpression.isNotNullExpression(): Boolean {
|
||||
val innerExpression = this.extractExpressionIfSingle()
|
||||
return innerExpression != null && innerExpression.getText() != "null"
|
||||
}
|
||||
|
||||
fun JetExpression.evaluatesTo(other: JetExpression): Boolean {
|
||||
return this.extractExpressionIfSingle()?.getText() == other.getText()
|
||||
}
|
||||
|
||||
fun JetExpression.convertToIfNotNullExpression(conditionLhs: JetExpression, thenClause: JetExpression, elseClause: JetExpression?): JetIfExpression {
|
||||
val elseBranch = if (elseClause == null) "" else " else ${elseClause.getText()}"
|
||||
val conditionalString = "if (${conditionLhs.getText()} != null) ${thenClause.getText()}$elseBranch"
|
||||
|
||||
val st = this.replace(conditionalString) as JetExpression
|
||||
return JetPsiUtil.deparenthesize(st) as JetIfExpression
|
||||
}
|
||||
|
||||
fun JetIfExpression.introduceValueForCondition(occurrenceInThenClause: JetExpression, editor: Editor) {
|
||||
val project = this.getProject()
|
||||
val occurrenceInConditional = (this.getCondition() as JetBinaryExpression).getLeft()!!
|
||||
JetIntroduceVariableHandler.doRefactoring(project, editor, occurrenceInConditional, listOf(occurrenceInConditional, occurrenceInThenClause))
|
||||
}
|
||||
|
||||
fun PsiElement.replace(expressionAsString: String): PsiElement =
|
||||
this.replace(JetPsiFactory.createExpression(this.getProject(), expressionAsString))
|
||||
|
||||
fun JetSimpleNameExpression.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor: Editor) {
|
||||
val declaration = this.getReference()?.resolve() as JetDeclaration
|
||||
|
||||
val enclosingElement = JetPsiUtil.getEnclosingElementForLocalDeclaration(declaration)
|
||||
val isLocal = enclosingElement != null
|
||||
if (!isLocal) return
|
||||
|
||||
val scope = LocalSearchScope(enclosingElement!!)
|
||||
|
||||
val references = ReferencesSearch.search(declaration, scope).findAll()
|
||||
if (references.size() == 1) {
|
||||
KotlinInlineValHandler().inlineElement(this.getProject(), editor, declaration)
|
||||
}
|
||||
}
|
||||
|
||||
fun JetSafeQualifiedExpression.inlineReceiverIfApplicableWithPrompt(editor: Editor) {
|
||||
(this.getReceiverExpression() as? JetSimpleNameExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
}
|
||||
|
||||
fun JetBinaryExpression.inlineLeftSideIfApplicableWithPrompt(editor: Editor) {
|
||||
(this.getLeft() as? JetSimpleNameExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
}
|
||||
|
||||
fun JetExpression.isStableVariable(): Boolean {
|
||||
val context = AnalyzerFacadeWithCache.getContextForElement(this)
|
||||
val descriptor = BindingContextUtils.extractVariableDescriptorIfAny(context, this, false)
|
||||
return descriptor is VariableDescriptor && DataFlowValueFactory.isStableVariable(descriptor)
|
||||
}
|
||||
Reference in New Issue
Block a user