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

This commit is contained in:
Kirill Kalishev
2010-06-03 15:54:33 +04:00
11 changed files with 238 additions and 48 deletions
@@ -53,9 +53,9 @@ public final class PsiUtil extends PsiUtilBase {
private PsiUtil() {}
public static boolean isOnAssignmentLeftHand(PsiExpression expr) {
PsiElement parent = expr.getParent();
return parent instanceof PsiAssignmentExpression
&& expr.equals(((PsiAssignmentExpression) parent).getLExpression());
PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, PsiParenthesizedExpression.class);
return parent instanceof PsiAssignmentExpression &&
PsiTreeUtil.isAncestor(((PsiAssignmentExpression)parent).getLExpression(), expr, false);
}
public static boolean isAccessibleFromPackage(@NotNull PsiModifierListOwner element, @NotNull PsiPackage aPackage) {
@@ -66,7 +66,7 @@ public final class PsiUtil extends PsiUtilBase {
public static boolean isAccessedForWriting(PsiExpression expr) {
if (isOnAssignmentLeftHand(expr)) return true;
PsiElement parent = expr.getParent();
PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, PsiParenthesizedExpression.class);
if (parent instanceof PsiPrefixExpression) {
IElementType tokenType = ((PsiPrefixExpression) parent).getOperationTokenType();
return tokenType == JavaTokenType.PLUSPLUS || tokenType == JavaTokenType.MINUSMINUS;
@@ -81,9 +81,9 @@ public final class PsiUtil extends PsiUtilBase {
}
public static boolean isAccessedForReading(PsiExpression expr) {
PsiElement parent = expr.getParent();
PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, PsiParenthesizedExpression.class);
return !(parent instanceof PsiAssignmentExpression) ||
!expr.equals(((PsiAssignmentExpression)parent).getLExpression()) ||
!PsiTreeUtil.isAncestor(((PsiAssignmentExpression)parent).getLExpression(), expr, false) ||
((PsiAssignmentExpression)parent).getOperationSign().getTokenType() != JavaTokenType.EQ;
}
@@ -322,6 +322,19 @@ public class PsiTreeUtil {
return null;
}
@Nullable
public static PsiElement skipParentsOfType(@Nullable PsiElement element, @NotNull Class... parentClasses) {
if (element == null) return null;
NextSibling:
for (PsiElement e = element.getParent(); e != null; e = e.getParent()) {
for (Class aClass : parentClasses) {
if (instanceOf(aClass, e)) continue NextSibling;
}
return e;
}
return null;
}
@Nullable
public static <T extends PsiElement> T getParentOfType(PsiElement element, @NotNull Class<? extends T>... classes) {
if (element == null) return null;
@@ -589,6 +589,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
field.setAccessible(true);
field.set(ioFile, null);
FileUtil.resetCanonicalTempPathCache();
}
catch (NoSuchFieldException ignore) {
// field was removed in JDK 1.6.0_12
@@ -48,7 +48,8 @@ public class FileUtil {
};
// do not use channels to copy files larger than 5 Mb because of possible MapFailed error
private static final long CHANNELS_COPYING_LIMIT = 5L * 1024L * 1024L;
private static final long CHANNELS_COPYING_LIMIT = 5L * 1024L * 1024L;
private static String ourCanonicalTempPathCache = null;
//private static final byte[] BUFFER = new byte[1024 * 20];
@@ -369,7 +370,24 @@ public class FileUtil {
}
public static String getTempDirectory() {
return System.getProperty("java.io.tmpdir");
if (ourCanonicalTempPathCache == null) {
ourCanonicalTempPathCache = calcCanonicalTempPath();
}
return ourCanonicalTempPathCache;
}
public static void resetCanonicalTempPathCache() {
ourCanonicalTempPathCache = null;
}
private static String calcCanonicalTempPath() {
final String prop = System.getProperty("java.io.tmpdir");
try {
return new File(prop).getCanonicalPath();
}
catch (IOException e) {
return prop;
}
}
public static void asyncDelete(@NotNull File file) {
+2
View File
@@ -116,6 +116,8 @@
<lang.surroundDescriptor language="Groovy"
implementationClass="org.jetbrains.plugins.groovy.lang.surroundWith.descriptors.GroovyStmtsSurroundDescriptor"/>
<lang.findUsagesProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.findUsages.GroovyFindUsagesProvider"/>
<readWriteAccessDetector implementation="org.jetbrains.plugins.groovy.findUsages.GroovyReadWriteAccessDetector" order="before java"/>
<findUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GroovyFindUsagesHandlerFactory"/>
<lang.braceMatcher language="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyBraceMatcher"/>
<lang.importOptimizer language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.editor.GroovyImportOptimizer"/>
<lang.documentationProvider language="Groovy"
@@ -0,0 +1,96 @@
/*
* Copyright 2000-2010 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.findUsages;
import com.intellij.CommonBundle;
import com.intellij.find.FindBundle;
import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.JavaFindUsagesHandler;
import com.intellij.find.findUsages.JavaFindUsagesHandlerFactory;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Maxim.Medvedev
*/
public class GroovyFindUsagesHandlerFactory extends JavaFindUsagesHandlerFactory {
public GroovyFindUsagesHandlerFactory(Project project) {
super(project);
}
@Override
public boolean canFindUsages(@NotNull PsiElement element) {
return element instanceof GrField;
}
@Override
public FindUsagesHandler createFindUsagesHandler(@NotNull PsiElement element, boolean forHighlightUsages) {
return new JavaFindUsagesHandler(element, getFindClassOptions(), getFindMethodOptions(), getFindPackageOptions(), getFindThrowOptions(),
getFindVariableOptions()) {
@NotNull
@Override
public PsiElement[] getSecondaryElements() {
PsiElement element = getPsiElement();
if (ApplicationManager.getApplication().isUnitTestMode()) return PsiElement.EMPTY_ARRAY;
final PsiField field = (PsiField)element;
PsiClass containingClass = field.getContainingClass();
if (containingClass != null) {
PsiMethod getter = GroovyPropertyUtils.findGetterForField(field);
PsiMethod setter = GroovyPropertyUtils.findSetterForField(field);
if (getter != null || setter != null) {
final boolean doSearch;
if ((getter == null || !getter.isPhysical()) && (setter == null || !setter.isPhysical())) {
doSearch = true;
}
else {
doSearch = Messages.showDialog(FindBundle.message("find.field.accessors.prompt", field.getName()),
FindBundle.message("find.field.accessors.title"),
new String[]{CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText()}, 0,
Messages.getQuestionIcon()) == DialogWrapper.OK_EXIT_CODE;
}
if (doSearch) {
final List<PsiElement> elements = new ArrayList<PsiElement>();
if (getter != null) {
elements.addAll(Arrays.asList(SuperMethodWarningUtil.checkSuperMethods(getter, ACTION_STRING)));
}
if (setter != null) {
elements.addAll(Arrays.asList(SuperMethodWarningUtil.checkSuperMethods(setter, ACTION_STRING)));
}
return elements.toArray(new PsiElement[elements.size()]);
} else {
return PsiElement.EMPTY_ARRAY;
}
}
}
return super.getSecondaryElements();
}
};
}
}
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2010 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.findUsages;
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
* @author Maxim.Medvedev
*/
public class GroovyReadWriteAccessDetector extends ReadWriteAccessDetector{
@Override
public boolean isReadWriteAccessible(PsiElement element) {
return element instanceof GrVariable;
}
@Override
public boolean isDeclarationWriteAccess(PsiElement element) {
if (element instanceof GrVariable && ((GrVariable)element).getInitializerGroovy() != null) {
return true;
}
return false;
}
@Override
public Access getReferenceAccess(PsiElement referencedElement, PsiReference reference) {
return getExpressionAccess(reference.getElement());
}
@Override
public Access getExpressionAccess(PsiElement expression) {
if (!(expression instanceof GrExpression)) return Access.Read;
GrExpression expr = (GrExpression) expression;
boolean readAccess = PsiUtil.isAccessedForReading(expr);
boolean writeAccess = PsiUtil.isAccessedForWriting(expr);
if (!writeAccess && expr instanceof GrReferenceExpression) {
//when searching usages of fields, should show all found setters as a "only write usage"
PsiElement actualReferee = ((GrReferenceExpression) expr).resolve();
if (actualReferee instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertySetter((PsiMethod)actualReferee)) {
writeAccess = true;
readAccess = false;
}
}
if (writeAccess && readAccess) return Access.ReadWrite;
return writeAccess ? Access.Write : Access.Read;
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
@@ -55,7 +54,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
@@ -684,30 +682,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
}
public boolean isReferenceTo(PsiElement element) {
if (element instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod) element)) {
final PsiElement target = resolve();
if (element instanceof GrAccessorMethod && getManager().areElementsEquivalent(((GrAccessorMethod)element).getProperty(), target)) {
return false;
}
return getManager().areElementsEquivalent(element, target);
}
if (element instanceof GrField && ((GrField) element).isProperty()) {
final PsiElement target = resolve();
if (getManager().areElementsEquivalent(element, target)) {
return true;
}
for (final GrAccessorMethod getter : ((GrField)element).getGetters()) {
if (getManager().areElementsEquivalent(getter, target)) {
return true;
}
}
return getManager().areElementsEquivalent(((GrField)element).getSetter(), target);
}
if (element instanceof PsiNamedElement && Comparing.equal(((PsiNamedElement) element).getName(), getReferenceName())) {
if (element instanceof PsiNamedElement) {
return getManager().areElementsEquivalent(element, resolve());
}
return false;
@@ -27,6 +27,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
@@ -109,11 +110,11 @@ public class PsiUtil {
public static boolean isLValue(GroovyPsiElement element) {
if (element instanceof GrExpression) {
PsiElement parent = element.getParent();
PsiElement parent = PsiTreeUtil.skipParentsOfType(element, GrParenthesizedExpression.class);
if (parent instanceof GrListOrMap && !((GrListOrMap)parent).isMap()) {
return isLValue((GroovyPsiElement)parent);
}
return parent instanceof GrAssignmentExpression && element.equals(((GrAssignmentExpression)parent).getLValue());
return parent instanceof GrAssignmentExpression && PsiTreeUtil.isAncestor(((GrAssignmentExpression)parent).getLValue(), element, false);
}
return false;
}
@@ -777,4 +778,20 @@ public class PsiUtil {
return constructorResults.toArray(new GroovyResolveResult[constructorResults.size()]);
}
public static boolean isAccessedForReading(GrExpression expr) {
return !isLValue(expr);
}
public static boolean isAccessedForWriting(GrExpression expr) {
if (isLValue(expr)) return true;
PsiElement parent = PsiTreeUtil.skipParentsOfType(expr, GrParenthesizedExpression.class);
if (parent instanceof GrUnaryExpression) {
IElementType tokenType = ((GrUnaryExpression)parent).getOperationTokenType();
return tokenType == GroovyTokenTypes.mINC || tokenType == GroovyTokenTypes.mDEC;
}
return false;
}
}
+1 -1
View File
@@ -1038,7 +1038,7 @@
<vetoRenameCondition implementation="com.intellij.refactoring.rename.JavaVetoRenameCondition"/>
<readWriteAccessDetector implementation="com.intellij.codeInsight.highlighting.JavaReadWriteAccessDetector"/>
<readWriteAccessDetector implementation="com.intellij.codeInsight.highlighting.JavaReadWriteAccessDetector" id="java"/>
<elementDescriptionProvider implementation="com.intellij.codeInsight.highlighting.JavaHighlightUsagesDescriptionProvider"/>
<elementDescriptionProvider implementation="com.intellij.usageView.JavaUsageViewDescriptionProvider"/>
@@ -25,6 +25,7 @@ import com.intellij.psi.TokenType;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.formatter.common.AbstractBlock;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlElementType;
@@ -128,23 +129,23 @@ public class XmlBlock extends AbstractXmlBlock {
private List<Block> splitComment() {
if (myNode.getElementType() != XmlElementType.XML_COMMENT) return null;
//
// Do not build subblocks for comment-only node.
if (myNode.getFirstChildNode() != null &&
myNode.getFirstChildNode().getElementType() == XmlElementType.XML_COMMENT_START &&
myNode.getLastChildNode().getElementType() == XmlElementType.XML_COMMENT_END) {
return EMPTY;
}
if (myNode.getElementType() != XmlElementType.XML_COMMENT) return EMPTY;
final ArrayList<Block> result = new ArrayList<Block>(3);
final ArrayList<Block> commentBlocks = new ArrayList<Block>(3);
ASTNode child = myNode.getFirstChildNode();
boolean hasOuterLangElements = false;
while (child != null) {
IElementType childType = child.getElementType();
if (child instanceof OuterLanguageElement) {
hasOuterLangElements = true;
}
result.add(new XmlBlock(child, null, null, myXmlFormattingPolicy, getChildIndent(), null));
child = child.getTreeNext();
}
return result;
if (hasOuterLangElements) {
return result;
}
else {
return EMPTY;
}
}
protected @Nullable Wrap getDefaultWrap(ASTNode node) {