Convert PositioningStrategy to Kotlin. Auto-convert.

This commit is contained in:
Evgeny Gerashchenko
2014-12-04 16:07:23 +03:00
parent d4a8aa4eaa
commit 52549607f9
2 changed files with 486 additions and 556 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* 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.
@@ -14,537 +14,472 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.diagnostics;
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.annotations.NotNull;
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 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;
import java.util.List;
import java.util.Arrays
import java.util.Collections
public class PositioningStrategies {
public class PositioningStrategies private() {
public static final PositioningStrategy<PsiElement> DEFAULT = new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull PsiElement element) {
if (element instanceof JetObjectLiteralExpression) {
JetObjectDeclaration objectDeclaration = ((JetObjectLiteralExpression) element).getObjectDeclaration();
PsiElement objectKeyword = objectDeclaration.getObjectKeyword();
JetDelegationSpecifierList delegationSpecifierList = objectDeclaration.getDelegationSpecifierList();
if (delegationSpecifierList == null) {
return markElement(objectKeyword);
}
return markRange(objectKeyword, delegationSpecifierList);
}
else if (element instanceof JetClassObject) {
JetClassObject classObject = (JetClassObject) element;
PsiElement classKeyword = classObject.getClassKeyword();
PsiElement objectKeyword = classObject.getObjectDeclaration().getObjectKeyword();
return markRange(classKeyword, objectKeyword);
}
else {
return super.mark(element);
}
}
};
public static final PositioningStrategy<JetDeclaration> DECLARATION_RETURN_TYPE = new PositioningStrategy<JetDeclaration>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetDeclaration declaration) {
return markElement(getElementToMark(declaration));
}
@Override
public boolean isValid(@NotNull JetDeclaration declaration) {
return !hasSyntaxErrors(getElementToMark(declaration));
}
private PsiElement getElementToMark(@NotNull JetDeclaration declaration) {
JetTypeReference returnTypeRef = null;
PsiElement nameIdentifierOrPlaceholder = null;
if (declaration instanceof JetNamedFunction) {
JetFunction function = (JetNamedFunction) declaration;
returnTypeRef = function.getTypeReference();
nameIdentifierOrPlaceholder = function.getNameIdentifier();
}
else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration;
returnTypeRef = property.getTypeReference();
nameIdentifierOrPlaceholder = property.getNameIdentifier();
}
else if (declaration instanceof JetPropertyAccessor) {
JetPropertyAccessor accessor = (JetPropertyAccessor) declaration;
returnTypeRef = accessor.getReturnTypeReference();
nameIdentifierOrPlaceholder = accessor.getNamePlaceholder();
}
if (returnTypeRef != null) return returnTypeRef;
if (nameIdentifierOrPlaceholder != null) return nameIdentifierOrPlaceholder;
return declaration;
}
};
private static class DeclarationHeader<T extends JetDeclaration> extends PositioningStrategy<T> {
@Override
public boolean isValid(@NotNull T element) {
if (element instanceof JetNamedDeclaration && !(element instanceof JetObjectDeclaration)) {
if (((JetNamedDeclaration) element).getNameIdentifier() == null) {
return false;
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) {
return false
}
}
return super.isValid(element);
return super.isValid(element)
}
}
public static final PositioningStrategy<JetNamedDeclaration> DECLARATION_NAME = new DeclarationHeader<JetNamedDeclaration>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetNamedDeclaration element) {
PsiElement nameIdentifier = element.getNameIdentifier();
if (nameIdentifier != null) {
if (element instanceof JetClassOrObject) {
ASTNode startNode = 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 instanceof JetObjectDeclaration) {
PsiElement objectKeyword = ((JetObjectDeclaration) element).getObjectKeyword();
PsiElement parent = element.getParent();
if (parent instanceof JetClassObject) {
PsiElement classKeyword = ((JetClassObject) parent).getClassKeyword();
PsiElement start = classKeyword == null ? objectKeyword : classKeyword;
return markRange(start, objectKeyword);
}
return markElement(objectKeyword);
}
return super.mark(element);
}
};
class object {
public static final PositioningStrategy<JetDeclaration> DECLARATION_SIGNATURE = new DeclarationHeader<JetDeclaration>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetDeclaration element) {
if (element instanceof JetNamedFunction) {
JetNamedFunction function = (JetNamedFunction)element;
PsiElement endOfSignatureElement;
JetParameterList valueParameterList = function.getValueParameterList();
JetElement returnTypeRef = function.getTypeReference();
PsiElement nameIdentifier = function.getNameIdentifier();
if (returnTypeRef != null) {
endOfSignatureElement = returnTypeRef;
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()
val objectKeyword = objectDeclaration.getObjectKeyword()
val delegationSpecifierList = objectDeclaration.getDelegationSpecifierList()
if (delegationSpecifierList == null) {
return markElement(objectKeyword)
}
return markRange(objectKeyword, delegationSpecifierList)
}
else if (valueParameterList != null) {
endOfSignatureElement = valueParameterList;
}
else if (nameIdentifier != null) {
endOfSignatureElement = nameIdentifier;
else if (element is JetClassObject) {
val classObject = element as JetClassObject
val classKeyword = classObject.getClassKeyword()
val objectKeyword = classObject.getObjectDeclaration().getObjectKeyword()
return markRange(classKeyword, objectKeyword)
}
else {
endOfSignatureElement = function;
return super.mark(element)
}
return markRange(function, endOfSignatureElement);
}
else if (element instanceof JetProperty) {
JetProperty property = (JetProperty) element;
PsiElement endOfSignatureElement;
JetTypeReference propertyTypeRef = property.getTypeReference();
PsiElement nameIdentifier = property.getNameIdentifier();
if (propertyTypeRef != null) {
endOfSignatureElement = propertyTypeRef;
}
else if (nameIdentifier != null) {
endOfSignatureElement = nameIdentifier;
}
else {
endOfSignatureElement = property;
}
return markRange(property, endOfSignatureElement);
}
else if (element instanceof JetPropertyAccessor) {
JetPropertyAccessor accessor = (JetPropertyAccessor) element;
PsiElement endOfSignatureElement = accessor.getReturnTypeReference();
if (endOfSignatureElement == null) {
ASTNode rpar = accessor.getRightParenthesis();
endOfSignatureElement = rpar == null ? null : rpar.getPsi();
}
if (endOfSignatureElement == null) {
endOfSignatureElement = accessor.getNamePlaceholder();
}
return markRange(accessor, endOfSignatureElement);
}
else if (element instanceof JetClass) {
PsiElement nameAsDeclaration = ((JetClass) element).getNameIdentifier();
if (nameAsDeclaration == null) {
return markElement(element);
}
PsiElement primaryConstructorParameterList = ((JetClass) element).getPrimaryConstructorParameterList();
if (primaryConstructorParameterList == null) {
return markElement(nameAsDeclaration);
}
return markRange(nameAsDeclaration, primaryConstructorParameterList);
}
else if (element instanceof JetObjectDeclaration) {
return DECLARATION_NAME.mark((JetObjectDeclaration) element);
}
return super.mark(element);
}
};
public static final PositioningStrategy<PsiElement> DECLARATION_SIGNATURE_OR_DEFAULT = new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull PsiElement element) {
if (element instanceof JetDeclaration) {
return DECLARATION_SIGNATURE.mark((JetDeclaration) element);
}
return DEFAULT.mark(element);
}
@Override
public boolean isValid(@NotNull PsiElement element) {
if (element instanceof JetDeclaration) {
return DECLARATION_SIGNATURE.isValid((JetDeclaration) 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
}
return DEFAULT.isValid(element);
}
};
public static final PositioningStrategy<JetModifierListOwner> ABSTRACT_MODIFIER = modifierSetPosition(JetTokens.ABSTRACT_KEYWORD);
public static final PositioningStrategy<JetModifierListOwner> OVERRIDE_MODIFIER = modifierSetPosition(JetTokens.OVERRIDE_KEYWORD);
public static final PositioningStrategy<JetModifierListOwner> FINAL_MODIFIER = modifierSetPosition(JetTokens.FINAL_KEYWORD);
public static final PositioningStrategy<JetModifierListOwner> VARIANCE_MODIFIER = modifierSetPosition(JetTokens.IN_KEYWORD,
JetTokens.OUT_KEYWORD);
public static final PositioningStrategy<PsiElement> FOR_REDECLARATION = new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull PsiElement element) {
if (element instanceof JetNamedDeclaration) {
PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier();
public val DECLARATION_NAME: PositioningStrategy<JetNamedDeclaration> = object : DeclarationHeader<JetNamedDeclaration>() {
override fun mark(element: JetNamedDeclaration): List<TextRange> {
val nameIdentifier = element.getNameIdentifier()
if (nameIdentifier != null) {
return markElement(nameIdentifier);
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)
}
}
else if (element instanceof JetFile) {
JetFile file = (JetFile) element;
PsiElement nameIdentifier = file.getPackageDirective().getNameIdentifier();
if (nameIdentifier != null) {
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)
}
return markElement(element);
}
};
public static final PositioningStrategy<JetReferenceExpression> FOR_UNRESOLVED_REFERENCE =
new PositioningStrategy<JetReferenceExpression>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetReferenceExpression element) {
if (element instanceof JetArrayAccessExpression) {
List<TextRange> ranges = ((JetArrayAccessExpression) element).getBracketRanges();
if (!ranges.isEmpty()) {
return ranges;
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)
}
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)
}
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)
}
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)
}
return markRange(nameAsDeclaration, primaryConstructorParameterList)
}
else if (element is JetObjectDeclaration) {
return DECLARATION_NAME.mark(element as JetObjectDeclaration)
}
return super.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)
}
}
public val ABSTRACT_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.ABSTRACT_KEYWORD)
public val OVERRIDE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.OVERRIDE_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 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)
}
}
return Collections.singletonList(element.getTextRange());
throw IllegalStateException("None of the modifiers is found: " + Arrays.asList<JetKeywordToken>(*tokens))
}
};
}
}
public static PositioningStrategy<JetModifierListOwner> modifierSetPosition(final JetKeywordToken... tokens) {
return new PositioningStrategy<JetModifierListOwner>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetModifierListOwner modifierListOwner) {
JetModifierList modifierList = modifierListOwner.getModifierList();
assert modifierList != null : "No modifier list, but modifier has been found by the analyzer";
public val ARRAY_ACCESS: PositioningStrategy<JetArrayAccessExpression> = object : PositioningStrategy<JetArrayAccessExpression>() {
override fun mark(element: JetArrayAccessExpression): List<TextRange> {
return markElement(element.getIndicesNode())
}
}
for (JetKeywordToken token : tokens) {
ASTNode node = modifierList.getModifierNode(token);
if (node != null) {
return markNode(node);
public val VISIBILITY_MODIFIER: PositioningStrategy<JetModifierListOwner> = 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())
}
}
throw new IllegalStateException("None of the modifiers is found: " + Arrays.asList(tokens));
}
};
}
public static final PositioningStrategy<JetArrayAccessExpression> ARRAY_ACCESS = new PositioningStrategy<JetArrayAccessExpression>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetArrayAccessExpression element) {
return markElement(element.getIndicesNode());
}
};
if (!result.isEmpty()) return result
public static final PositioningStrategy<JetModifierListOwner> VISIBILITY_MODIFIER = new PositioningStrategy<JetModifierListOwner>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetModifierListOwner element) {
List<JetModifierKeywordToken> visibilityTokens = Lists.newArrayList(
JetTokens.PRIVATE_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PUBLIC_KEYWORD, JetTokens.INTERNAL_KEYWORD);
List<TextRange> result = Lists.newArrayList();
for (JetModifierKeywordToken token : visibilityTokens) {
if (element.hasModifier(token)) {
//noinspection ConstantConditions
result.add(element.getModifierList().getModifierNode(token).getTextRange());
}
}
// Try to resolve situation when there's no visibility modifiers written before element
if (!result.isEmpty()) return result;
// Try to resolve situation when there's no visibility modifiers written before element
if (element instanceof PsiNameIdentifierOwner) {
PsiElement nameIdentifier = ((PsiNameIdentifierOwner) element).getNameIdentifier();
if (nameIdentifier != null) {
return ImmutableList.of(nameIdentifier.getTextRange());
}
}
if (element instanceof JetObjectDeclaration) {
return ImmutableList.of(((JetObjectDeclaration) element).getObjectKeyword().getTextRange());
}
if (element instanceof JetPropertyAccessor) {
return ImmutableList.of(((JetPropertyAccessor) element).getNamePlaceholder().getTextRange());
}
if (element instanceof JetClassInitializer) {
return ImmutableList.of(element.getTextRange());
}
if (element instanceof JetClassObject) {
JetObjectDeclaration objectDeclaration = ((JetClassObject) element).getObjectDeclaration();
return ImmutableList.of(objectDeclaration.getObjectKeyword().getTextRange());
}
throw new IllegalArgumentException(
String.format("Can't find text range for element '%s' with the text '%s'",
element.getClass().getCanonicalName(), element.getText()));
}
};
public static final PositioningStrategy<JetTypeProjection> VARIANCE_IN_PROJECTION = new PositioningStrategy<JetTypeProjection>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetTypeProjection element) {
return markNode(element.getProjectionNode());
}
};
public static final PositioningStrategy<JetParameter> PARAMETER_DEFAULT_VALUE = new PositioningStrategy<JetParameter>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetParameter element) {
return markNode(element.getDefaultValue().getNode());
}
};
public static final PositioningStrategy<PsiElement> CALL_ELEMENT = new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull PsiElement callElement) {
if (callElement instanceof JetCallElement) {
JetExpression calleeExpression = ((JetCallElement) callElement).getCalleeExpression();
if (calleeExpression != null) {
return markElement(calleeExpression);
}
}
return markElement(callElement);
}
};
public static final PositioningStrategy<JetDeclarationWithBody> DECLARATION_WITH_BODY = new PositioningStrategy<JetDeclarationWithBody>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetDeclarationWithBody element) {
JetExpression bodyExpression = element.getBodyExpression();
if ((bodyExpression instanceof JetBlockExpression)) {
TextRange lastBracketRange = ((JetBlockExpression) bodyExpression).getLastBracketRange();
if (lastBracketRange != null) {
return markRange(lastBracketRange);
}
}
return markElement(element);
}
@Override
public boolean isValid(@NotNull JetDeclarationWithBody element) {
if (!super.isValid(element)) return false;
JetExpression bodyExpression = element.getBodyExpression();
if (!(bodyExpression instanceof JetBlockExpression)) return false;
if (((JetBlockExpression) bodyExpression).getLastBracketRange() == null) return false;
return true;
}
};
public static final PositioningStrategy<JetProperty> VAL_OR_VAR_NODE = new PositioningStrategy<JetProperty>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetProperty property) {
return markNode(property.getValOrVarNode());
}
};
public static final PositioningStrategy<JetWhenEntry> ELSE_ENTRY = new PositioningStrategy<JetWhenEntry>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetWhenEntry entry) {
PsiElement elseKeywordElement = entry.getElseKeywordElement();
assert elseKeywordElement != null;
return markElement(elseKeywordElement);
}
};
public static final PositioningStrategy<JetWhenExpression> WHEN_EXPRESSION = new PositioningStrategy<JetWhenExpression>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetWhenExpression element) {
return markElement(element.getWhenKeywordElement());
}
};
public static final PositioningStrategy<JetWhenConditionInRange> WHEN_CONDITION_IN_RANGE =
new PositioningStrategy<JetWhenConditionInRange>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetWhenConditionInRange condition) {
return markElement(condition.getOperationReference());
}
};
public static final PositioningStrategy<JetNullableType> NULLABLE_TYPE = new PositioningStrategy<JetNullableType>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetNullableType element) {
return markNode(element.getQuestionMarkNode());
}
};
public static final PositioningStrategy<PsiElement> CALL_EXPRESSION = new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull PsiElement element) {
if (element instanceof JetCallExpression) {
JetCallExpression callExpression = (JetCallExpression) element;
PsiElement endElement;
JetTypeArgumentList typeArgumentList = callExpression.getTypeArgumentList();
JetExpression 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 static final PositioningStrategy<JetElement> VALUE_ARGUMENTS = new PositioningStrategy<JetElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetElement element) {
if (element instanceof JetValueArgumentList) {
PsiElement rightParenthesis = ((JetValueArgumentList) element).getRightParenthesis();
if (rightParenthesis != null) {
return markElement(rightParenthesis);
if (element is PsiNameIdentifierOwner) {
val nameIdentifier = (element as PsiNameIdentifierOwner).getNameIdentifier()
if (nameIdentifier != null) {
return ImmutableList.of<TextRange>(nameIdentifier.getTextRange())
}
}
}
return super.mark(element);
}
};
if (element is JetObjectDeclaration) {
return ImmutableList.of<TextRange>((element as JetObjectDeclaration).getObjectKeyword().getTextRange())
}
public static final PositioningStrategy<JetFunctionLiteral> FUNCTION_LITERAL_PARAMETERS = new PositioningStrategy<JetFunctionLiteral>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetFunctionLiteral functionLiteral) {
JetParameterList valueParameterList = functionLiteral.getValueParameterList();
if (valueParameterList != null) {
return markElement(valueParameterList);
}
return markNode(functionLiteral.getLBrace().getNode());
}
};
if (element is JetPropertyAccessor) {
return ImmutableList.of<TextRange>((element as JetPropertyAccessor).getNamePlaceholder().getTextRange())
}
public static final PositioningStrategy<JetElement> CUT_CHAR_QUOTES = new PositioningStrategy<JetElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetElement element) {
if (element instanceof JetConstantExpression) {
if (element.getNode().getElementType() == JetNodeTypes.CHARACTER_CONSTANT) {
TextRange elementTextRange = element.getTextRange();
return Collections.singletonList(
TextRange.create(elementTextRange.getStartOffset() + 1, elementTextRange.getEndOffset() - 1));
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()))
}
}
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)
}
}
return super.mark(element);
}
};
public static final PositioningStrategy<JetElement> LONG_LITERAL_SUFFIX = new PositioningStrategy<JetElement>() {
@NotNull
@Override
public List<TextRange> mark(@NotNull JetElement element) {
if (element instanceof JetConstantExpression) {
if (element.getNode().getElementType() == JetNodeTypes.INTEGER_CONSTANT) {
int endOffset = element.getTextRange().getEndOffset();
return Collections.singletonList(TextRange.create(endOffset - 1, endOffset));
}
}
return super.mark(element);
}
};
public static PositioningStrategy<PsiElement> markTextRangesFromDiagnostic(
@NotNull final Function1<Diagnostic, List<TextRange>> getTextRanges
) {
return new PositioningStrategy<PsiElement>() {
@NotNull
@Override
public List<TextRange> markDiagnostic(@NotNull ParametrizedDiagnostic<? extends PsiElement> diagnostic) {
return getTextRanges.invoke(diagnostic);
}
};
}
private PositioningStrategies() {
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* 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.
@@ -14,86 +14,81 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.diagnostics;
package org.jetbrains.jet.lang.diagnostics
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiWhiteSpace;
import org.jetbrains.annotations.NotNull;
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiWhiteSpace
import java.util.Collections;
import java.util.List;
import java.util.Collections
public class PositioningStrategy<E extends PsiElement> {
@NotNull
public List<TextRange> markDiagnostic(@NotNull ParametrizedDiagnostic<? extends E> diagnostic) {
return mark(diagnostic.getPsiElement());
public open class PositioningStrategy<E : PsiElement> {
public open fun markDiagnostic(diagnostic: ParametrizedDiagnostic<out E>): List<TextRange> {
return mark(diagnostic.getPsiElement())
}
@NotNull
protected List<TextRange> mark(@NotNull E element) {
return markElement(element);
protected open fun mark(element: E): List<TextRange> {
return markElement(element)
}
public boolean isValid(@NotNull E element) {
return !hasSyntaxErrors(element);
public open fun isValid(element: E): Boolean {
return !hasSyntaxErrors(element)
}
@NotNull
protected static List<TextRange> markElement(@NotNull PsiElement element) {
return Collections.singletonList(new TextRange(getStartOffset(element), getEndOffset(element)));
}
class object {
@NotNull
protected static List<TextRange> markNode(@NotNull ASTNode node) {
return markElement(node.getPsi());
}
@NotNull
protected static List<TextRange> markRange(@NotNull TextRange range) {
return Collections.singletonList(range);
}
@NotNull
protected static List<TextRange> markRange(@NotNull PsiElement from, @NotNull PsiElement to) {
return markRange(new TextRange(getStartOffset(from), getEndOffset(to)));
}
private static int getStartOffset(@NotNull PsiElement element) {
PsiElement child = element.getFirstChild();
if (child != null) {
while (child instanceof PsiComment || child instanceof PsiWhiteSpace) {
child = child.getNextSibling();
}
if (child != null) {
return getStartOffset(child);
}
protected fun markElement(element: PsiElement): List<TextRange> {
return listOf(TextRange(getStartOffset(element), getEndOffset(element)))
}
return element.getTextRange().getStartOffset();
}
private static int getEndOffset(@NotNull PsiElement element) {
PsiElement child = element.getLastChild();
if (child != null) {
while (child instanceof PsiComment || child instanceof PsiWhiteSpace) {
child = child.getPrevSibling();
}
if (child != null) {
return getEndOffset(child);
}
protected fun markNode(node: ASTNode): List<TextRange> {
return markElement(node.getPsi())
}
return element.getTextRange().getEndOffset();
}
protected static boolean hasSyntaxErrors(@NotNull PsiElement psiElement) {
if (psiElement instanceof PsiErrorElement) return true;
protected fun markRange(range: TextRange): List<TextRange> {
return listOf(range)
}
PsiElement[] children = psiElement.getChildren();
if (children.length > 0 && hasSyntaxErrors(children[children.length - 1])) return true;
protected fun markRange(from: PsiElement, to: PsiElement): List<TextRange> {
return markRange(TextRange(getStartOffset(from), getEndOffset(to)))
}
return false;
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
}
}
}