Added ability not to mark error if there is a syntax one in some cases
This commit is contained in:
@@ -44,8 +44,8 @@ public class CheckerTestUtil {
|
|||||||
public static final Comparator<Diagnostic> DIAGNOSTIC_COMPARATOR = new Comparator<Diagnostic>() {
|
public static final Comparator<Diagnostic> DIAGNOSTIC_COMPARATOR = new Comparator<Diagnostic>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(Diagnostic o1, Diagnostic o2) {
|
public int compare(Diagnostic o1, Diagnostic o2) {
|
||||||
List<TextRange> ranges1 = getTextRanges(o1);
|
List<TextRange> ranges1 = o1.getTextRanges();
|
||||||
List<TextRange> ranges2 = getTextRanges(o2);
|
List<TextRange> ranges2 = o2.getTextRanges();
|
||||||
if (ranges1.size() != ranges2.size()) return ranges1.size() - ranges2.size();
|
if (ranges1.size() != ranges2.size()) return ranges1.size() - ranges2.size();
|
||||||
for (int i = 0; i < ranges1.size(); i++) {
|
for (int i = 0; i < ranges1.size(); i++) {
|
||||||
TextRange range1 = ranges1.get(i);
|
TextRange range1 = ranges1.get(i);
|
||||||
@@ -160,7 +160,7 @@ public class CheckerTestUtil {
|
|||||||
private static void unexpectedDiagnostics(List<Diagnostic> actual, DiagnosticDiffCallbacks callbacks) {
|
private static void unexpectedDiagnostics(List<Diagnostic> actual, DiagnosticDiffCallbacks callbacks) {
|
||||||
for (Diagnostic diagnostic : actual) {
|
for (Diagnostic diagnostic : actual) {
|
||||||
if (!diagnostic.getPsiFile().equals(callbacks.getFile())) continue;
|
if (!diagnostic.getPsiFile().equals(callbacks.getFile())) continue;
|
||||||
List<TextRange> textRanges = getTextRanges(diagnostic);
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
for (TextRange textRange : textRanges) {
|
for (TextRange textRange : textRanges) {
|
||||||
callbacks.unexpectedDiagnostic(diagnostic.getFactory().getName(), textRange.getStartOffset(), textRange.getEndOffset());
|
callbacks.unexpectedDiagnostic(diagnostic.getFactory().getName(), textRange.getStartOffset(), textRange.getEndOffset());
|
||||||
}
|
}
|
||||||
@@ -358,7 +358,10 @@ public class CheckerTestUtil {
|
|||||||
List<DiagnosticDescriptor> diagnosticDescriptors = Lists.newArrayList();
|
List<DiagnosticDescriptor> diagnosticDescriptors = Lists.newArrayList();
|
||||||
DiagnosticDescriptor currentDiagnosticDescriptor = null;
|
DiagnosticDescriptor currentDiagnosticDescriptor = null;
|
||||||
for (Diagnostic diagnostic : list) {
|
for (Diagnostic diagnostic : list) {
|
||||||
TextRange textRange = getTextRanges(diagnostic).get(0);
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
|
if (textRanges.isEmpty()) continue;
|
||||||
|
|
||||||
|
TextRange textRange = textRanges.get(0);
|
||||||
if (currentDiagnosticDescriptor != null && currentDiagnosticDescriptor.equalRange(textRange)) {
|
if (currentDiagnosticDescriptor != null && currentDiagnosticDescriptor.equalRange(textRange)) {
|
||||||
currentDiagnosticDescriptor.diagnostics.add(diagnostic);
|
currentDiagnosticDescriptor.diagnostics.add(diagnostic);
|
||||||
}
|
}
|
||||||
@@ -370,10 +373,6 @@ public class CheckerTestUtil {
|
|||||||
return diagnosticDescriptors;
|
return diagnosticDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<TextRange> getTextRanges(Diagnostic currentDiagnostic) {
|
|
||||||
return currentDiagnostic.getTextRanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class DiagnosticDescriptor {
|
private static class DiagnosticDescriptor {
|
||||||
private final int start;
|
private final int start;
|
||||||
private final int end;
|
private final int end;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import com.intellij.psi.PsiFile;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -75,11 +77,13 @@ public class DiagnosticUtils {
|
|||||||
return offsetToLineAndColumn(document, offset).toString() + pathSuffix;
|
return offsetToLineAndColumn(document, offset).toString() + pathSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
public static LineAndColumn getLineAndColumn(@NotNull Diagnostic diagnostic) {
|
public static LineAndColumn getLineAndColumn(@NotNull Diagnostic diagnostic) {
|
||||||
PsiFile file = diagnostic.getPsiFile();
|
PsiFile file = diagnostic.getPsiFile();
|
||||||
Document document = file.getViewProvider().getDocument();
|
Document document = file.getViewProvider().getDocument();
|
||||||
TextRange firstRange = diagnostic.getTextRanges().iterator().next();
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
|
if (textRanges.isEmpty()) return null;
|
||||||
|
TextRange firstRange = textRanges.iterator().next();
|
||||||
return offsetToLineAndColumn(document, firstRange.getStartOffset());
|
return offsetToLineAndColumn(document, firstRange.getStartOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.jetbrains.jet.resolve.DescriptorRenderer;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -116,7 +117,6 @@ public interface Errors {
|
|||||||
DiagnosticFactory<JetExpression> MANY_FUNCTION_LITERAL_ARGUMENTS = DiagnosticFactory.create(ERROR, "Only one function literal is allowed outside a parenthesized argument list");
|
DiagnosticFactory<JetExpression> MANY_FUNCTION_LITERAL_ARGUMENTS = DiagnosticFactory.create(ERROR, "Only one function literal is allowed outside a parenthesized argument list");
|
||||||
DiagnosticFactory<PsiElement> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = DiagnosticFactory.create(ERROR, "This property must either have a type annotation or be initialized");
|
DiagnosticFactory<PsiElement> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = DiagnosticFactory.create(ERROR, "This property must either have a type annotation or be initialized");
|
||||||
|
|
||||||
DiagnosticFactory<JetElement> FUNCTION_WITH_NO_TYPE_NO_BODY = DiagnosticFactory.create(ERROR, "This function must either declare a return type or have a body element");
|
|
||||||
DiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = DiagnosticFactory.create(ERROR, "This property cannot be declared abstract", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
DiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = DiagnosticFactory.create(ERROR, "This property cannot be declared abstract", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
||||||
DiagnosticFactory<JetProperty> ABSTRACT_PROPERTY_NOT_IN_CLASS = DiagnosticFactory.create(ERROR, "A property may be abstract only when defined in a class or trait", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
DiagnosticFactory<JetProperty> ABSTRACT_PROPERTY_NOT_IN_CLASS = DiagnosticFactory.create(ERROR, "A property may be abstract only when defined in a class or trait", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
||||||
DiagnosticFactory<JetExpression> ABSTRACT_PROPERTY_WITH_INITIALIZER = DiagnosticFactory.create(ERROR, "Property with initializer cannot be abstract");
|
DiagnosticFactory<JetExpression> ABSTRACT_PROPERTY_WITH_INITIALIZER = DiagnosticFactory.create(ERROR, "Property with initializer cannot be abstract");
|
||||||
@@ -124,21 +124,21 @@ public interface Errors {
|
|||||||
DiagnosticFactory<JetPropertyAccessor> ABSTRACT_PROPERTY_WITH_SETTER = DiagnosticFactory.create(ERROR, "Property with setter implementation cannot be abstract");
|
DiagnosticFactory<JetPropertyAccessor> ABSTRACT_PROPERTY_WITH_SETTER = DiagnosticFactory.create(ERROR, "Property with setter implementation cannot be abstract");
|
||||||
|
|
||||||
DiagnosticFactory<PsiElement> GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY = DiagnosticFactory.create(ERROR, "Getter visibility must be the same as property visibility");
|
DiagnosticFactory<PsiElement> GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY = DiagnosticFactory.create(ERROR, "Getter visibility must be the same as property visibility");
|
||||||
DiagnosticFactory BACKING_FIELD_IN_TRAIT = DiagnosticFactory.create(ERROR, "Property in a trait cannot have a backing field");
|
DiagnosticFactory<JetProperty> BACKING_FIELD_IN_TRAIT = DiagnosticFactory.create(ERROR, "Property in a trait cannot have a backing field", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
||||||
DiagnosticFactory MUST_BE_INITIALIZED = DiagnosticFactory.create(ERROR, "Property must be initialized");
|
DiagnosticFactory<JetProperty> MUST_BE_INITIALIZED = DiagnosticFactory.create(ERROR, "Property must be initialized", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
||||||
DiagnosticFactory<PsiElement> MUST_BE_INITIALIZED_OR_BE_ABSTRACT = DiagnosticFactory.create(ERROR, "Property must be initialized or be abstract");
|
DiagnosticFactory<JetProperty> MUST_BE_INITIALIZED_OR_BE_ABSTRACT = DiagnosticFactory.create(ERROR, "Property must be initialized or be abstract", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
||||||
DiagnosticFactory<JetExpression> PROPERTY_INITIALIZER_IN_TRAIT = DiagnosticFactory.create(ERROR, "Property initializers are not allowed in traits");
|
DiagnosticFactory<JetExpression> PROPERTY_INITIALIZER_IN_TRAIT = DiagnosticFactory.create(ERROR, "Property initializers are not allowed in traits");
|
||||||
DiagnosticFactory PROPERTY_INITIALIZER_NO_BACKING_FIELD = DiagnosticFactory.create(ERROR, "Initializer is not allowed here because this property has no backing field");
|
DiagnosticFactory<JetExpression> PROPERTY_INITIALIZER_NO_BACKING_FIELD = DiagnosticFactory.create(ERROR, "Initializer is not allowed here because this property has no backing field");
|
||||||
DiagnosticFactory3<JetModifierListOwner, String, ClassDescriptor, JetClass> ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS = DiagnosticFactory3.create(ERROR, "Abstract property {0} in non-abstract class {1}", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
DiagnosticFactory3<JetModifierListOwner, String, ClassDescriptor, JetClass> ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS = DiagnosticFactory3.create(ERROR, "Abstract property {0} in non-abstract class {1}", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
||||||
DiagnosticFactory3<JetFunction, String, ClassDescriptor, JetClass> ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = DiagnosticFactory3.create(ERROR, "Abstract function {0} in non-abstract class {1}", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
DiagnosticFactory3<JetFunction, String, ClassDescriptor, JetClass> ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = DiagnosticFactory3.create(ERROR, "Abstract function {0} in non-abstract class {1}", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
||||||
DiagnosticFactory1<PsiElement, SimpleFunctionDescriptor> ABSTRACT_FUNCTION_WITH_BODY = DiagnosticFactory1.create(ERROR, "A function {0} with body cannot be abstract");
|
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> ABSTRACT_FUNCTION_WITH_BODY = DiagnosticFactory1.create(ERROR, "A function {0} with body cannot be abstract", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
||||||
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = DiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = DiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
||||||
DiagnosticFactory1<JetModifierListOwner, SimpleFunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = DiagnosticFactory1.create(ERROR, "Function {0} is not a class or trait member and cannot be abstract", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
DiagnosticFactory1<JetModifierListOwner, SimpleFunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = DiagnosticFactory1.create(ERROR, "Function {0} is not a class or trait member and cannot be abstract", PositioningStrategies.POSITION_ABSTRACT_MODIFIER);
|
||||||
|
|
||||||
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = DiagnosticFactory1.create(ERROR, "Function {0} must have a body", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = DiagnosticFactory1.create(ERROR, "Function {0} must have a body", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
||||||
DiagnosticFactory<PsiElement> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory.create(ERROR, "Non final member in a final class");
|
DiagnosticFactory<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory.create(ERROR, "Non final member in a final class", PositioningStrategies.positionModifier(JetTokens.OPEN_KEYWORD));
|
||||||
|
|
||||||
DiagnosticFactory<PsiElement> PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = DiagnosticFactory.create(ERROR, "Public or protected member should specify a type");
|
DiagnosticFactory<JetNamedDeclaration> PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = DiagnosticFactory.create(ERROR, "Public or protected member should specify a type", PositioningStrategies.POSITION_NAME_IDENTIFIER);
|
||||||
|
|
||||||
DiagnosticFactory<JetTypeProjection> PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = DiagnosticFactory.create(ERROR, "Projections are not allowed on type arguments of functions and properties"); // TODO : better positioning
|
DiagnosticFactory<JetTypeProjection> PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = DiagnosticFactory.create(ERROR, "Projections are not allowed on type arguments of functions and properties"); // TODO : better positioning
|
||||||
DiagnosticFactory<JetDelegatorToSuperClass> SUPERTYPE_NOT_INITIALIZED = DiagnosticFactory.create(ERROR, "This type has a constructor, and thus must be initialized here");
|
DiagnosticFactory<JetDelegatorToSuperClass> SUPERTYPE_NOT_INITIALIZED = DiagnosticFactory.create(ERROR, "This type has a constructor, and thus must be initialized here");
|
||||||
@@ -189,20 +189,8 @@ public interface Errors {
|
|||||||
DiagnosticFactory<JetPropertyAccessor> LOCAL_VARIABLE_WITH_SETTER = DiagnosticFactory.create(ERROR, "Local variables are not allowed to have setters");
|
DiagnosticFactory<JetPropertyAccessor> LOCAL_VARIABLE_WITH_SETTER = DiagnosticFactory.create(ERROR, "Local variables are not allowed to have setters");
|
||||||
DiagnosticFactory<JetPropertyAccessor> VAL_WITH_SETTER = DiagnosticFactory.create(ERROR, "A 'val'-property cannot have a setter");
|
DiagnosticFactory<JetPropertyAccessor> VAL_WITH_SETTER = DiagnosticFactory.create(ERROR, "A 'val'-property cannot have a setter");
|
||||||
|
|
||||||
DiagnosticFactory<JetArrayAccessExpression> NO_GET_METHOD = DiagnosticFactory.create(ERROR, "No get method providing array access", new PositioningStrategy<JetArrayAccessExpression>() {
|
DiagnosticFactory<JetArrayAccessExpression> NO_GET_METHOD = DiagnosticFactory.create(ERROR, "No get method providing array access", PositioningStrategies.POSITION_ARRAY_ACCESS);
|
||||||
@NotNull
|
DiagnosticFactory<JetArrayAccessExpression> NO_SET_METHOD = DiagnosticFactory.create(ERROR, "No set method providing array access", PositioningStrategies.POSITION_ARRAY_ACCESS);
|
||||||
@Override
|
|
||||||
public List<TextRange> mark(@NotNull JetArrayAccessExpression element) {
|
|
||||||
return markElement(element.getIndicesNode());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
DiagnosticFactory<JetArrayAccessExpression> NO_SET_METHOD = DiagnosticFactory.create(ERROR, "No set method providing array access", new PositioningStrategy<JetArrayAccessExpression>() {
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<TextRange> mark(@NotNull JetArrayAccessExpression element) {
|
|
||||||
return markElement(element.getIndicesNode());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
DiagnosticFactory<JetSimpleNameExpression> INC_DEC_SHOULD_NOT_RETURN_UNIT = DiagnosticFactory.create(ERROR, "Functions inc(), dec() shouldn't return Unit to be used by operators ++, --");
|
DiagnosticFactory<JetSimpleNameExpression> INC_DEC_SHOULD_NOT_RETURN_UNIT = DiagnosticFactory.create(ERROR, "Functions inc(), dec() shouldn't return Unit to be used by operators ++, --");
|
||||||
DiagnosticFactory2<JetSimpleNameExpression, DeclarationDescriptor, JetSimpleNameExpression> ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT =
|
DiagnosticFactory2<JetSimpleNameExpression, DeclarationDescriptor, JetSimpleNameExpression> ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT =
|
||||||
@@ -218,10 +206,9 @@ public interface Errors {
|
|||||||
DiagnosticFactory<JetThisExpression> NO_THIS = DiagnosticFactory.create(ERROR, "'this' is not defined in this context");
|
DiagnosticFactory<JetThisExpression> NO_THIS = DiagnosticFactory.create(ERROR, "'this' is not defined in this context");
|
||||||
DiagnosticFactory<JetSuperExpression> SUPER_NOT_AVAILABLE = DiagnosticFactory.create(ERROR, "No supertypes are accessible in this context");
|
DiagnosticFactory<JetSuperExpression> SUPER_NOT_AVAILABLE = DiagnosticFactory.create(ERROR, "No supertypes are accessible in this context");
|
||||||
DiagnosticFactory<JetSuperExpression> AMBIGUOUS_SUPER = DiagnosticFactory.create(ERROR, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super<Foo>'");
|
DiagnosticFactory<JetSuperExpression> AMBIGUOUS_SUPER = DiagnosticFactory.create(ERROR, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super<Foo>'");
|
||||||
DiagnosticFactory<JetExpression> ABSTRACT_SUPER_CALL = DiagnosticFactory.create(ERROR, "Abstarct member cannot be accessed directly");
|
DiagnosticFactory<JetExpression> ABSTRACT_SUPER_CALL = DiagnosticFactory.create(ERROR, "Abstract member cannot be accessed directly");
|
||||||
DiagnosticFactory<JetTypeReference> NOT_A_SUPERTYPE = DiagnosticFactory.create(ERROR, "Not a supertype");
|
DiagnosticFactory<JetTypeReference> NOT_A_SUPERTYPE = DiagnosticFactory.create(ERROR, "Not a supertype");
|
||||||
DiagnosticFactory<PsiElement> TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER = DiagnosticFactory.create(WARNING, "Type arguments do not need to be specified in a 'super' qualifier");
|
DiagnosticFactory<PsiElement> TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER = DiagnosticFactory.create(WARNING, "Type arguments do not need to be specified in a 'super' qualifier");
|
||||||
DiagnosticFactory<JetWhenExpression> NO_WHEN_ENTRIES = DiagnosticFactory.create(ERROR, "Entries are required for when-expression"); // TODO : Scope, and maybe this should not be an error
|
|
||||||
DiagnosticFactory<JetSimpleNameExpression> USELESS_CAST_STATIC_ASSERT_IS_FINE = DiagnosticFactory.create(WARNING, "No cast needed, use ':' instead");
|
DiagnosticFactory<JetSimpleNameExpression> USELESS_CAST_STATIC_ASSERT_IS_FINE = DiagnosticFactory.create(WARNING, "No cast needed, use ':' instead");
|
||||||
DiagnosticFactory<JetSimpleNameExpression> USELESS_CAST = DiagnosticFactory.create(WARNING, "No cast needed");
|
DiagnosticFactory<JetSimpleNameExpression> USELESS_CAST = DiagnosticFactory.create(WARNING, "No cast needed");
|
||||||
DiagnosticFactory<JetSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory.create(WARNING, "This cast can never succeed");
|
DiagnosticFactory<JetSimpleNameExpression> CAST_NEVER_SUCCEEDS = DiagnosticFactory.create(WARNING, "This cast can never succeed");
|
||||||
@@ -285,6 +272,7 @@ public interface Errors {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<TextRange> mark(@NotNull JetWhenExpression element) {
|
public List<TextRange> mark(@NotNull JetWhenExpression element) {
|
||||||
|
if (hasSyntaxError(element)) return Collections.emptyList();
|
||||||
return markElement(element.getWhenKeywordElement());
|
return markElement(element.getWhenKeywordElement());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+14
-26
@@ -20,6 +20,7 @@ package org.jetbrains.jet.lang.diagnostics;
|
|||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiErrorElement;
|
||||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -36,31 +37,6 @@ public class PositioningStrategies {
|
|||||||
|
|
||||||
public static final PositioningStrategy<PsiElement> DEFAULT = new PositioningStrategy<PsiElement>();
|
public static final PositioningStrategy<PsiElement> DEFAULT = new PositioningStrategy<PsiElement>();
|
||||||
|
|
||||||
public static final PositioningStrategy<JetFunction> MARK_FUNCTION = new PositioningStrategy<JetFunction>() {
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<TextRange> mark(@NotNull JetFunction function) {
|
|
||||||
TextRange textRange;
|
|
||||||
PsiElement nameIdentifier = function.getNameIdentifier();
|
|
||||||
JetTypeReference returnTypeRef = function.getReturnTypeRef();
|
|
||||||
JetParameterList valueParameterList = function.getValueParameterList();
|
|
||||||
if (nameIdentifier == null) {
|
|
||||||
textRange = TextRange.from(function.getTextRange().getEndOffset(), 0);
|
|
||||||
}
|
|
||||||
else if (returnTypeRef != null) {
|
|
||||||
textRange = TextRange.from(returnTypeRef.getTextRange().getEndOffset(), 1);
|
|
||||||
}
|
|
||||||
else if (valueParameterList != null) {
|
|
||||||
textRange = TextRange.from(valueParameterList.getTextRange().getEndOffset(), 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
textRange = TextRange.from(nameIdentifier.getTextRange().getEndOffset(), 1);
|
|
||||||
}
|
|
||||||
return markRange(textRange);
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final PositioningStrategy<JetDeclaration> POSITION_DECLARATION = new PositioningStrategy<JetDeclaration>() {
|
public static final PositioningStrategy<JetDeclaration> POSITION_DECLARATION = new PositioningStrategy<JetDeclaration>() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -87,6 +63,7 @@ public class PositioningStrategies {
|
|||||||
return super.mark(declaration);
|
return super.mark(declaration);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ASTNode getNameNode(JetNamedDeclaration function) {
|
private ASTNode getNameNode(JetNamedDeclaration function) {
|
||||||
PsiElement nameIdentifier = function.getNameIdentifier();
|
PsiElement nameIdentifier = function.getNameIdentifier();
|
||||||
return nameIdentifier == null ? null : nameIdentifier.getNode();
|
return nameIdentifier == null ? null : nameIdentifier.getNode();
|
||||||
@@ -97,6 +74,9 @@ public class PositioningStrategies {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<TextRange> mark(@NotNull PsiNameIdentifierOwner element) {
|
public List<TextRange> mark(@NotNull PsiNameIdentifierOwner element) {
|
||||||
|
if (element.getLastChild() instanceof PsiErrorElement) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
PsiElement nameIdentifier = element.getNameIdentifier();
|
PsiElement nameIdentifier = element.getNameIdentifier();
|
||||||
if (nameIdentifier != null) {
|
if (nameIdentifier != null) {
|
||||||
return markElement(nameIdentifier);
|
return markElement(nameIdentifier);
|
||||||
@@ -114,7 +94,7 @@ public class PositioningStrategies {
|
|||||||
public List<TextRange> mark(@NotNull JetModifierListOwner modifierListOwner) {
|
public List<TextRange> mark(@NotNull JetModifierListOwner modifierListOwner) {
|
||||||
if (modifierListOwner.hasModifier(token)) {
|
if (modifierListOwner.hasModifier(token)) {
|
||||||
JetModifierList modifierList = modifierListOwner.getModifierList();
|
JetModifierList modifierList = modifierListOwner.getModifierList();
|
||||||
assert modifierList != null;
|
assert modifierList != null;
|
||||||
ASTNode node = modifierList.getModifierNode(token);
|
ASTNode node = modifierList.getModifierNode(token);
|
||||||
assert node != null;
|
assert node != null;
|
||||||
return Collections.singletonList(node.getTextRange());
|
return Collections.singletonList(node.getTextRange());
|
||||||
@@ -123,4 +103,12 @@ public class PositioningStrategies {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PositioningStrategy<JetArrayAccessExpression> POSITION_ARRAY_ACCESS = new PositioningStrategy<JetArrayAccessExpression>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<TextRange> mark(@NotNull JetArrayAccessExpression element) {
|
||||||
|
return markElement(element.getIndicesNode());
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.diagnostics;
|
|||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiErrorElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -33,6 +34,10 @@ public class PositioningStrategy<E extends PsiElement> {
|
|||||||
return markElement(element);
|
return markElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean hasSyntaxError(@NotNull E element) {
|
||||||
|
return element.getLastChild() instanceof PsiErrorElement;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected static List<TextRange> markElement(@NotNull PsiElement element) {
|
protected static List<TextRange> markElement(@NotNull PsiElement element) {
|
||||||
return Collections.singletonList(element.getTextRange());
|
return Collections.singletonList(element.getTextRange());
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class DeclarationsChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkClass(JetClass aClass, MutableClassDescriptor classDescriptor) {
|
private void checkClass(JetClass aClass, MutableClassDescriptor classDescriptor) {
|
||||||
checkOpenMembers(aClass, classDescriptor);
|
checkOpenMembers(classDescriptor);
|
||||||
checkTraitModifiers(aClass);
|
checkTraitModifiers(aClass);
|
||||||
checkEnum(aClass, classDescriptor);
|
checkEnum(aClass, classDescriptor);
|
||||||
}
|
}
|
||||||
@@ -118,15 +118,12 @@ public class DeclarationsChecker {
|
|||||||
checkIllegalInThisContextModifiers(objectDeclaration.getModifierList(), Sets.newHashSet(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
checkIllegalInThisContextModifiers(objectDeclaration.getModifierList(), Sets.newHashSet(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkOpenMembers(JetClass aClass, MutableClassDescriptor classDescriptor) {
|
private void checkOpenMembers(MutableClassDescriptor classDescriptor) {
|
||||||
for (CallableMemberDescriptor memberDescriptor : classDescriptor.getCallableMembers()) {
|
for (CallableMemberDescriptor memberDescriptor : classDescriptor.getCallableMembers()) {
|
||||||
|
|
||||||
JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, memberDescriptor);
|
JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, memberDescriptor);
|
||||||
if (member != null && classDescriptor.getModality() == Modality.FINAL && member.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
if (member != null && classDescriptor.getModality() == Modality.FINAL && member.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
||||||
JetModifierList modifierList = member.getModifierList();
|
context.getTrace().report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member));
|
||||||
assert modifierList != null;
|
|
||||||
ASTNode openModifierNode = modifierList.getModifierNode(JetTokens.OPEN_KEYWORD);
|
|
||||||
context.getTrace().report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(openModifierNode.getPsi()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +140,6 @@ public class DeclarationsChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkDeclaredTypeInPublicMember(JetNamedDeclaration member, CallableMemberDescriptor memberDescriptor) {
|
private void checkDeclaredTypeInPublicMember(JetNamedDeclaration member, CallableMemberDescriptor memberDescriptor) {
|
||||||
PsiElement nameIdentifier = member.getNameIdentifier();
|
|
||||||
boolean hasDeferredType;
|
boolean hasDeferredType;
|
||||||
if (member instanceof JetProperty) {
|
if (member instanceof JetProperty) {
|
||||||
hasDeferredType = ((JetProperty) member).getPropertyTypeRef() == null && DescriptorResolver.hasBody((JetProperty) member);
|
hasDeferredType = ((JetProperty) member).getPropertyTypeRef() == null && DescriptorResolver.hasBody((JetProperty) member);
|
||||||
@@ -153,9 +149,8 @@ public class DeclarationsChecker {
|
|||||||
JetFunction function = (JetFunction) member;
|
JetFunction function = (JetFunction) member;
|
||||||
hasDeferredType = function.getReturnTypeRef() == null && function.getBodyExpression() != null && !function.hasBlockBody();
|
hasDeferredType = function.getReturnTypeRef() == null && function.getBodyExpression() != null && !function.hasBlockBody();
|
||||||
}
|
}
|
||||||
if ((memberDescriptor.getVisibility() == Visibility.PUBLIC || memberDescriptor.getVisibility() == Visibility.PROTECTED) &&
|
if ((memberDescriptor.getVisibility() == Visibility.PUBLIC || memberDescriptor.getVisibility() == Visibility.PROTECTED) && hasDeferredType) {
|
||||||
hasDeferredType && nameIdentifier != null) {
|
context.getTrace().report(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE.on(member));
|
||||||
context.getTrace().report(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE.on(nameIdentifier));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,27 +207,21 @@ public class DeclarationsChecker {
|
|||||||
JetExpression initializer = property.getInitializer();
|
JetExpression initializer = property.getInitializer();
|
||||||
boolean backingFieldRequired = context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
boolean backingFieldRequired = context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
||||||
|
|
||||||
PsiElement nameIdentifier = property.getNameIdentifier();
|
if (inTrait && backingFieldRequired && hasAccessorImplementation) {
|
||||||
|
context.getTrace().report(BACKING_FIELD_IN_TRAIT.on(property));
|
||||||
if (inTrait && backingFieldRequired && hasAccessorImplementation && nameIdentifier != null) {
|
|
||||||
context.getTrace().report(BACKING_FIELD_IN_TRAIT.on(nameIdentifier));
|
|
||||||
}
|
}
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
if (nameIdentifier != null && backingFieldRequired && !inTrait && !context.getTrace().getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
|
if (backingFieldRequired && !inTrait && !context.getTrace().getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
|
||||||
if (classDescriptor == null || hasAccessorImplementation) {
|
if (classDescriptor == null || hasAccessorImplementation) {
|
||||||
context.getTrace().report(MUST_BE_INITIALIZED.on(nameIdentifier));
|
context.getTrace().report(MUST_BE_INITIALIZED.on(property));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
context.getTrace().report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(nameIdentifier));
|
context.getTrace().report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (inTrait) {
|
if (inTrait) {
|
||||||
JetType returnType = propertyDescriptor.getReturnType();
|
|
||||||
if (returnType instanceof DeferredType) {
|
|
||||||
returnType = ((DeferredType) returnType).getActualType();
|
|
||||||
}
|
|
||||||
context.getTrace().report(PROPERTY_INITIALIZER_IN_TRAIT.on(initializer));
|
context.getTrace().report(PROPERTY_INITIALIZER_IN_TRAIT.on(initializer));
|
||||||
}
|
}
|
||||||
else if (!backingFieldRequired) {
|
else if (!backingFieldRequired) {
|
||||||
@@ -242,10 +231,7 @@ public class DeclarationsChecker {
|
|||||||
|
|
||||||
protected void checkFunction(JetNamedFunction function, SimpleFunctionDescriptor functionDescriptor) {
|
protected void checkFunction(JetNamedFunction function, SimpleFunctionDescriptor functionDescriptor) {
|
||||||
DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
|
||||||
PsiElement nameIdentifier = function.getNameIdentifier();
|
boolean hasAbstractModifier = function.hasModifier(JetTokens.ABSTRACT_KEYWORD);
|
||||||
JetModifierList modifierList = function.getModifierList();
|
|
||||||
ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;
|
|
||||||
boolean hasAbstractModifier = abstractNode != null;
|
|
||||||
checkDeclaredTypeInPublicMember(function, functionDescriptor);
|
checkDeclaredTypeInPublicMember(function, functionDescriptor);
|
||||||
if (containingDescriptor instanceof ClassDescriptor) {
|
if (containingDescriptor instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
|
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
|
||||||
@@ -261,9 +247,9 @@ public class DeclarationsChecker {
|
|||||||
context.getTrace().report(ABSTRACT_MODIFIER_IN_TRAIT.on(function));
|
context.getTrace().report(ABSTRACT_MODIFIER_IN_TRAIT.on(function));
|
||||||
}
|
}
|
||||||
if (function.getBodyExpression() != null && hasAbstractModifier) {
|
if (function.getBodyExpression() != null && hasAbstractModifier) {
|
||||||
context.getTrace().report(ABSTRACT_FUNCTION_WITH_BODY.on(abstractNode.getPsi(), functionDescriptor));
|
context.getTrace().report(ABSTRACT_FUNCTION_WITH_BODY.on(function, functionDescriptor));
|
||||||
}
|
}
|
||||||
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null) {
|
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait) {
|
||||||
context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
|
context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -271,7 +257,7 @@ public class DeclarationsChecker {
|
|||||||
if (hasAbstractModifier) {
|
if (hasAbstractModifier) {
|
||||||
context.getTrace().report(NON_MEMBER_ABSTRACT_FUNCTION.on(function, functionDescriptor));
|
context.getTrace().report(NON_MEMBER_ABSTRACT_FUNCTION.on(function, functionDescriptor));
|
||||||
}
|
}
|
||||||
if (function.getBodyExpression() == null && !hasAbstractModifier && nameIdentifier != null) {
|
if (function.getBodyExpression() == null && !hasAbstractModifier) {
|
||||||
context.getTrace().report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
|
context.getTrace().report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,6 @@ public class DescriptorResolver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trace.report(FUNCTION_WITH_NO_TYPE_NO_BODY.on(function.asElement()));
|
|
||||||
returnType = ErrorUtils.createErrorType("No type, no body");
|
returnType = ErrorUtils.createErrorType("No type, no body");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -124,10 +124,6 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
if (!expressionTypes.isEmpty()) {
|
if (!expressionTypes.isEmpty()) {
|
||||||
return DataFlowUtils.checkImplicitCast(CommonSupertypes.commonSupertype(expressionTypes), expression, contextWithExpectedType, isStatement);
|
return DataFlowUtils.checkImplicitCast(CommonSupertypes.commonSupertype(expressionTypes), expression, contextWithExpectedType, isStatement);
|
||||||
}
|
}
|
||||||
else if (expression.getEntries().isEmpty()) {
|
|
||||||
// context.trace.getErrorHandler().genericError(expression.getNode(), "Entries required for when-expression");
|
|
||||||
context.trace.report(NO_WHEN_ENTRIES.on(expression));
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,7 +256,9 @@ public class JetPsiChecker implements Annotator {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Annotation markRedeclaration(@NotNull Set<PsiElement> redeclarations, @NotNull RedeclarationDiagnostic diagnostic, @NotNull AnnotationHolder holder) {
|
private Annotation markRedeclaration(@NotNull Set<PsiElement> redeclarations, @NotNull RedeclarationDiagnostic diagnostic, @NotNull AnnotationHolder holder) {
|
||||||
if (!redeclarations.add(diagnostic.getPsiElement())) return null;
|
if (!redeclarations.add(diagnostic.getPsiElement())) return null;
|
||||||
return holder.createErrorAnnotation(diagnostic.getTextRanges().get(0), getMessage(diagnostic));
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
|
if (textRanges.isEmpty()) return null;
|
||||||
|
return holder.createErrorAnnotation(textRanges.get(0), getMessage(diagnostic));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user