Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Dmitry Cheryasov
2011-01-31 12:40:51 +02:00
24 changed files with 349 additions and 86 deletions
@@ -474,7 +474,16 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.PARAMETER_LIST) {
final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.METHOD_PARAMETERS_WRAP), false);
final Wrap wrap;
Wrap reservedWrap = getReservedWrap(JavaElementType.MODIFIER_LIST);
// There is a possible case that particular annotated method definition is too long. We may wrap either after annotation
// or after opening lbrace then. Our strategy is to wrap after annotation whenever possible.
if (reservedWrap == null) {
wrap = Wrap.createWrap(getWrapType(mySettings.METHOD_PARAMETERS_WRAP), false);
}
else {
wrap = Wrap.createChildWrap(reservedWrap, getWrapType(mySettings.METHOD_PARAMETERS_WRAP), false);
}
child = processParenthesisBlock(result, child,
WrappingStrategy.createDoNotWrapCommaStrategy(wrap),
mySettings.ALIGN_MULTILINE_PARAMETERS);
@@ -533,6 +542,19 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
myAnnotationWrap = null;
}
}
else if (childType == JavaElementType.PARAMETER_LIST && nodeType == JavaElementType.METHOD) {
// We prefer wrapping after method annotation to wrapping method parameter list, hence, deliver target wrap object
// to child block if necessary.
if (!result.isEmpty()) {
Block firstChildBlock = result.get(0);
if (firstChildBlock instanceof AbstractJavaBlock) {
AbstractJavaBlock childJavaBlock = (AbstractJavaBlock)firstChildBlock;
if (firstChildIsAnnotation(childJavaBlock.getNode())) {
javaBlock.setReservedWrap(childJavaBlock.getReservedWrap(JavaElementType.MODIFIER_LIST), JavaElementType.MODIFIER_LIST);
}
}
}
}
}
result.add(block);
@@ -747,6 +769,14 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
private static boolean firstChildIsAnnotation(final ASTNode child) {
ASTNode current = child.getFirstChildNode();
while (current != null && current.getElementType() == TokenType.WHITE_SPACE) {
current = current.getTreeNext();
}
return current != null && current.getElementType() == JavaElementType.ANNOTATION;
}
private static boolean lastChildIsAnnotation(final ASTNode child) {
ASTNode current = child.getLastChildNode();
while (current != null && current.getElementType() == TokenType.WHITE_SPACE) {
@@ -17,6 +17,7 @@ package com.intellij.psi.formatter.java;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
/**
* Is intended to hold specific java formatting tests for 'wrapping' settings.
@@ -224,4 +225,18 @@ public class JavaFormatterWrapTest extends AbstractJavaFormatterTest {
"}"
);
}
public void testWrapMethodAnnotationBeforeParams() throws Exception {
// Inspired by IDEA-59536
getSettings().RIGHT_MARGIN = 90;
getSettings().METHOD_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED;
getSettings().METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED;
doClassTest(
"@SuppressWarnings({\"SomeInspectionIWantToIgnore\"}) public void doSomething(int x, int y) {}",
"@SuppressWarnings({\"SomeInspectionIWantToIgnore\"})\n" +
"public void doSomething(int x, int y) {" +
"\n}"
);
}
}
@@ -99,10 +99,10 @@ public class GenericLineWrapPositionStrategy implements LineWrapPositionStrategy
// Try to find target offset that is beyond preferred offset.
// Note that we don't consider symbol weights here and just break on the first appropriate position.
if (!allowToBeyondMaxPreferredOffset || maxPreferredOffset >= text.length() - 1) {
if (!allowToBeyondMaxPreferredOffset) {
return maxPreferredOffset;
}
for (int i = maxPreferredOffsetToUse + 1; i < endOffset; i++) {
for (int i = Math.min(maxPreferredOffsetToUse + 1, text.length() - 1); i < endOffset; i++) {
char c = text.charAt(i);
if (c == '\n') {
return i + 1;
@@ -3354,7 +3354,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void requestFocus() {
IdeFocusManager.getInstance(myProject).requestFocus(myEditorComponent, true);
final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject);
if (focusManager.getFocusOwner() != myEditorComponent) { //IDEA-64501
focusManager.requestFocus(myEditorComponent, true);
}
}
private void validateMousePointer(MouseEvent e) {
@@ -709,13 +709,27 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
public void visitClosure(GrClosableBlock closure) {
super.visitClosure(closure);
if (!closure.hasParametersSection()) {
final PsiElement parent = closure.getParent();
if (parent instanceof GrCodeBlock || parent instanceof GroovyFile) {
if (!checkClosureForAmbiguous(closure)) {
myHolder.createErrorAnnotation(closure, GroovyBundle.message("ambiguous.code.block"));
}
}
}
private static boolean checkClosureForAmbiguous(GrClosableBlock closure) {
PsiElement place;
PsiElement parent = closure;
do {
place = parent;
parent = place.getParent();
}
while (!(parent instanceof GrContinueStatement || parent instanceof GrCodeBlock || parent instanceof GroovyFile));
while (place != null) {
if (place == closure) return false;
place = place.getFirstChild();
}
return true;
}
@Override
public void visitSuperExpression(GrSuperReferenceExpression superExpression) {
checkThisOrSuperReferenceExpression(superExpression, myHolder);
@@ -68,4 +68,5 @@ type.doesnt.contain.method=Type ''{0}'' cannot be iterated in range because it d
incorrect.range.argument=Incorrect range arguments
type.doesnt.implemnt.comparable=Type ''{0}'' doesnt implement Comparable
add.method=Add method ''{0}()'' to class ''{1}''
implement.class=Implement {0}
implement.class=Implement {0}
fix.class=Fix class {0}
@@ -37,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.arithmetic.GrRangeExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
@@ -78,34 +79,60 @@ public class GroovyRangeTypeCheckInspection extends BaseInspection {
}
@Override
protected GroovyFix[] buildFixes(PsiElement location) {
protected GroovyFix buildFix(PsiElement location) {
final GrRangeExpression range = (GrRangeExpression)location;
final PsiType type = range.getType();
List<GroovyFix> fixes = new ArrayList<GroovyFix>(3);
final List<GroovyFix> fixes = new ArrayList<GroovyFix>(3);
if (type instanceof GrRangeType) {
PsiType iterationType = ((GrRangeType)type).getIterationType();
if (!(iterationType instanceof PsiClassType)) return GroovyFix.EMPTY_ARRAY;
if (!(iterationType instanceof PsiClassType)) return null;
final PsiClass psiClass = ((PsiClassType)iterationType).resolve();
if (!(psiClass instanceof GrTypeDefinition)) return GroovyFix.EMPTY_ARRAY;
if (!(psiClass instanceof GrTypeDefinition)) return null;
final GroovyResolveResult[] nexts = ResolveUtil.getMethodCandidates(iterationType, "next", range, PsiType.EMPTY_ARRAY);
final GroovyResolveResult[] previouses = ResolveUtil.getMethodCandidates(iterationType, "previous", range, PsiType.EMPTY_ARRAY);
final GroovyResolveResult[] nexts = ResolveUtil.getMethodCandidates(iterationType, "next", range);
final GroovyResolveResult[] previouses = ResolveUtil.getMethodCandidates(iterationType, "previous", range);
final GroovyResolveResult[] compareTos = ResolveUtil.getMethodCandidates(iterationType, "compareTo", range, iterationType);
if (nexts.length == 0) {
if (countImplementations(psiClass, nexts)==0) {
fixes.add(new AddMethodFix("next", (GrTypeDefinition)psiClass));
}
if (previouses.length == 0) {
if (countImplementations(psiClass, previouses) == 0) {
fixes.add(new AddMethodFix("previous", (GrTypeDefinition)psiClass));
}
if (!InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_COMPARABLE)) {
if (!InheritanceUtil.isInheritor(iterationType, CommonClassNames.JAVA_LANG_COMPARABLE) ||
countImplementations(psiClass, compareTos) == 0) {
fixes.add(new AddClassToExtends((GrTypeDefinition)psiClass, CommonClassNames.JAVA_LANG_COMPARABLE));
}
return new GroovyFix() {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
for (GroovyFix fix : fixes) {
fix.applyFix(project, descriptor);
}
}
@NotNull
@Override
public String getName() {
return GroovyInspectionBundle.message("fix.class", psiClass.getName());
}
};
}
return fixes.toArray(new GroovyFix[fixes.size()]);
return null;
}
private static int countImplementations(PsiClass clazz, GroovyResolveResult[] methods) {
if (clazz.isInterface()) return methods.length;
int result = 0;
for (GroovyResolveResult method : methods) {
final PsiElement el = method.getElement();
if (el instanceof PsiMethod && !((PsiMethod)el).hasModifierProperty(GrModifier.ABSTRACT)) result++;
}
return result;
}
@Override
protected String buildErrorString(Object... args) {
@@ -225,32 +252,6 @@ public class GroovyRangeTypeCheckInspection extends BaseInspection {
GrReferenceList list;
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
if (myPsiClass.isInterface()) {
list = myPsiClass.getExtendsClause();
if (list == null) {
list = factory.createExtendsClause();
PsiElement anchor = myPsiClass.getImplementsClause();
if (anchor==null) {
anchor = myPsiClass.getBody();
}
if (anchor == null) return;
list = (GrReferenceList)myPsiClass.addBefore(list, anchor);
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", anchor.getNode());
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", list.getNode());
}
}
else {
list = myPsiClass.getImplementsClause();
if (list == null) {
list = factory.createImplementsClause();
PsiElement anchor = myPsiClass.getBody();
if (anchor == null) return;
list = (GrReferenceList)myPsiClass.addBefore(list, anchor);
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", list.getNode());
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", anchor.getNode());
}
}
final PsiClass comparable =
JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_COMPARABLE, myPsiClass.getResolveScope());
@@ -270,11 +271,40 @@ public class GroovyRangeTypeCheckInspection extends BaseInspection {
}
}
final PsiElement ref =
list
.add(factory.createReferenceElementFromText(myInterfaceName + (addTypeParam ? "<" + generateTypeText(myPsiClass) + ">" : "")));
PsiUtil.shortenReference((GrReferenceElement)ref);
if (!InheritanceUtil.isInheritor(myPsiClass, CommonClassNames.JAVA_LANG_COMPARABLE)) {
if (myPsiClass.isInterface()) {
list = myPsiClass.getExtendsClause();
if (list == null) {
list = factory.createExtendsClause();
PsiElement anchor = myPsiClass.getImplementsClause();
if (anchor == null) {
anchor = myPsiClass.getBody();
}
if (anchor == null) return;
list = (GrReferenceList)myPsiClass.addBefore(list, anchor);
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", anchor.getNode());
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", list.getNode());
}
}
else {
list = myPsiClass.getImplementsClause();
if (list == null) {
list = factory.createImplementsClause();
PsiElement anchor = myPsiClass.getBody();
if (anchor == null) return;
list = (GrReferenceList)myPsiClass.addBefore(list, anchor);
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", list.getNode());
myPsiClass.getNode().addLeaf(GroovyTokenTypes.mWS, " ", anchor.getNode());
}
}
final PsiElement ref =
list
.add(factory.createReferenceElementFromText(myInterfaceName + (addTypeParam ? "<" + generateTypeText(myPsiClass) + ">" : "")));
PsiUtil.shortenReference((GrReferenceElement)ref);
}
if (comparable != null && !myPsiClass.isInterface()) {
GroovyOverrideImplementUtil
.generateImplementation(null, myPsiClass.getContainingFile(), myPsiClass, comparable.getMethods()[0], substitutor);
@@ -283,8 +313,7 @@ public class GroovyRangeTypeCheckInspection extends BaseInspection {
@NotNull
@Override
public String getName
() {
public String getName() {
return GroovyInspectionBundle.message("implement.class", myInterfaceName);
}
}
@@ -144,10 +144,11 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
for (String accessorName : accessorNames) {
AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(accessorName, this, !isLValue);
resolveImpl(accessorResolver);
final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate
if (candidates.length == 1 && candidates[0].isStaticsOK()) {
if (isPropertyName || candidates[0].getElement() instanceof GrAccessorMethod) {
return candidates;
final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one correct candidate
if (candidates.length > 0 && candidates[candidates.length - 1].isStaticsOK()) {
if (isPropertyName || candidates[candidates.length - 1].getElement() instanceof GrAccessorMethod) {
if (candidates.length == 1) return candidates;
return new GroovyResolveResult[]{candidates[candidates.length - 1]};
}
}
else {
@@ -627,43 +628,45 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
}
}
private void resolveImpl(ResolverProcessor processor) {
private boolean resolveImpl(ResolverProcessor processor) {
GrExpression qualifier = getQualifierExpression();
if (qualifier == null) {
ResolveUtil.treeWalkUp(this, processor, true);
if (!processor.hasCandidates()) {
qualifier = PsiImplUtil.getRuntimeQualifier(this);
if (qualifier != null) {
processQualifier(processor, qualifier);
if (!processQualifier(processor, qualifier)) return false;
}
}
} else {
if (getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) {
processQualifier(processor, qualifier);
if (!processQualifier(processor, qualifier)) return false;
} else {
processQualifierForSpreadDot(processor, qualifier);
if (!processQualifierForSpreadDot(processor, qualifier)) return false;
}
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
qualifier instanceof GrThisReferenceExpression) {
processIfJavaLangClass(processor, qualifier.getType(), qualifier);
return processIfJavaLangClass(processor, qualifier.getType(), qualifier);
}
}
return true;
}
private void processIfJavaLangClass(ResolverProcessor processor, PsiType type, GroovyPsiElement resolveContext) {
private boolean processIfJavaLangClass(ResolverProcessor processor, PsiType type, GroovyPsiElement resolveContext) {
if (type instanceof PsiClassType) {
final PsiClass psiClass = ((PsiClassType)type).resolve();
if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
final PsiType[] params = ((PsiClassType)type).getParameters();
if (params.length == 1) {
processClassQualifierType(processor, params[0], resolveContext);
if (!processClassQualifierType(processor, params[0], resolveContext)) return false;
}
}
}
return true;
}
private void processQualifierForSpreadDot(ResolverProcessor processor, GrExpression qualifier) {
private boolean processQualifierForSpreadDot(ResolverProcessor processor, GrExpression qualifier) {
PsiType qualifierType = qualifier.getType();
if (qualifierType instanceof PsiClassType) {
PsiClassType.ClassResolveResult result = ((PsiClassType) qualifierType).resolveGenerics();
@@ -676,37 +679,38 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
if (substitutor != null) {
PsiType componentType = substitutor.substitute(collection.getTypeParameters()[0]);
if (componentType != null) {
processClassQualifierType(processor, componentType, qualifier);
return processClassQualifierType(processor, componentType, qualifier);
}
}
}
}
} else if (qualifierType instanceof PsiArrayType) {
processClassQualifierType(processor, ((PsiArrayType) qualifierType).getComponentType(), qualifier);
return processClassQualifierType(processor, ((PsiArrayType) qualifierType).getComponentType(), qualifier);
}
return true;
}
private void processQualifier(ResolverProcessor processor, GrExpression qualifier) {
private boolean processQualifier(ResolverProcessor processor, GrExpression qualifier) {
PsiType qualifierType = qualifier.getType();
if (qualifierType == null) {
if (qualifier instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
if (resolved instanceof PsiPackage) {
if (!resolved.processDeclarations(processor, ResolveState.initial().put(ResolverProcessor.RESOLVE_CONTEXT, qualifier), null, this)) //noinspection UnnecessaryReturnStatement
return;
return resolved.processDeclarations(processor, ResolveState.initial().put(ResolverProcessor.RESOLVE_CONTEXT, qualifier), null,
this);
}
else {
qualifierType = TypesUtil.getJavaLangObject(this);
processClassQualifierType(processor, qualifierType, qualifier);
return processClassQualifierType(processor, qualifierType, qualifier);
}
}
} else {
if (qualifierType instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
processClassQualifierType(processor, conjunct, qualifier);
if (!processClassQualifierType(processor, conjunct, qualifier)) return false;
}
} else {
processClassQualifierType(processor, qualifierType, qualifier);
if (!processClassQualifierType(processor, qualifierType, qualifier)) return false;
if (qualifier instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
if (resolved instanceof PsiClass) { //omitted .class
@@ -720,17 +724,18 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
substitutor = substitutor.put(typeParameters[0], qualifierType);
state = state.put(PsiSubstitutor.KEY, substitutor);
}
if (!javaLangClass.processDeclarations(processor, state, null, this)) return;
if (!javaLangClass.processDeclarations(processor, state, null, this)) return false;
PsiType javaLangClassType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createType(javaLangClass, substitutor);
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, this, state);
if (!ResolveUtil.processNonCodeMethods(javaLangClassType, processor, this, state)) return false;
}
}
}
}
}
return true;
}
private void processClassQualifierType(ResolverProcessor processor, PsiType qualifierType, GroovyPsiElement resolveContext) {
private boolean processClassQualifierType(ResolverProcessor processor, PsiType qualifierType, GroovyPsiElement resolveContext) {
final ResolveState state;
if (qualifierType instanceof PsiClassType) {
PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType)qualifierType).resolveGenerics();
@@ -738,27 +743,25 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
state = ResolveState.initial().put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor())
.put(ResolverProcessor.RESOLVE_CONTEXT, resolveContext);
if (qualifierClass != null) {
if (!qualifierClass.processDeclarations(processor, state, null, this)) {
return;
}
if (!qualifierClass.processDeclarations(processor, state, null, this)) return false;
}
}
else if (qualifierType instanceof PsiArrayType) {
final GrTypeDefinition arrayClass = GroovyPsiManager.getInstance(getProject()).getArrayClass();
state = ResolveState.initial();
if (!arrayClass.processDeclarations(processor, state, null, this)) return;
if (!arrayClass.processDeclarations(processor, state, null, this)) return false;
}
else if (qualifierType instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
processClassQualifierType(processor, conjunct, resolveContext);
if (!processClassQualifierType(processor, conjunct, resolveContext)) return false;
}
return;
return true;
} else {
state = ResolveState.initial();
}
if (!ResolveUtil.processCategoryMembers(this, processor)) return;
ResolveUtil.processNonCodeMethods(qualifierType, processor, this, state);
if (!ResolveUtil.processCategoryMembers(this, processor)) return false;
return ResolveUtil.processNonCodeMethods(qualifierType, processor, this, state);
}
public MethodResolverProcessor runMethodResolverProcessor(String referenceName, PsiType[] argTypes, final boolean allVariants) {
@@ -585,7 +585,7 @@ public class ResolveUtil {
public static GroovyResolveResult[] getMethodCandidates(@NotNull PsiType thisType,
@Nullable String methodName,
@NotNull GroovyPsiElement place,
@Nullable PsiType[] argumentTypes) {
@Nullable PsiType... argumentTypes) {
if (methodName != null) {
MethodResolverProcessor processor =
new MethodResolverProcessor(methodName, place, false, thisType, argumentTypes, PsiType.EMPTY_ARRAY);
@@ -63,7 +63,7 @@ public class AccessorResolverProcessor extends ResolverProcessor {
final GroovyPsiElement resolveContext = state.get(RESOLVE_CONTEXT);
boolean isStaticsOK = isStaticsOK(method, resolveContext);
addCandidate(new GroovyResolveResultImpl(method, resolveContext, substitutor, isAccessible, isStaticsOK, myIsPropertyInvoked));
return !isAccessible;
return !isAccessible || !isStaticsOK;
}
private static boolean usedInCategory(GroovyPsiElement resolveContext) {
@@ -90,7 +90,7 @@ public class ResolverProcessor implements PsiScopeProcessor, NameHint, ClassHint
final GroovyPsiElement resolveContext = state.get(RESOLVE_CONTEXT);
boolean isStaticsOK = isStaticsOK(namedElement, resolveContext);
addCandidate(new GroovyResolveResultImpl(namedElement, resolveContext, substitutor, isAccessible, isStaticsOK));
return !isAccessible;
return !isAccessible || !isStaticsOK;
}
return true;
@@ -0,0 +1,68 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.codeInspection.bugs
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.PostprocessReformattingAspect
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.arithmetic.GrRangeExpression
import org.jetbrains.plugins.groovy.util.TestUtils
/**
* @author Maxim.Medvedev
*/
class GroovyRangeTypeCheckTest extends LightCodeInsightFixtureTestCase {
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + 'groovy/inspections/rangeTypeCheck'
}
public void doTest() {
myFixture.configureByFile getTestName(false) + '.groovy'
final int offset = myFixture.getEditor().getCaretModel().getOffset()
final PsiElement atCaret = myFixture.getFile().findElementAt(offset)
final GrRangeExpression range = PsiTreeUtil.getParentOfType(atCaret, GrRangeExpression)
final GroovyRangeTypeCheckInspection inspection = new GroovyRangeTypeCheckInspection()
GroovyFix fix = inspection.buildFix(range)
final ProblemDescriptor descriptor = InspectionManager.getInstance(project).createProblemDescriptor(range, "bla-bla", fix, ProblemHighlightType.WEAK_WARNING);
ApplicationManager.application.runWriteAction(
new Runnable() {
@Override
void run() {
fix.applyFix myFixture.project, descriptor
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
}
})
myFixture.checkResultByFile getTestName(false) + '_after.groovy'
}
void testNotComparable() {doTest()}
void testNext() {doTest()}
void testAll() {doTest()}
}
@@ -21,6 +21,7 @@ import org.jetbrains.plugins.groovy.codeInspection.GroovyImportsTracker;
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection;
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyUncheckedAssignmentOfMemberOfRawTypeInspection;
import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyAccessibilityInspection;
import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyRangeTypeCheckInspection;
import org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyResultOfObjectAllocationIgnoredInspection;
import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection;
import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection;
@@ -253,6 +254,7 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
public void testPutIncorrectValueToMap() throws Exception {doTest(new GroovyAssignabilityCheckInspection());}
public void testAmbiguousCodeBlock() throws Exception {doTest();}
public void testAmbiguousCodeBlockInMethodCall() throws Exception {doTest();}
public void testNotAmbiguousClosableBlock() throws Exception {doTest();}
public void testDuplicateParameterInClosableBlock() throws Exception {doTest();}
@@ -311,4 +313,12 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
}
public void testMapParamWithNoArgs() {doTest(new GroovyAssignabilityCheckInspection());}
public void testRangeType() {
doTest(new GroovyRangeTypeCheckInspection());
}
public void testResolveMetaClass() {
doTest(new GroovyAccessibilityInspection());
}
}
@@ -0,0 +1,5 @@
class Foo {
}
print new Foo().<caret>.new Foo()
@@ -0,0 +1,16 @@
class Foo implements Comparable<Foo> {
def Foo next() {
return null //To change body of implemented methods use File | Settings | File Templates.
}
def Foo previous() {
return null //To change body of implemented methods use File | Settings | File Templates.
}
int compareTo(Foo o) {
return 0 //To change body of implemented methods use File | Settings | File Templates.
}
}
print new Foo()..new Foo()
@@ -0,0 +1,13 @@
class Foo implements Comparable<Foo> {
@Override
int compareTo(Foo o) {
return 0
}
def previous() {
return this
}
}
print new Foo().<caret>.new Foo()
@@ -0,0 +1,16 @@
class Foo implements Comparable<Foo> {
@Override
int compareTo(Foo o) {
return 0
}
def previous() {
return this
}
def Foo next() {
return null //To change body of implemented methods use File | Settings | File Templates.
}
}
print new Foo()..new Foo()
@@ -0,0 +1,10 @@
class Foo {
def next() {return this}
def previous() {return this}
}
class X {
def foo() {
final ObjectRange range = new Foo().<caret>.new Foo()
}
}
@@ -0,0 +1,14 @@
class Foo implements Comparable<Foo> {
def next() {return this}
def previous() {return this}
int compareTo(Foo o) {
return 0 //To change body of implemented methods use File | Settings | File Templates.
}
}
class X {
def foo() {
final ObjectRange range = new Foo()..new Foo()
}
}
@@ -0,0 +1 @@
<error descr="Ambiguous code block">{print "foo"}</error>.call()
@@ -1,7 +1,7 @@
class A {
def r() {
def a = 0;
{
{->
a.intValue()
}.call()
}
+4
View File
@@ -0,0 +1,4 @@
class Foo {
}
print <warning descr="Type 'Foo' doesnt implement Comparable"><warning descr="Type 'Foo' cannot be iterated in range because it does not have method 'previous()'"><warning descr="Type 'Foo' cannot be iterated in range because it does not have method 'next()'">new Foo()..new Foo()</warning></warning></warning>
@@ -0,0 +1,6 @@
class MyClass {
private field
}
print MyClass.metaClass.getMethods()
print MyClass.field
@@ -30,6 +30,7 @@ import com.thaiopensource.util.PropertyMapBuilder;
import com.thaiopensource.validate.Schema;
import com.thaiopensource.validate.ValidateProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
@@ -41,7 +42,10 @@ import org.xml.sax.SAXParseException;
* Date: 30.07.2007
*/
public class XmlInstanceValidator {
private static final Logger LOG = Logger.getInstance("#org.intellij.plugins.relaxNG.validation.MessageViewHelper");
private static final Logger LOG = Logger.getInstance("org.intellij.plugins.relaxNG.validation.XmlInstanceValidator");
private XmlInstanceValidator() {
}
public static void doValidation(@NotNull final XmlDocument doc, final Validator.ValidationHost host, final XmlFile descriptorFile) {
try {
@@ -63,7 +67,7 @@ public class XmlInstanceValidator {
doc.accept(new Psi2SaxAdapter(handler));
} catch (ProcessCanceledException e) {
LOG.error(e);
throw e;
} catch (RuntimeException e) {
LOG.error(e);
} catch (Exception e) {
@@ -106,6 +110,7 @@ public class XmlInstanceValidator {
});
}
@Nullable
public static ErrorHandler create(XmlDocument doc, Validator.ValidationHost host) {
final XmlTag rootTag = doc.getRootTag();
if (rootTag == null) {