Convert PositioningStrategy to Kotlin. Cleanup.
This commit is contained in:
+278
-392
@@ -16,30 +16,23 @@
|
||||
|
||||
package org.jetbrains.jet.lang.diagnostics
|
||||
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.Lists
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import kotlin.Function1
|
||||
import org.jetbrains.jet.JetNodeTypes
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
|
||||
import java.util.Arrays
|
||||
import java.util.Collections
|
||||
|
||||
public class PositioningStrategies private() {
|
||||
import kotlin.platform.platformStatic
|
||||
import org.jetbrains.kotlin.util.sure
|
||||
|
||||
public object PositioningStrategies {
|
||||
private open class DeclarationHeader<T : JetDeclaration> : PositioningStrategy<T>() {
|
||||
override fun isValid(element: T): Boolean {
|
||||
if (element is JetNamedDeclaration && !(element is JetObjectDeclaration)) {
|
||||
if ((element as JetNamedDeclaration).getNameIdentifier() == null) {
|
||||
if (element is JetNamedDeclaration && element !is JetObjectDeclaration) {
|
||||
if (element.getNameIdentifier() == null) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -47,12 +40,11 @@ public class PositioningStrategies private() {
|
||||
}
|
||||
}
|
||||
|
||||
class object {
|
||||
|
||||
public val DEFAULT: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
if (element is JetObjectLiteralExpression) {
|
||||
val objectDeclaration = (element as JetObjectLiteralExpression).getObjectDeclaration()
|
||||
public val DEFAULT: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
when (element) {
|
||||
is JetObjectLiteralExpression -> {
|
||||
val objectDeclaration = element.getObjectDeclaration()
|
||||
val objectKeyword = objectDeclaration.getObjectKeyword()
|
||||
val delegationSpecifierList = objectDeclaration.getDelegationSpecifierList()
|
||||
if (delegationSpecifierList == null) {
|
||||
@@ -60,425 +52,319 @@ public class PositioningStrategies private() {
|
||||
}
|
||||
return markRange(objectKeyword, delegationSpecifierList)
|
||||
}
|
||||
else if (element is JetClassObject) {
|
||||
val classObject = element as JetClassObject
|
||||
val classKeyword = classObject.getClassKeyword()
|
||||
val objectKeyword = classObject.getObjectDeclaration().getObjectKeyword()
|
||||
is JetClassObject -> {
|
||||
val classKeyword = element.getClassKeyword()
|
||||
val objectKeyword = element.getObjectDeclaration().getObjectKeyword()
|
||||
return markRange(classKeyword, objectKeyword)
|
||||
}
|
||||
else {
|
||||
else -> {
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public val DECLARATION_RETURN_TYPE: PositioningStrategy<JetDeclaration> = object : PositioningStrategy<JetDeclaration>() {
|
||||
override fun mark(declaration: JetDeclaration): List<TextRange> {
|
||||
return markElement(getElementToMark(declaration))
|
||||
}
|
||||
|
||||
override fun isValid(declaration: JetDeclaration): Boolean {
|
||||
return !hasSyntaxErrors(getElementToMark(declaration))
|
||||
}
|
||||
|
||||
private fun getElementToMark(declaration: JetDeclaration): PsiElement {
|
||||
var returnTypeRef: JetTypeReference? = null
|
||||
var nameIdentifierOrPlaceholder: PsiElement? = null
|
||||
if (declaration is JetNamedFunction) {
|
||||
val function = declaration as JetNamedFunction
|
||||
returnTypeRef = function.getTypeReference()
|
||||
nameIdentifierOrPlaceholder = function.getNameIdentifier()
|
||||
}
|
||||
else if (declaration is JetProperty) {
|
||||
val property = declaration as JetProperty
|
||||
returnTypeRef = property.getTypeReference()
|
||||
nameIdentifierOrPlaceholder = property.getNameIdentifier()
|
||||
}
|
||||
else if (declaration is JetPropertyAccessor) {
|
||||
val accessor = declaration as JetPropertyAccessor
|
||||
returnTypeRef = accessor.getReturnTypeReference()
|
||||
nameIdentifierOrPlaceholder = accessor.getNamePlaceholder()
|
||||
}
|
||||
|
||||
if (returnTypeRef != null) return returnTypeRef
|
||||
if (nameIdentifierOrPlaceholder != null) return nameIdentifierOrPlaceholder
|
||||
return declaration
|
||||
}
|
||||
public val DECLARATION_RETURN_TYPE: PositioningStrategy<JetDeclaration> = object : PositioningStrategy<JetDeclaration>() {
|
||||
override fun mark(element: JetDeclaration): List<TextRange> {
|
||||
return markElement(getElementToMark(element))
|
||||
}
|
||||
|
||||
public val DECLARATION_NAME: PositioningStrategy<JetNamedDeclaration> = object : DeclarationHeader<JetNamedDeclaration>() {
|
||||
override fun mark(element: JetNamedDeclaration): List<TextRange> {
|
||||
val nameIdentifier = element.getNameIdentifier()
|
||||
if (nameIdentifier != null) {
|
||||
if (element is JetClassOrObject) {
|
||||
var startNode: ASTNode? = null
|
||||
if (element.hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||
//noinspection ConstantConditions
|
||||
startNode = element.getModifierList()!!.getModifier(JetTokens.ENUM_KEYWORD)!!.getNode()
|
||||
}
|
||||
if (startNode == null) {
|
||||
startNode = element.getNode().findChildByType(TokenSet.create(JetTokens.CLASS_KEYWORD, JetTokens.OBJECT_KEYWORD))
|
||||
}
|
||||
if (startNode == null) {
|
||||
startNode = element.getNode()
|
||||
}
|
||||
return markRange(startNode!!.getPsi(), nameIdentifier)
|
||||
}
|
||||
return markElement(nameIdentifier)
|
||||
}
|
||||
if (element is JetObjectDeclaration) {
|
||||
val objectKeyword = (element as JetObjectDeclaration).getObjectKeyword()
|
||||
val parent = element.getParent()
|
||||
if (parent is JetClassObject) {
|
||||
val classKeyword = (parent as JetClassObject).getClassKeyword()
|
||||
val start = if (classKeyword == null) objectKeyword else classKeyword
|
||||
return markRange(start, objectKeyword)
|
||||
}
|
||||
return markElement(objectKeyword)
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
override fun isValid(element: JetDeclaration): Boolean {
|
||||
return !hasSyntaxErrors(getElementToMark(element))
|
||||
}
|
||||
|
||||
public val DECLARATION_SIGNATURE: PositioningStrategy<JetDeclaration> = object : DeclarationHeader<JetDeclaration>() {
|
||||
override fun mark(element: JetDeclaration): List<TextRange> {
|
||||
if (element is JetNamedFunction) {
|
||||
val function = element as JetNamedFunction
|
||||
val endOfSignatureElement: PsiElement
|
||||
val valueParameterList = function.getValueParameterList()
|
||||
val returnTypeRef = function.getTypeReference()
|
||||
val nameIdentifier = function.getNameIdentifier()
|
||||
if (returnTypeRef != null) {
|
||||
endOfSignatureElement = returnTypeRef
|
||||
}
|
||||
else if (valueParameterList != null) {
|
||||
endOfSignatureElement = valueParameterList
|
||||
}
|
||||
else if (nameIdentifier != null) {
|
||||
endOfSignatureElement = nameIdentifier
|
||||
}
|
||||
else {
|
||||
endOfSignatureElement = function
|
||||
}
|
||||
return markRange(function, endOfSignatureElement)
|
||||
private fun getElementToMark(declaration: JetDeclaration): PsiElement {
|
||||
val (returnTypeRef, nameIdentifierOrPlaceholder) = when (declaration) {
|
||||
is JetCallableDeclaration -> Pair(declaration.getTypeReference(), declaration.getNameIdentifier())
|
||||
is JetPropertyAccessor -> Pair(declaration.getReturnTypeReference(), declaration.getNamePlaceholder())
|
||||
else -> Pair(null, null)
|
||||
}
|
||||
|
||||
if (returnTypeRef != null) return returnTypeRef
|
||||
if (nameIdentifierOrPlaceholder != null) return nameIdentifierOrPlaceholder
|
||||
return declaration
|
||||
}
|
||||
}
|
||||
|
||||
public val DECLARATION_NAME: PositioningStrategy<JetNamedDeclaration> = object : DeclarationHeader<JetNamedDeclaration>() {
|
||||
override fun mark(element: JetNamedDeclaration): List<TextRange> {
|
||||
val nameIdentifier = element.getNameIdentifier()
|
||||
if (nameIdentifier != null) {
|
||||
if (element is JetClassOrObject) {
|
||||
val startElement =
|
||||
element.getModifierList()?.getModifier(JetTokens.ENUM_KEYWORD)
|
||||
?: element.getNode().findChildByType(TokenSet.create(JetTokens.CLASS_KEYWORD, JetTokens.OBJECT_KEYWORD))?.getPsi()
|
||||
?: element
|
||||
|
||||
return markRange(startElement, nameIdentifier)
|
||||
}
|
||||
else if (element is JetProperty) {
|
||||
val property = element as JetProperty
|
||||
val endOfSignatureElement: PsiElement
|
||||
val propertyTypeRef = property.getTypeReference()
|
||||
val nameIdentifier = property.getNameIdentifier()
|
||||
if (propertyTypeRef != null) {
|
||||
endOfSignatureElement = propertyTypeRef
|
||||
}
|
||||
else if (nameIdentifier != null) {
|
||||
endOfSignatureElement = nameIdentifier
|
||||
}
|
||||
else {
|
||||
endOfSignatureElement = property
|
||||
}
|
||||
return markRange(property, endOfSignatureElement)
|
||||
return markElement(nameIdentifier)
|
||||
}
|
||||
if (element is JetObjectDeclaration) {
|
||||
val objectKeyword = element.getObjectKeyword()
|
||||
val parent = element.getParent()
|
||||
if (parent is JetClassObject) {
|
||||
val classKeyword = parent.getClassKeyword()
|
||||
val start = classKeyword ?: objectKeyword
|
||||
return markRange(start, objectKeyword)
|
||||
}
|
||||
else if (element is JetPropertyAccessor) {
|
||||
val accessor = element as JetPropertyAccessor
|
||||
var endOfSignatureElement: PsiElement? = accessor.getReturnTypeReference()
|
||||
if (endOfSignatureElement == null) {
|
||||
val rpar = accessor.getRightParenthesis()
|
||||
endOfSignatureElement = if (rpar == null) null else rpar.getPsi()
|
||||
}
|
||||
if (endOfSignatureElement == null) {
|
||||
endOfSignatureElement = accessor.getNamePlaceholder()
|
||||
}
|
||||
return markRange(accessor, endOfSignatureElement)
|
||||
return markElement(objectKeyword)
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val DECLARATION_SIGNATURE: PositioningStrategy<JetDeclaration> = object : DeclarationHeader<JetDeclaration>() {
|
||||
override fun mark(element: JetDeclaration): List<TextRange> {
|
||||
when (element) {
|
||||
is JetNamedFunction -> {
|
||||
val endOfSignatureElement =
|
||||
element.getTypeReference()
|
||||
?: element.getValueParameterList()
|
||||
?: element.getNameIdentifier()
|
||||
?: element
|
||||
|
||||
return markRange(element, endOfSignatureElement)
|
||||
}
|
||||
else if (element is JetClass) {
|
||||
val nameAsDeclaration = (element as JetClass).getNameIdentifier()
|
||||
if (nameAsDeclaration == null) {
|
||||
return markElement(element)
|
||||
}
|
||||
val primaryConstructorParameterList = (element as JetClass).getPrimaryConstructorParameterList()
|
||||
if (primaryConstructorParameterList == null) {
|
||||
return markElement(nameAsDeclaration)
|
||||
}
|
||||
is JetProperty -> {
|
||||
val endOfSignatureElement = element.getTypeReference() ?: element.getNameIdentifier() ?: element
|
||||
return markRange(element, endOfSignatureElement)
|
||||
}
|
||||
is JetPropertyAccessor -> {
|
||||
val endOfSignatureElement =
|
||||
element.getReturnTypeReference()
|
||||
?: element.getRightParenthesis()?.getPsi()
|
||||
?: element.getNamePlaceholder()
|
||||
|
||||
return markRange(element, endOfSignatureElement)
|
||||
}
|
||||
is JetClass -> {
|
||||
val nameAsDeclaration = element.getNameIdentifier() ?: return markElement(element)
|
||||
val primaryConstructorParameterList = element.getPrimaryConstructorParameterList() ?: return markElement(nameAsDeclaration)
|
||||
return markRange(nameAsDeclaration, primaryConstructorParameterList)
|
||||
}
|
||||
else if (element is JetObjectDeclaration) {
|
||||
return DECLARATION_NAME.mark(element as JetObjectDeclaration)
|
||||
is JetObjectDeclaration -> {
|
||||
return DECLARATION_NAME.mark(element)
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val DECLARATION_SIGNATURE_OR_DEFAULT: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
return if (element is JetDeclaration)
|
||||
DECLARATION_SIGNATURE.mark(element)
|
||||
else
|
||||
DEFAULT.mark(element)
|
||||
}
|
||||
|
||||
public val DECLARATION_SIGNATURE_OR_DEFAULT: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
if (element is JetDeclaration) {
|
||||
return DECLARATION_SIGNATURE.mark(element as JetDeclaration)
|
||||
}
|
||||
return DEFAULT.mark(element)
|
||||
}
|
||||
|
||||
override fun isValid(element: PsiElement): Boolean {
|
||||
if (element is JetDeclaration) {
|
||||
return DECLARATION_SIGNATURE.isValid(element as JetDeclaration)
|
||||
}
|
||||
return DEFAULT.isValid(element)
|
||||
}
|
||||
override fun isValid(element: PsiElement): Boolean {
|
||||
return if (element is JetDeclaration)
|
||||
DECLARATION_SIGNATURE.isValid(element)
|
||||
else
|
||||
DEFAULT.isValid(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val ABSTRACT_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.ABSTRACT_KEYWORD)
|
||||
public val ABSTRACT_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.ABSTRACT_KEYWORD)
|
||||
|
||||
public val OVERRIDE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.OVERRIDE_KEYWORD)
|
||||
public val OVERRIDE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.OVERRIDE_KEYWORD)
|
||||
|
||||
public val FINAL_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.FINAL_KEYWORD)
|
||||
public val FINAL_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.FINAL_KEYWORD)
|
||||
|
||||
public val VARIANCE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD)
|
||||
public val FOR_REDECLARATION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
if (element is JetNamedDeclaration) {
|
||||
val nameIdentifier = (element as JetNamedDeclaration).getNameIdentifier()
|
||||
if (nameIdentifier != null) {
|
||||
return markElement(nameIdentifier)
|
||||
}
|
||||
}
|
||||
else if (element is JetFile) {
|
||||
val file = element as JetFile
|
||||
val nameIdentifier = file.getPackageDirective()!!.getNameIdentifier()
|
||||
if (nameIdentifier != null) {
|
||||
return markElement(nameIdentifier)
|
||||
}
|
||||
}
|
||||
return markElement(element)
|
||||
public val VARIANCE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD)
|
||||
|
||||
public val FOR_REDECLARATION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
val nameIdentifier = when (element) {
|
||||
is JetNamedDeclaration -> element.getNameIdentifier()
|
||||
is JetFile -> element.getPackageDirective()!!.getNameIdentifier()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
public val FOR_UNRESOLVED_REFERENCE: PositioningStrategy<JetReferenceExpression> = object : PositioningStrategy<JetReferenceExpression>() {
|
||||
override fun mark(element: JetReferenceExpression): List<TextRange> {
|
||||
if (element is JetArrayAccessExpression) {
|
||||
val ranges = (element as JetArrayAccessExpression).getBracketRanges()
|
||||
if (!ranges.isEmpty()) {
|
||||
return ranges
|
||||
}
|
||||
}
|
||||
return listOf(element.getTextRange())
|
||||
}
|
||||
}
|
||||
|
||||
public fun modifierSetPosition(vararg tokens: JetKeywordToken): PositioningStrategy<JetModifierListOwner> {
|
||||
return object : PositioningStrategy<JetModifierListOwner>() {
|
||||
override fun mark(modifierListOwner: JetModifierListOwner): List<TextRange> {
|
||||
val modifierList = modifierListOwner.getModifierList()
|
||||
assert(modifierList != null, "No modifier list, but modifier has been found by the analyzer")
|
||||
|
||||
for (token in tokens) {
|
||||
val node = modifierList!!.getModifierNode(token)
|
||||
if (node != null) {
|
||||
return markNode(node)
|
||||
}
|
||||
}
|
||||
throw IllegalStateException("None of the modifiers is found: " + Arrays.asList<JetKeywordToken>(*tokens))
|
||||
return markElement(nameIdentifier ?: element)
|
||||
}
|
||||
}
|
||||
public val FOR_UNRESOLVED_REFERENCE: PositioningStrategy<JetReferenceExpression> = object : PositioningStrategy<JetReferenceExpression>() {
|
||||
override fun mark(element: JetReferenceExpression): List<TextRange> {
|
||||
if (element is JetArrayAccessExpression) {
|
||||
val ranges = element.getBracketRanges()
|
||||
if (!ranges.isEmpty()) {
|
||||
return ranges
|
||||
}
|
||||
}
|
||||
return listOf(element.getTextRange())
|
||||
}
|
||||
}
|
||||
|
||||
public val ARRAY_ACCESS: PositioningStrategy<JetArrayAccessExpression> = object : PositioningStrategy<JetArrayAccessExpression>() {
|
||||
override fun mark(element: JetArrayAccessExpression): List<TextRange> {
|
||||
return markElement(element.getIndicesNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val VISIBILITY_MODIFIER: PositioningStrategy<JetModifierListOwner> = object : PositioningStrategy<JetModifierListOwner>() {
|
||||
platformStatic
|
||||
public fun modifierSetPosition(vararg tokens: JetKeywordToken): PositioningStrategy<JetModifierListOwner> {
|
||||
return object : PositioningStrategy<JetModifierListOwner>() {
|
||||
override fun mark(element: JetModifierListOwner): List<TextRange> {
|
||||
val visibilityTokens = Lists.newArrayList<JetModifierKeywordToken>(JetTokens.PRIVATE_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PUBLIC_KEYWORD, JetTokens.INTERNAL_KEYWORD)
|
||||
val result = Lists.newArrayList<TextRange>()
|
||||
for (token in visibilityTokens) {
|
||||
if (element.hasModifier(token)) {
|
||||
//noinspection ConstantConditions
|
||||
result.add(element.getModifierList()!!.getModifierNode(token)!!.getTextRange())
|
||||
val modifierList = element.getModifierList().sure("No modifier list, but modifier has been found by the analyzer")
|
||||
|
||||
for (token in tokens) {
|
||||
val node = modifierList.getModifierNode(token)
|
||||
if (node != null) {
|
||||
return markNode(node)
|
||||
}
|
||||
}
|
||||
throw IllegalStateException("None of the modifiers is found: " + listOf(*tokens))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.isEmpty()) return result
|
||||
public val ARRAY_ACCESS: PositioningStrategy<JetArrayAccessExpression> = object : PositioningStrategy<JetArrayAccessExpression>() {
|
||||
override fun mark(element: JetArrayAccessExpression): List<TextRange> {
|
||||
return markElement(element.getIndicesNode())
|
||||
}
|
||||
}
|
||||
|
||||
// Try to resolve situation when there's no visibility modifiers written before element
|
||||
public val VISIBILITY_MODIFIER: PositioningStrategy<JetModifierListOwner> = object : PositioningStrategy<JetModifierListOwner>() {
|
||||
override fun mark(element: JetModifierListOwner): List<TextRange> {
|
||||
val visibilityTokens = listOf(JetTokens.PRIVATE_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PUBLIC_KEYWORD, JetTokens.INTERNAL_KEYWORD)
|
||||
val modifierList = element.getModifierList()
|
||||
|
||||
if (element is PsiNameIdentifierOwner) {
|
||||
val nameIdentifier = (element as PsiNameIdentifierOwner).getNameIdentifier()
|
||||
if (nameIdentifier != null) {
|
||||
return ImmutableList.of<TextRange>(nameIdentifier.getTextRange())
|
||||
}
|
||||
val result = visibilityTokens.map { modifierList?.getModifierNode(it)?.getTextRange() }.filterNotNull()
|
||||
if (!result.isEmpty()) return result
|
||||
|
||||
// Try to resolve situation when there's no visibility modifiers written before element
|
||||
if (element is PsiNameIdentifierOwner) {
|
||||
val nameIdentifier = element.getNameIdentifier()
|
||||
if (nameIdentifier != null) {
|
||||
return markElement(nameIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
if (element is JetObjectDeclaration) {
|
||||
return ImmutableList.of<TextRange>((element as JetObjectDeclaration).getObjectKeyword().getTextRange())
|
||||
val elementToMark = when (element) {
|
||||
is JetObjectDeclaration -> element.getObjectKeyword()
|
||||
is JetPropertyAccessor -> element.getNamePlaceholder()
|
||||
is JetClassInitializer -> element
|
||||
is JetClassObject -> element.getObjectDeclaration().getObjectKeyword()
|
||||
else -> throw IllegalArgumentException(
|
||||
"Can't find text range for element '${element.javaClass.getCanonicalName()}' with the text '${element.getText()}'")
|
||||
}
|
||||
return markElement(elementToMark)
|
||||
}
|
||||
}
|
||||
|
||||
public val VARIANCE_IN_PROJECTION: PositioningStrategy<JetTypeProjection> = object : PositioningStrategy<JetTypeProjection>() {
|
||||
override fun mark(element: JetTypeProjection): List<TextRange> {
|
||||
return markNode(element.getProjectionNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val PARAMETER_DEFAULT_VALUE: PositioningStrategy<JetParameter> = object : PositioningStrategy<JetParameter>() {
|
||||
override fun mark(element: JetParameter): List<TextRange> {
|
||||
return markNode(element.getDefaultValue()!!.getNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val CALL_ELEMENT: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
return markElement((element as? JetCallElement)?.getCalleeExpression() ?: element)
|
||||
}
|
||||
}
|
||||
|
||||
public val DECLARATION_WITH_BODY: PositioningStrategy<JetDeclarationWithBody> = object : PositioningStrategy<JetDeclarationWithBody>() {
|
||||
override fun mark(element: JetDeclarationWithBody): List<TextRange> {
|
||||
val lastBracketRange = (element.getBodyExpression() as? JetBlockExpression)?.getLastBracketRange()
|
||||
return if (lastBracketRange != null)
|
||||
markRange(lastBracketRange)
|
||||
else
|
||||
markElement(element)
|
||||
}
|
||||
|
||||
override fun isValid(element: JetDeclarationWithBody): Boolean {
|
||||
return super.isValid(element) && (element.getBodyExpression() as? JetBlockExpression)?.getLastBracketRange() != null
|
||||
}
|
||||
}
|
||||
|
||||
public val VAL_OR_VAR_NODE: PositioningStrategy<JetProperty> = object : PositioningStrategy<JetProperty>() {
|
||||
override fun mark(element: JetProperty): List<TextRange> {
|
||||
return markNode(element.getValOrVarNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val ELSE_ENTRY: PositioningStrategy<JetWhenEntry> = object : PositioningStrategy<JetWhenEntry>() {
|
||||
override fun mark(element: JetWhenEntry): List<TextRange> {
|
||||
return markElement(element.getElseKeywordElement()!!)
|
||||
}
|
||||
}
|
||||
|
||||
public val WHEN_EXPRESSION: PositioningStrategy<JetWhenExpression> = object : PositioningStrategy<JetWhenExpression>() {
|
||||
override fun mark(element: JetWhenExpression): List<TextRange> {
|
||||
return markElement(element.getWhenKeywordElement())
|
||||
}
|
||||
}
|
||||
|
||||
public val WHEN_CONDITION_IN_RANGE: PositioningStrategy<JetWhenConditionInRange> = object : PositioningStrategy<JetWhenConditionInRange>() {
|
||||
override fun mark(element: JetWhenConditionInRange): List<TextRange> {
|
||||
return markElement(element.getOperationReference())
|
||||
}
|
||||
}
|
||||
|
||||
public val NULLABLE_TYPE: PositioningStrategy<JetNullableType> = object : PositioningStrategy<JetNullableType>() {
|
||||
override fun mark(element: JetNullableType): List<TextRange> {
|
||||
return markNode(element.getQuestionMarkNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val CALL_EXPRESSION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
if (element is JetCallExpression) {
|
||||
return markRange(element, element.getTypeArgumentList() ?: element.getCalleeExpression() ?: element)
|
||||
}
|
||||
return markElement(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val VALUE_ARGUMENTS: PositioningStrategy<JetElement> = object : PositioningStrategy<JetElement>() {
|
||||
override fun mark(element: JetElement): List<TextRange> {
|
||||
return markElement((element as? JetValueArgumentList)?.getRightParenthesis() ?: element)
|
||||
}
|
||||
}
|
||||
|
||||
public val FUNCTION_LITERAL_PARAMETERS: PositioningStrategy<JetFunctionLiteral> = object : PositioningStrategy<JetFunctionLiteral>() {
|
||||
override fun mark(element: JetFunctionLiteral): List<TextRange> {
|
||||
val valueParameterList = element.getValueParameterList()
|
||||
if (valueParameterList != null) {
|
||||
return markElement(valueParameterList)
|
||||
}
|
||||
return markNode(element.getLBrace().getNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val CUT_CHAR_QUOTES: PositioningStrategy<JetElement> = object : PositioningStrategy<JetElement>() {
|
||||
override fun mark(element: JetElement): List<TextRange> {
|
||||
if (element is JetConstantExpression) {
|
||||
if (element.getNode().getElementType() == JetNodeTypes.CHARACTER_CONSTANT) {
|
||||
val elementTextRange = element.getTextRange()
|
||||
return listOf(TextRange.create(elementTextRange.getStartOffset() + 1, elementTextRange.getEndOffset() - 1))
|
||||
}
|
||||
}
|
||||
return markElement(element)
|
||||
}
|
||||
}
|
||||
|
||||
if (element is JetPropertyAccessor) {
|
||||
return ImmutableList.of<TextRange>((element as JetPropertyAccessor).getNamePlaceholder().getTextRange())
|
||||
public val LONG_LITERAL_SUFFIX: PositioningStrategy<JetElement> = object : PositioningStrategy<JetElement>() {
|
||||
override fun mark(element: JetElement): List<TextRange> {
|
||||
if (element is JetConstantExpression) {
|
||||
if (element.getNode().getElementType() == JetNodeTypes.INTEGER_CONSTANT) {
|
||||
val endOffset = element.getTextRange().getEndOffset()
|
||||
return listOf(TextRange.create(endOffset - 1, endOffset))
|
||||
}
|
||||
|
||||
if (element is JetClassInitializer) {
|
||||
return ImmutableList.of<TextRange>(element.getTextRange())
|
||||
}
|
||||
|
||||
if (element is JetClassObject) {
|
||||
val objectDeclaration = (element as JetClassObject).getObjectDeclaration()
|
||||
return ImmutableList.of<TextRange>(objectDeclaration.getObjectKeyword().getTextRange())
|
||||
}
|
||||
|
||||
throw IllegalArgumentException(String.format("Can't find text range for element '%s' with the text '%s'", element.javaClass.getCanonicalName(), element.getText()))
|
||||
}
|
||||
return markElement(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val VARIANCE_IN_PROJECTION: PositioningStrategy<JetTypeProjection> = object : PositioningStrategy<JetTypeProjection>() {
|
||||
override fun mark(element: JetTypeProjection): List<TextRange> {
|
||||
return markNode(element.getProjectionNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val PARAMETER_DEFAULT_VALUE: PositioningStrategy<JetParameter> = object : PositioningStrategy<JetParameter>() {
|
||||
override fun mark(element: JetParameter): List<TextRange> {
|
||||
return markNode(element.getDefaultValue()!!.getNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val CALL_ELEMENT: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(callElement: PsiElement): List<TextRange> {
|
||||
if (callElement is JetCallElement) {
|
||||
val calleeExpression = (callElement as JetCallElement).getCalleeExpression()
|
||||
if (calleeExpression != null) {
|
||||
return markElement(calleeExpression)
|
||||
}
|
||||
}
|
||||
return markElement(callElement)
|
||||
}
|
||||
}
|
||||
|
||||
public val DECLARATION_WITH_BODY: PositioningStrategy<JetDeclarationWithBody> = object : PositioningStrategy<JetDeclarationWithBody>() {
|
||||
override fun mark(element: JetDeclarationWithBody): List<TextRange> {
|
||||
val bodyExpression = element.getBodyExpression()
|
||||
if ((bodyExpression is JetBlockExpression)) {
|
||||
val lastBracketRange = (bodyExpression as JetBlockExpression).getLastBracketRange()
|
||||
if (lastBracketRange != null) {
|
||||
return markRange(lastBracketRange)
|
||||
}
|
||||
}
|
||||
return markElement(element)
|
||||
}
|
||||
|
||||
override fun isValid(element: JetDeclarationWithBody): Boolean {
|
||||
if (!super.isValid(element)) return false
|
||||
|
||||
val bodyExpression = element.getBodyExpression()
|
||||
if (!(bodyExpression is JetBlockExpression)) return false
|
||||
if ((bodyExpression as JetBlockExpression).getLastBracketRange() == null) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public val VAL_OR_VAR_NODE: PositioningStrategy<JetProperty> = object : PositioningStrategy<JetProperty>() {
|
||||
override fun mark(property: JetProperty): List<TextRange> {
|
||||
return markNode(property.getValOrVarNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val ELSE_ENTRY: PositioningStrategy<JetWhenEntry> = object : PositioningStrategy<JetWhenEntry>() {
|
||||
override fun mark(entry: JetWhenEntry): List<TextRange> {
|
||||
val elseKeywordElement = entry.getElseKeywordElement()
|
||||
assert(elseKeywordElement != null)
|
||||
return markElement(elseKeywordElement)
|
||||
}
|
||||
}
|
||||
|
||||
public val WHEN_EXPRESSION: PositioningStrategy<JetWhenExpression> = object : PositioningStrategy<JetWhenExpression>() {
|
||||
override fun mark(element: JetWhenExpression): List<TextRange> {
|
||||
return markElement(element.getWhenKeywordElement())
|
||||
}
|
||||
}
|
||||
|
||||
public val WHEN_CONDITION_IN_RANGE: PositioningStrategy<JetWhenConditionInRange> = object : PositioningStrategy<JetWhenConditionInRange>() {
|
||||
override fun mark(condition: JetWhenConditionInRange): List<TextRange> {
|
||||
return markElement(condition.getOperationReference())
|
||||
}
|
||||
}
|
||||
|
||||
public val NULLABLE_TYPE: PositioningStrategy<JetNullableType> = object : PositioningStrategy<JetNullableType>() {
|
||||
override fun mark(element: JetNullableType): List<TextRange> {
|
||||
return markNode(element.getQuestionMarkNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val CALL_EXPRESSION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
if (element is JetCallExpression) {
|
||||
val callExpression = element as JetCallExpression
|
||||
val endElement: PsiElement
|
||||
val typeArgumentList = callExpression.getTypeArgumentList()
|
||||
val calleeExpression = callExpression.getCalleeExpression()
|
||||
if (typeArgumentList != null) {
|
||||
endElement = typeArgumentList
|
||||
}
|
||||
else if (calleeExpression != null) {
|
||||
endElement = calleeExpression
|
||||
}
|
||||
else {
|
||||
endElement = element
|
||||
}
|
||||
return markRange(element, endElement)
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val VALUE_ARGUMENTS: PositioningStrategy<JetElement> = object : PositioningStrategy<JetElement>() {
|
||||
override fun mark(element: JetElement): List<TextRange> {
|
||||
if (element is JetValueArgumentList) {
|
||||
val rightParenthesis = (element as JetValueArgumentList).getRightParenthesis()
|
||||
if (rightParenthesis != null) {
|
||||
return markElement(rightParenthesis)
|
||||
}
|
||||
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val FUNCTION_LITERAL_PARAMETERS: PositioningStrategy<JetFunctionLiteral> = object : PositioningStrategy<JetFunctionLiteral>() {
|
||||
override fun mark(functionLiteral: JetFunctionLiteral): List<TextRange> {
|
||||
val valueParameterList = functionLiteral.getValueParameterList()
|
||||
if (valueParameterList != null) {
|
||||
return markElement(valueParameterList)
|
||||
}
|
||||
return markNode(functionLiteral.getLBrace().getNode())
|
||||
}
|
||||
}
|
||||
|
||||
public val CUT_CHAR_QUOTES: PositioningStrategy<JetElement> = object : PositioningStrategy<JetElement>() {
|
||||
override fun mark(element: JetElement): List<TextRange> {
|
||||
if (element is JetConstantExpression) {
|
||||
if (element.getNode().getElementType() == JetNodeTypes.CHARACTER_CONSTANT) {
|
||||
val elementTextRange = element.getTextRange()
|
||||
return listOf(TextRange.create(elementTextRange.getStartOffset() + 1, elementTextRange.getEndOffset() - 1))
|
||||
}
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
public val LONG_LITERAL_SUFFIX: PositioningStrategy<JetElement> = object : PositioningStrategy<JetElement>() {
|
||||
override fun mark(element: JetElement): List<TextRange> {
|
||||
if (element is JetConstantExpression) {
|
||||
if (element.getNode().getElementType() == JetNodeTypes.INTEGER_CONSTANT) {
|
||||
val endOffset = element.getTextRange().getEndOffset()
|
||||
return listOf(TextRange.create(endOffset - 1, endOffset))
|
||||
}
|
||||
}
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
public fun markTextRangesFromDiagnostic(getTextRanges: Function1<Diagnostic, List<TextRange>>): PositioningStrategy<PsiElement> {
|
||||
return object : PositioningStrategy<PsiElement>() {
|
||||
override fun markDiagnostic(diagnostic: ParametrizedDiagnostic<out PsiElement>): List<TextRange> {
|
||||
return getTextRanges.invoke(diagnostic)
|
||||
}
|
||||
[platformStatic]
|
||||
public fun markTextRangesFromDiagnostic(getTextRanges: (Diagnostic) -> List<TextRange>): PositioningStrategy<PsiElement> {
|
||||
return object : PositioningStrategy<PsiElement>() {
|
||||
override fun markDiagnostic(diagnostic: ParametrizedDiagnostic<out PsiElement>): List<TextRange> {
|
||||
return getTextRanges(diagnostic)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
|
||||
import java.util.Collections
|
||||
|
||||
public open class PositioningStrategy<E : PsiElement> {
|
||||
public open fun markDiagnostic(diagnostic: ParametrizedDiagnostic<out E>): List<TextRange> {
|
||||
return mark(diagnostic.getPsiElement())
|
||||
@@ -37,58 +35,54 @@ public open class PositioningStrategy<E : PsiElement> {
|
||||
public open fun isValid(element: E): Boolean {
|
||||
return !hasSyntaxErrors(element)
|
||||
}
|
||||
}
|
||||
|
||||
class object {
|
||||
fun markElement(element: PsiElement): List<TextRange> {
|
||||
return listOf(TextRange(getStartOffset(element), getEndOffset(element)))
|
||||
}
|
||||
|
||||
protected fun markElement(element: PsiElement): List<TextRange> {
|
||||
return listOf(TextRange(getStartOffset(element), getEndOffset(element)))
|
||||
fun markNode(node: ASTNode): List<TextRange> {
|
||||
return markElement(node.getPsi())
|
||||
}
|
||||
|
||||
fun markRange(range: TextRange): List<TextRange> {
|
||||
return listOf(range)
|
||||
}
|
||||
|
||||
fun markRange(from: PsiElement, to: PsiElement): List<TextRange> {
|
||||
return markRange(TextRange(getStartOffset(from), getEndOffset(to)))
|
||||
}
|
||||
|
||||
private fun getStartOffset(element: PsiElement): Int {
|
||||
var child = element.getFirstChild()
|
||||
if (child != null) {
|
||||
while (child is PsiComment || child is PsiWhiteSpace) {
|
||||
child = child!!.getNextSibling()
|
||||
}
|
||||
|
||||
protected fun markNode(node: ASTNode): List<TextRange> {
|
||||
return markElement(node.getPsi())
|
||||
}
|
||||
|
||||
protected fun markRange(range: TextRange): List<TextRange> {
|
||||
return listOf(range)
|
||||
}
|
||||
|
||||
protected fun markRange(from: PsiElement, to: PsiElement): List<TextRange> {
|
||||
return markRange(TextRange(getStartOffset(from), getEndOffset(to)))
|
||||
}
|
||||
|
||||
private fun getStartOffset(element: PsiElement): Int {
|
||||
var child: PsiElement? = element.getFirstChild()
|
||||
if (child != null) {
|
||||
while (child is PsiComment || child is PsiWhiteSpace) {
|
||||
child = child!!.getNextSibling()
|
||||
}
|
||||
if (child != null) {
|
||||
return getStartOffset(child)
|
||||
}
|
||||
}
|
||||
return element.getTextRange().getStartOffset()
|
||||
}
|
||||
|
||||
private fun getEndOffset(element: PsiElement): Int {
|
||||
var child: PsiElement? = element.getLastChild()
|
||||
if (child != null) {
|
||||
while (child is PsiComment || child is PsiWhiteSpace) {
|
||||
child = child!!.getPrevSibling()
|
||||
}
|
||||
if (child != null) {
|
||||
return getEndOffset(child)
|
||||
}
|
||||
}
|
||||
return element.getTextRange().getEndOffset()
|
||||
}
|
||||
|
||||
protected fun hasSyntaxErrors(psiElement: PsiElement): Boolean {
|
||||
if (psiElement is PsiErrorElement) return true
|
||||
|
||||
val children = psiElement.getChildren()
|
||||
if (children.size > 0 && hasSyntaxErrors(children[children.size - 1])) return true
|
||||
|
||||
return false
|
||||
if (child != null) {
|
||||
return getStartOffset(child!!)
|
||||
}
|
||||
}
|
||||
return element.getTextRange().getStartOffset()
|
||||
}
|
||||
|
||||
private fun getEndOffset(element: PsiElement): Int {
|
||||
var child = element.getLastChild()
|
||||
if (child != null) {
|
||||
while (child is PsiComment || child is PsiWhiteSpace) {
|
||||
child = child!!.getPrevSibling()
|
||||
}
|
||||
if (child != null) {
|
||||
return getEndOffset(child!!)
|
||||
}
|
||||
}
|
||||
return element.getTextRange().getEndOffset()
|
||||
}
|
||||
|
||||
fun hasSyntaxErrors(psiElement: PsiElement): Boolean {
|
||||
if (psiElement is PsiErrorElement) return true
|
||||
|
||||
val children = psiElement.getChildren()
|
||||
return children.isNotEmpty() && hasSyntaxErrors(children.last())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user