Merge branch 'master' into upsource-master

This commit is contained in:
Evgeny Pasynkov
2012-07-25 12:15:47 +02:00
1512 changed files with 76449 additions and 33681 deletions
@@ -924,7 +924,7 @@ public class ExpectedTypesProvider {
}
}
final PsiExpression[] args = argumentList.getExpressions();
final PsiExpression[] args = argumentList.getExpressions().clone();
final int index = ArrayUtil.indexOf(args, argument);
LOG.assertTrue(index >= 0);
@@ -932,6 +932,9 @@ public class ExpectedTypesProvider {
if (index <= args.length - 1) {
leftArgs = new PsiExpression[index];
System.arraycopy(args, 0, leftArgs, 0, index);
if (forCompletion) {
args[index] = null;
}
}
else {
leftArgs = null;
@@ -945,7 +948,7 @@ public class ExpectedTypesProvider {
PsiSubstitutor substitutor;
if (candidateInfo instanceof MethodCandidateInfo) {
final MethodCandidateInfo info = (MethodCandidateInfo)candidateInfo;
substitutor = info.inferTypeArguments(policy);
substitutor = info.inferTypeArguments(policy, args);
if (!info.isStaticsScopeCorrect() && method != null && !method.hasModifierProperty(PsiModifier.STATIC)) continue;
}
else {
@@ -87,7 +87,7 @@ public class ExternalAnnotationsManagerImpl extends ExternalAnnotationsManager {
@NotNull private final ConcurrentMap<String, List<XmlFile>> myExternalAnnotations = new ConcurrentWeakValueHashMap<String, List<XmlFile>>();
@NotNull private volatile ThreeState myHasAnyAnnotationsRoots = ThreeState.UNSURE;
@NotNull private static final List<XmlFile> NULL = new ArrayList<XmlFile>();
@NotNull private static final List<XmlFile> NULL = new ArrayList<XmlFile>(0);
private final PsiManager myPsiManager;
public ExternalAnnotationsManagerImpl(@NotNull final Project project, final PsiManager psiManager) {
@@ -154,7 +154,7 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
final PsiModifierListOwner parent = PsiTreeUtil.getParentOfType(elementAt, PsiModifierListOwner.class, false, PsiCodeBlock.class);
if (parent != null) {
for (PsiMethod m : ((PsiClass)item.getObject()).getMethods()) {
if (!(m instanceof PsiAnnotationMethod)) continue;
if (!PsiUtil.isAnnotationMethod(m)) continue;
final PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod)m).getDefaultValue();
if (defaultValue == null) return true;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -62,7 +62,7 @@ public class JavaCompletionSorting {
ContainerUtil.addIfNotNull(afterNegativeStats, preferStatics(position, expectedTypes));
}
if (!JavaCompletionData.START_FOR.accepts(position)) {
afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type, position));
afterNegativeStats.add(new PreferByKindWeigher(type, position));
}
ContainerUtil.addIfNotNull(afterNegativeStats, recursion(parameters, expectedTypes));
if (!smart && !afterNew) {
@@ -23,7 +23,7 @@ import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix;
import com.intellij.codeInsight.guess.GuessManager;
import com.intellij.codeInsight.lookup.*;
import com.intellij.ide.highlighter.XmlLikeFileType;
import com.intellij.lang.StdLanguages;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -418,7 +418,7 @@ public class JavaCompletionUtil {
public static Set<LookupElement> processJavaReference(PsiElement element, PsiJavaReference javaReference, ElementFilter elementFilter,
final boolean checkAccess, boolean filterStaticAfterInstance, final PrefixMatcher matcher, CompletionParameters parameters) {
final THashSet<LookupElement> set = new THashSet<LookupElement>();
final Set<LookupElement> set = new LinkedHashSet<LookupElement>();
final Condition<String> nameCondition = new Condition<String>() {
public boolean value(String s) {
return matcher.prefixMatches(s);
@@ -736,7 +736,9 @@ public class JavaCompletionUtil {
PsiElement element = file.findElementAt(startOffset);
if (element instanceof PsiIdentifier) {
PsiElement parent = element.getParent();
if (parent instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement)parent).isQualified() && !(parent.getParent() instanceof PsiPackageStatement)) {
if (parent instanceof PsiJavaCodeReferenceElement &&
!((PsiJavaCodeReferenceElement)parent).isQualified() &&
!(parent.getParent() instanceof PsiPackageStatement)) {
PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)parent;
if (psiClass.isValid() && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference(ref))) {
@@ -750,8 +752,8 @@ public class JavaCompletionUtil {
documentManager.commitDocument(document);
newElement = CodeInsightUtilBase.findElementInRange(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
PsiJavaCodeReferenceElement.class,
JavaLanguage.INSTANCE);
PsiJavaCodeReferenceElement.class,
JavaLanguage.INSTANCE);
rangeMarker.dispose();
if (newElement != null) {
newEndOffset = newElement.getTextRange().getEndOffset();
@@ -762,7 +764,9 @@ public class JavaCompletionUtil {
}
}
if (!staticImport && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference((PsiReference)newElement))) {
if (!staticImport &&
!psiClass.getManager().areElementsEquivalent(psiClass, resolveReference((PsiReference)newElement)) &&
!PsiUtil.isInnerClass(psiClass)) {
final String qName = psiClass.getQualifiedName();
if (qName != null) {
document.replaceString(newElement.getTextRange().getStartOffset(), newEndOffset, qName);
@@ -944,8 +948,8 @@ public class JavaCompletionUtil {
}
public static String escapeXmlIfNeeded(InsertionContext context, String generics) {
if (context.getFile().getFileType() instanceof XmlLikeFileType) {
generics = StringUtil.escapeXml(generics);
if (context.getFile().getViewProvider().getBaseLanguage() == StdLanguages.JSPX) {
return StringUtil.escapeXml(generics);
}
return generics;
}
@@ -39,6 +39,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
/**
* @author peter
*/
@@ -116,8 +118,10 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
if (psiClass == null || psiClass.getName() == null) return null;
PsiElement position = parameters.getPosition();
if ((parameters.getInvocationCount() < 2 || psiClass instanceof PsiCompiledElement) &&
HighlightClassUtil.checkCreateInnerClassFromStaticContext(parameters.getPosition(), null, psiClass) != null) {
HighlightClassUtil.checkCreateInnerClassFromStaticContext(position, null, psiClass) != null &&
!psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).afterLeaf(".")).accepts(position)) {
return null;
}
@@ -143,7 +147,7 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
}
}
}
final PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(psiType, parameters.getPosition());
final PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(psiType, position);
JavaCompletionUtil.setShowFQN(item);
if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
@@ -111,7 +111,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
suggestedNameInfo = codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, var, false);
final String[] suggestedNames = suggestedNameInfo.names;
addLookupItems(set, suggestedNameInfo, matcher, project, suggestedNames);
if (set.isEmpty()) {
if (!hasStartMatches(set, matcher)) {
if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) && matcher.prefixMatches("object")) {
set.add(LookupElementBuilder.create("object"));
}
@@ -120,7 +120,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
}
}
if (set.isEmpty() && includeOverlapped) {
if (!hasStartMatches(set, matcher) && includeOverlapped) {
addLookupItems(set, null, matcher, project, getOverlappedNameVersions(matcher.getPrefix(), suggestedNames, ""));
}
PsiElement parent = PsiTreeUtil.getParentOfType(var, PsiCodeBlock.class);
@@ -137,6 +137,23 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
}
}
private static boolean hasStartMatches(PrefixMatcher matcher, Set<String> set) {
for (String s : set) {
if (matcher.isStartMatch(s)) {
return true;
}
}
return false;
}
private static boolean hasStartMatches(Set<LookupElement> set, PrefixMatcher matcher) {
for (LookupElement lookupElement : set) {
if (hasStartMatches(matcher, lookupElement.getAllLookupStrings())) {
return true;
}
}
return false;
}
private static void addSuggestionsInspiredByFieldNames(Set<LookupElement> set,
PrefixMatcher matcher,
PsiVariable var,
@@ -246,7 +263,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
final String[] suggestedNames = suggestedNameInfo.names;
addLookupItems(set, suggestedNameInfo, matcher, project, suggestedNames);
if (set.isEmpty() && includeOverlapped) {
if (!hasStartMatches(set, matcher) && includeOverlapped) {
// use suggested names as suffixes
final String requiredSuffix = codeStyleManager.getSuffixByVariableKind(variableKind);
if(variableKind != VariableKind.STATIC_FINAL_FIELD){
@@ -295,7 +312,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
}
}
if (result.isEmpty() && PsiType.VOID != varType && includeOverlapped) {
if (!hasStartMatches(matcher, result) && PsiType.VOID != varType && includeOverlapped) {
// use suggested names as suffixes
final String requiredSuffix = codeStyleManager.getSuffixByVariableKind(varKind);
final String prefix = matcher.getPrefix();
@@ -30,6 +30,9 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.intellij.patterns.PsiJavaPatterns.psiClass;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
/**
* @author peter
*/
@@ -37,17 +40,24 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true));
final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) ||
suggestMetaAnnotations(parameters);
if (!empty && parameters.getInvocationCount() == 0) {
result.restartCompletionWhenNothingMatches();
}
if (empty) {
delegate(parameters, result);
delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
}
}
private static boolean suggestMetaAnnotations(CompletionParameters parameters) {
PsiElement position = parameters.getPosition();
return psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class, PsiModifierList.class, PsiClass.class).accepts( position) &&
psiElement().withSuperParent(4, psiClass().isAnnotationType()).accepts(position);
}
public static boolean containsOnlyPackages(LinkedHashSet<CompletionResult> results) {
for (CompletionResult result : results) {
if (!(CompletionUtil.getTargetElement(result.getLookupElement()) instanceof PsiPackage)) {
@@ -152,7 +162,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
JavaClassNameCompletionContributor.addAllClasses(parameters,
true, JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer<LookupElement>() {
true, result.getPrefixMatcher(), new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
@@ -1,140 +1,215 @@
/*
* Copyright 2000-2009 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 com.intellij.codeInsight.completion;
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
import com.intellij.psi.*;
import com.intellij.psi.filters.getters.MembersGetter;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* @author peter
*/
public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupElementWeigher {
private final CompletionType myCompletionType;
private final PsiElement myPosition;
private final Set<PsiField> myNonInitializedFields;
public PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(CompletionType completionType, PsiElement position) {
super("local");
myCompletionType = completionType;
myPosition = position;
myNonInitializedFields = JavaCompletionProcessor.getNonInitializedFields(position);
}
enum MyResult {
annoMethod,
probableKeyword,
localOrParameter,
qualifiedWithField,
qualifiedWithGetter,
superMethodParameters,
normal,
collectionFactory,
expectedTypeMember,
nonInitialized,
classLiteral,
classNameOrGlobalStatic,
}
@NotNull
@Override
public MyResult weigh(@NotNull LookupElement item) {
final Object object = item.getObject();
if (object instanceof PsiKeyword) {
String keyword = ((PsiKeyword)object).getText();
if (PsiKeyword.RETURN.equals(keyword) && isLastStatement(PsiTreeUtil.getParentOfType(myPosition, PsiStatement.class))) {
return MyResult.probableKeyword;
}
if (PsiKeyword.ELSE.equals(keyword) || PsiKeyword.FINALLY.equals(keyword)) {
return MyResult.probableKeyword;
}
}
if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
return MyResult.localOrParameter;
}
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
return MyResult.superMethodParameters;
}
if (myCompletionType == CompletionType.SMART) {
if (item.getUserData(CollectionsUtilityMethodsProvider.COLLECTION_FACTORY) != null) {
return MyResult.collectionFactory;
}
if (Boolean.TRUE.equals(item.getUserData(MembersGetter.EXPECTED_TYPE_INHERITOR_MEMBER))) {
return MyResult.expectedTypeMember;
}
final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY);
if (chain != null) {
Object qualifier = chain.getQualifier().getObject();
if (qualifier instanceof PsiLocalVariable || qualifier instanceof PsiParameter) {
return MyResult.localOrParameter;
}
if (qualifier instanceof PsiField) {
return MyResult.qualifiedWithField;
}
if (qualifier instanceof PsiMethod && PropertyUtil.isSimplePropertyGetter((PsiMethod)qualifier)) {
return MyResult.qualifiedWithGetter;
}
}
return MyResult.normal;
}
if (myCompletionType == CompletionType.BASIC) {
StaticallyImportable callElement = item.as(StaticallyImportable.CLASS_CONDITION_KEY);
if (callElement != null && callElement.canBeImported() && !callElement.willBeImported()) {
return MyResult.classNameOrGlobalStatic;
}
if (object instanceof PsiKeyword && PsiKeyword.CLASS.equals(item.getLookupString())) {
return MyResult.classLiteral;
}
if (object instanceof PsiAnnotationMethod && ((PsiAnnotationMethod)object).getContainingClass().isAnnotationType()) {
return MyResult.annoMethod;
}
if (object instanceof PsiClass) {
return MyResult.classNameOrGlobalStatic;
}
if (object instanceof PsiField && myNonInitializedFields.contains(object)) {
return MyResult.nonInitialized;
}
}
return MyResult.normal;
}
private static boolean isLastStatement(PsiStatement statement) {
if (statement == null || !(statement.getParent() instanceof PsiCodeBlock)) {
return true;
}
PsiStatement[] siblings = ((PsiCodeBlock)statement.getParent()).getStatements();
return statement == siblings[siblings.length - 1];
}
}
/*
* Copyright 2000-2009 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 com.intellij.codeInsight.completion;
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
import com.intellij.openapi.util.Condition;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.filters.getters.MembersGetter;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
import static com.intellij.patterns.StandardPatterns.or;
/**
* @author peter
*/
public class PreferByKindWeigher extends LookupElementWeigher {
static final ElementPattern<PsiElement> IN_CATCH_TYPE =
psiElement().withParent(psiElement(PsiJavaCodeReferenceElement.class).
withParent(psiElement(PsiTypeElement.class).
withParent(or(psiElement(PsiCatchSection.class),
psiElement(PsiVariable.class).withParent(PsiCatchSection.class)))));
static final ElementPattern<PsiElement> IN_MULTI_CATCH_TYPE =
or(psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiCatchSection.class)),
psiElement().afterLeaf(psiElement().withText("|").withParent(PsiTypeElement.class).withSuperParent(2, PsiParameter.class).withSuperParent(3, PsiCatchSection.class)));
static final ElementPattern<PsiElement> INSIDE_METHOD_THROWS_CLAUSE =
psiElement().afterLeaf(PsiKeyword.THROWS, ",").inside(psiElement(JavaElementType.THROWS_LIST));
static final ElementPattern<PsiElement> IN_RESOURCE_TYPE =
psiElement().withParent(psiElement(PsiJavaCodeReferenceElement.class).
withParent(psiElement(PsiTypeElement.class).
withParent(or(psiElement(PsiResourceVariable.class), psiElement(PsiResourceList.class)))));
private final CompletionType myCompletionType;
private final PsiElement myPosition;
private final Set<PsiField> myNonInitializedFields;
@NotNull private final Condition<PsiClass> myRequiredSuper;
public PreferByKindWeigher(CompletionType completionType, final PsiElement position) {
super("local");
myCompletionType = completionType;
myPosition = position;
myNonInitializedFields = JavaCompletionProcessor.getNonInitializedFields(position);
myRequiredSuper = createSuitabilityCondition(position);
}
private static Condition<PsiClass> createSuitabilityCondition(final PsiElement position) {
if (IN_CATCH_TYPE.accepts(position) ||
IN_MULTI_CATCH_TYPE.accepts(position) ||
JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(position) ||
INSIDE_METHOD_THROWS_CLAUSE.accepts(position)) {
return new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
return InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_LANG_THROWABLE);
}
};
}
if (IN_RESOURCE_TYPE.accepts(position)) {
return new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
return InheritanceUtil.isInheritor(psiClass, CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE);
}
};
}
if (psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).accepts(position)) {
final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(position, PsiAnnotation.class);
assert annotation != null;
PsiAnnotationOwner owner = annotation.getOwner();
if (owner instanceof PsiModifierList || owner instanceof PsiTypeElement ||
owner instanceof PsiMethodReceiver || owner instanceof PsiTypeParameter) {
PsiElement member = ((PsiElement)owner).getParent();
final String[] elementTypeFields = PsiAnnotationImpl
.getApplicableElementTypeFields(owner instanceof PsiModifierList ? member : (PsiElement)owner);
return new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
if (!psiClass.isAnnotationType()) {
return false;
}
return PsiAnnotationImpl.isAnnotationApplicable(false, psiClass, elementTypeFields, position.getResolveScope());
}
};
}
}
//noinspection unchecked
return Condition.FALSE;
}
enum MyResult {
annoMethod,
probableKeyword,
localOrParameter,
qualifiedWithField,
qualifiedWithGetter,
superMethodParameters,
normal,
collectionFactory,
expectedTypeMember,
suitableClass,
nonInitialized,
classLiteral,
classNameOrGlobalStatic,
}
@NotNull
@Override
public MyResult weigh(@NotNull LookupElement item) {
final Object object = item.getObject();
if (object instanceof PsiKeyword) {
String keyword = ((PsiKeyword)object).getText();
if (PsiKeyword.RETURN.equals(keyword) && isLastStatement(PsiTreeUtil.getParentOfType(myPosition, PsiStatement.class))) {
return MyResult.probableKeyword;
}
if (PsiKeyword.ELSE.equals(keyword) || PsiKeyword.FINALLY.equals(keyword)) {
return MyResult.probableKeyword;
}
}
if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
return MyResult.localOrParameter;
}
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
return MyResult.superMethodParameters;
}
if (myCompletionType == CompletionType.SMART) {
if (item.getUserData(CollectionsUtilityMethodsProvider.COLLECTION_FACTORY) != null) {
return MyResult.collectionFactory;
}
if (Boolean.TRUE.equals(item.getUserData(MembersGetter.EXPECTED_TYPE_INHERITOR_MEMBER))) {
return MyResult.expectedTypeMember;
}
final JavaChainLookupElement chain = item.as(JavaChainLookupElement.CLASS_CONDITION_KEY);
if (chain != null) {
Object qualifier = chain.getQualifier().getObject();
if (qualifier instanceof PsiLocalVariable || qualifier instanceof PsiParameter) {
return MyResult.localOrParameter;
}
if (qualifier instanceof PsiField) {
return MyResult.qualifiedWithField;
}
if (qualifier instanceof PsiMethod && PropertyUtil.isSimplePropertyGetter((PsiMethod)qualifier)) {
return MyResult.qualifiedWithGetter;
}
}
return MyResult.normal;
}
if (myCompletionType == CompletionType.BASIC) {
StaticallyImportable callElement = item.as(StaticallyImportable.CLASS_CONDITION_KEY);
if (callElement != null && callElement.canBeImported() && !callElement.willBeImported()) {
return MyResult.classNameOrGlobalStatic;
}
if (object instanceof PsiKeyword && PsiKeyword.CLASS.equals(item.getLookupString())) {
return MyResult.classLiteral;
}
if (object instanceof PsiMethod && PsiUtil.isAnnotationMethod((PsiElement)object)) {
return MyResult.annoMethod;
}
if (object instanceof PsiClass) {
if (myRequiredSuper.value((PsiClass)object)) {
return MyResult.suitableClass;
}
return MyResult.classNameOrGlobalStatic;
}
if (object instanceof PsiField && myNonInitializedFields.contains(object)) {
return MyResult.nonInitialized;
}
}
return MyResult.normal;
}
private static boolean isLastStatement(PsiStatement statement) {
if (statement == null || !(statement.getParent() instanceof PsiCodeBlock)) {
return true;
}
PsiStatement[] siblings = ((PsiCodeBlock)statement.getParent()).getStatements();
return statement == siblings[siblings.length - 1];
}
}
@@ -1,38 +0,0 @@
/*
* Copyright 2000-2009 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 com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author peter
*/
public class PreferLessParametersWeigher extends CompletionWeigher {
@Override
public Integer weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) {
if (location == null) {
return null;
}
final Object o = element.getObject();
if (o instanceof PsiMethod) {
return ((PsiMethod)o).getParameterList().getParametersCount();
}
return 0;
}
}
@@ -1,59 +1,62 @@
/*
* Copyright 2000-2009 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 com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.StdLanguages;
import com.intellij.psi.PsiElement;
import com.intellij.util.Consumer;
/**
* @author peter
*/
public class XmlBasicToClassNameDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
if (parameters.getCompletionType() != CompletionType.BASIC ||
!JavaCompletionContributor.mayStartClassName(result) ||
!position.getContainingFile().getLanguage().isKindOf(StdLanguages.XML)) {
return;
}
final boolean empty = result.runRemainingContributors(parameters, true).isEmpty();
if (!empty && parameters.getInvocationCount() == 0) {
result.restartCompletionWhenNothingMatches();
}
if (empty || parameters.isExtendedCompletion()) {
CompletionService.getCompletionService().getVariantsFromContributors(parameters.delegateToClassName(), null, new Consumer<CompletionResult>() {
public void consume(final CompletionResult completionResult) {
LookupElement lookupElement = completionResult.getLookupElement();
JavaPsiClassReferenceElement classElement = lookupElement.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
lookupElement.putUserData(XmlCompletionContributor.WORD_COMPLETION_COMPATIBLE, Boolean.TRUE); //todo think of a less dirty interaction
result.passResult(completionResult);
}
});
}
}
}
/*
* Copyright 2000-2009 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 com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.StdLanguages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
/**
* @author peter
*/
public class XmlBasicToClassNameDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
PsiFile file = position.getContainingFile();
if (parameters.getCompletionType() != CompletionType.BASIC ||
!JavaCompletionContributor.mayStartClassName(result) ||
!file.getLanguage().isKindOf(StdLanguages.XML)) {
return;
}
final boolean empty = result.runRemainingContributors(parameters, true).isEmpty();
if (!empty && parameters.getInvocationCount() == 0) {
result.restartCompletionWhenNothingMatches();
}
if (empty && JavaClassReferenceCompletionContributor.findJavaClassReference(file, parameters.getOffset()) != null ||
parameters.isExtendedCompletion()) {
CompletionService.getCompletionService().getVariantsFromContributors(parameters.delegateToClassName(), null, new Consumer<CompletionResult>() {
public void consume(final CompletionResult completionResult) {
LookupElement lookupElement = completionResult.getLookupElement();
JavaPsiClassReferenceElement classElement = lookupElement.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
}
lookupElement.putUserData(XmlCompletionContributor.WORD_COMPLETION_COMPATIBLE, Boolean.TRUE); //todo think of a less dirty interaction
result.passResult(completionResult);
}
});
}
}
}
@@ -261,8 +261,8 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
}
}
public Set<CompletionElement> getResults(){
return new THashSet<CompletionElement>(myResults);
public Iterable<CompletionElement> getResults(){
return myResults;
}
public void clear() {
@@ -188,7 +188,7 @@ public class AnnotationsHighlightUtil {
PsiMethod[] annotationMethods = aClass.getMethods();
List<String> missed = new ArrayList<String>();
for (PsiMethod method : annotationMethods) {
if (method instanceof PsiAnnotationMethod) {
if (PsiUtil.isAnnotationMethod(method)) {
PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod)method;
if (annotationMethod.getDefaultValue() == null) {
if (!names.contains(annotationMethod.getName())) {
@@ -216,7 +216,7 @@ public class AnnotationsHighlightUtil {
@Nullable
public static HighlightInfo checkConstantExpression(PsiExpression expression) {
final PsiElement parent = expression.getParent();
if (parent instanceof PsiAnnotationMethod || parent instanceof PsiNameValuePair || parent instanceof PsiArrayInitializerMemberValue) {
if (PsiUtil.isAnnotationMethod(parent) || parent instanceof PsiNameValuePair || parent instanceof PsiArrayInitializerMemberValue) {
if (!PsiUtil.isConstantExpression(expression)) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, JavaErrorMessages.message("annotation.nonconstant.attribute.value"));
}
@@ -312,7 +312,7 @@ public class AnnotationsHighlightUtil {
}
public static HighlightInfo checkAnnotationDeclaration(final PsiElement parent, final PsiReferenceList list) {
if (parent instanceof PsiAnnotationMethod) {
if (PsiUtil.isAnnotationMethod(parent)) {
PsiAnnotationMethod method = (PsiAnnotationMethod)parent;
if (list == method.getThrowsList()) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, list, JavaErrorMessages.message("annotation.members.may.not.have.throws.list"));
@@ -925,7 +925,7 @@ public class GenericsHighlightUtil {
parameterList,
JavaErrorMessages.message("generics.enum.may.not.have.type.parameters"));
}
if (parent instanceof PsiAnnotationMethod) {
if (PsiUtil.isAnnotationMethod(parent)) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, parameterList, JavaErrorMessages.message("generics.annotation.members.may.not.have.type.parameters"));
}
else if (parent instanceof PsiClass && ((PsiClass)parent).isAnnotationType()) {
@@ -692,10 +692,53 @@ public class HighlightControlFlowUtil {
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, context, description);
QuickFixAction.registerQuickFixAction(highlightInfo, new VariableAccessFromInnerClassFix(variable, innerClass));
return highlightInfo;
} else {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(context, PsiLambdaExpression.class);
if (lambdaExpression != null) {
boolean effectivelyFinal;
if (variable instanceof PsiParameter) {
final PsiElement parent = variable.getParent();
if (parent instanceof PsiParameterList && parent.getParent() == lambdaExpression) {
return null;
}
effectivelyFinal = isAccessedForWriting(variable, new LocalSearchScope(((PsiParameter)variable).getDeclarationScope()));
} else {
final ControlFlow controlFlow;
try {
controlFlow = getControlFlow(PsiUtil.getVariableCodeBlock(variable, context));
}
catch (AnalysisCanceledException e) {
return null;
}
if (ControlFlowUtil.isVariableDefinitelyAssigned(variable, controlFlow)) {
final Collection<ControlFlowUtil.VariableInfo> initializedTwice = ControlFlowUtil.getInitializedTwice(controlFlow);
effectivelyFinal = !initializedTwice.contains(new ControlFlowUtil.VariableInfo(variable, null));
if (effectivelyFinal) {
effectivelyFinal = isAccessedForWriting(variable, new LocalSearchScope(lambdaExpression));
}
} else {
effectivelyFinal = false;
}
}
if (!effectivelyFinal ) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, context, "Variable used in lambda expression should be effectively final");
}
}
}
return null;
}
private static boolean isAccessedForWriting(PsiVariable variable, final LocalSearchScope searchScope) {
for (PsiReference reference : ReferencesSearch.search(variable, searchScope)) {
final PsiElement element = reference.getElement();
if (element instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)element)) {
return false;
}
}
return true;
}
@Nullable
public static PsiClass getInnerClassVariableReferencedFrom(PsiVariable variable, PsiElement context) {
final PsiElement[] scope;
@@ -1280,19 +1280,21 @@ public class HighlightMethodUtil {
String toolTip = createMismatchedArgumentsHtmlTooltip(result, list);
PsiElement infoElement = list.getTextLength() > 0 ? list : constructorCall;
HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, infoElement, description, toolTip);
QuickFixAction.registerQuickFixAction(info, constructorCall.getTextRange(), new CreateConstructorFromCallFix(constructorCall));
if (classReference != null) {
ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(infoElement));
ChangeMethodSignatureFromUsageFix.registerIntentions(results, list, info, null);
ChangeTypeArgumentsFix.registerIntentions(results, list, info, aClass);
ConvertDoubleToFloatFix.registerIntentions(results, list, info, null);
PermuteArgumentsFix.registerFix(info, constructorCall, toMethodCandidates(results), getFixRange(list));
ChangeParameterClassFix.registerQuickFixActions(constructorCall, list, info);
QuickFixAction.registerQuickFixAction(info, getFixRange(list), new SurroundWithArrayFix(constructorCall));
if (info != null) {
QuickFixAction.registerQuickFixAction(info, constructorCall.getTextRange(), new CreateConstructorFromCallFix(constructorCall));
if (classReference != null) {
ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(infoElement));
ChangeMethodSignatureFromUsageFix.registerIntentions(results, list, info, null);
ChangeTypeArgumentsFix.registerIntentions(results, list, info, aClass);
ConvertDoubleToFloatFix.registerIntentions(results, list, info, null);
PermuteArgumentsFix.registerFix(info, constructorCall, toMethodCandidates(results), getFixRange(list));
ChangeParameterClassFix.registerQuickFixActions(constructorCall, list, info);
QuickFixAction.registerQuickFixAction(info, getFixRange(list), new SurroundWithArrayFix(constructorCall));
}
info.navigationShift = +1;
holder.add(info);
ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info);
}
info.navigationShift = +1;
holder.add(info);
ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info);
}
else {
HighlightInfo highlightInfo;
@@ -331,6 +331,9 @@ public class HighlightUtil {
PsiType checkType = typeElement.getType();
PsiType operandType = operand.getType();
if (operandType == null) return null;
if (operandType instanceof PsiLambdaExpressionType) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, "Lambda expression is not expected here");
}
if (TypeConversionUtil.isPrimitiveAndNotNull(operandType)
|| TypeConversionUtil.isPrimitiveAndNotNull(checkType)
|| !TypeConversionUtil.areTypesConvertible(operandType, checkType)) {
@@ -511,10 +514,15 @@ public class HighlightUtil {
if (suppressed(Kind.RETURN_STATEMENT, statement)) return null;
PsiMethod method = null;
PsiLambdaExpression lambda = null;
PsiElement parent = statement.getParent();
while (true) {
if (parent instanceof PsiFile) break;
if (parent instanceof PsiClassInitializer) break;
if (parent instanceof PsiLambdaExpression){
lambda = (PsiLambdaExpression)parent;
break;
}
if (parent instanceof PsiMethod) {
method = (PsiMethod)parent;
break;
@@ -524,7 +532,9 @@ public class HighlightUtil {
String description;
int navigationShift = 0;
HighlightInfo errorResult = null;
if (method == null && !(parent instanceof JspFile)) {
if (method == null && lambda != null) {
//todo check return statements type inside lambda
} else if (method == null && !(parent instanceof JspFile)) {
description = JavaErrorMessages.message("return.outside.method");
errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, statement, description);
}
@@ -2527,7 +2537,7 @@ public class HighlightUtil {
@Nullable
static HighlightInfo checkAnnotationMethodParameters(@NotNull PsiParameterList list) {
if (list.getParent() instanceof PsiAnnotationMethod && list.getParametersCount() > 0) {
if (PsiUtil.isAnnotationMethod(list.getParent()) && list.getParametersCount() > 0) {
final String message = JavaErrorMessages.message("annotation.interface.members.may.not.have.parameters");
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, list, message);
}
@@ -2628,10 +2638,6 @@ public class HighlightUtil {
@Nullable
public static HighlightInfo checkLambdaFeature(final PsiLambdaExpression expression) {
final HighlightInfo info = checkFeature(expression, Feature.LAMBDA_EXPRESSIONS);
if (info != null) return info;
// todo[r.sh] stub; remove after implementing support in TypeConversionUtil
final String message = "Lambda expressions type check is not yet implemented";
return HighlightInfo.createHighlightInfo(HighlightInfoType.WEAK_WARNING, expression, message);
return checkFeature(expression, Feature.LAMBDA_EXPRESSIONS);
}
}
@@ -190,7 +190,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (parent instanceof PsiNameValuePair) {
method = (PsiMethod)parent.getReference().resolve();
}
else if (parent instanceof PsiAnnotationMethod) {
else if (PsiUtil.isAnnotationMethod(parent)) {
method = (PsiMethod)parent;
}
if (method != null) {
@@ -1,58 +0,0 @@
/*
* Copyright 2000-2012 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 com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A filter to temporarily suppress highlighting errors inside lambda expressions.
* todo[r.sh] stub; remove after implementing type inference
*/
public class JavaHighlightInfoFilter implements HighlightInfoFilter {
@Override
public boolean accept(@NotNull final HighlightInfo info, @Nullable final PsiFile file) {
if (!(file instanceof PsiJavaFile)) return true;
if (info.getSeverity() != HighlightSeverity.ERROR) return true;
if (description(info, "Lambda expressions are not supported at this language level")) return true;
final PsiElement element = file.findElementAt(info.getStartOffset());
if (element == null) return true;
return !isInsideLambda(element) &&
!isLambdaInAmbiguousCall(info, element);
}
private static boolean isInsideLambda(final PsiElement element) {
return PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class, false) != null;
}
private static boolean isLambdaInAmbiguousCall(final HighlightInfo info, final PsiElement element) {
if (!description(info, "Ambiguous method call")) return false;
final PsiElement exprList = element.getParent();
if (!(exprList instanceof PsiExpressionList)) return false;
return PsiTreeUtil.getChildOfType(exprList, PsiLambdaExpression.class) != null;
}
private static boolean description(final HighlightInfo info, final String prefix) {
return info.description != null && info.description.startsWith(prefix);
}
}
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesHandler;
@@ -61,7 +60,7 @@ import java.util.*;
* @author cdr
* @since Nov 13, 2002
*/
public class ChangeMethodSignatureFromUsageFix implements IntentionAction, HighPriorityAction {
public class ChangeMethodSignatureFromUsageFix implements IntentionAction/*, HighPriorityAction*/ {
final PsiMethod myTargetMethod;
final PsiExpression[] myExpressions;
final PsiSubstitutor mySubstitutor;
@@ -176,6 +176,7 @@ public class RenameWrongRefFix implements IntentionAction {
}
}
items.add(LookupElementBuilder.create(myRefExpr.getReferenceName()));
MyScopeProcessor processor = new MyScopeProcessor(myRefExpr);
myRefExpr.processVariants(processor);
PsiElement[] variants = processor.getVariants();
@@ -96,7 +96,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> imple
public void processTransferableData(final Project project,
final Editor editor,
final RangeMarker bounds,
int caretColumn,
int caretOffset,
Ref<Boolean> indented, final ReferenceTransferableData value) {
if (DumbService.getInstance(project).isDumb()) {
return;
File diff suppressed because it is too large Load Diff
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.parameterInfo.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -122,6 +123,6 @@ public class AnnotationParameterInfoHandler implements ParameterInfoHandler<PsiA
if (pair == null) return null;
final PsiReference reference = pair.getReference();
final PsiElement resolved = reference != null ? reference.resolve():null;
return resolved instanceof PsiAnnotationMethod ? (PsiAnnotationMethod)resolved : null;
return PsiUtil.isAnnotationMethod(resolved) ? (PsiAnnotationMethod)resolved : null;
}
}
@@ -78,7 +78,12 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
}
}
}
if (importList.findSingleImportStatement(refExpr.getReferenceName()) == null) {
final PsiImportStatementBase importStatement = importList.findSingleImportStatement(refExpr.getReferenceName());
if (importStatement == null) {
return qName;
}
final PsiElement resolve = importStatement.resolve();
if (resolve instanceof PsiMember && ((PsiMember)resolve).getContainingClass() != aClass) {
return qName;
}
}
@@ -0,0 +1,110 @@
/*
* Copyright 2000-2012 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 com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class PushConditionInCallAction extends PsiElementBaseIntentionAction {
@Override
@NotNull
public String getFamilyName() {
return "Push condition inside call";
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
if (element instanceof PsiCompiledElement) return false;
if (!element.getManager().isInProject(element)) return false;
// if (!(element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.QUEST)) return false;
final PsiConditionalExpression conditionalExpression = PsiTreeUtil.getParentOfType(element, PsiConditionalExpression.class);
if (conditionalExpression == null) return false;
final PsiExpression thenExpression = conditionalExpression.getThenExpression();
if (!(thenExpression instanceof PsiCallExpression)) return false;
final PsiMethod thenMethod = ((PsiCallExpression)thenExpression).resolveMethod();
final PsiExpressionList thenArgsList = ((PsiCallExpression)thenExpression).getArgumentList();
if (thenArgsList == null) return false;
final PsiExpression[] thenExpressions = thenArgsList.getExpressions();
final PsiExpression elseExpression = conditionalExpression.getElseExpression();
if (!(elseExpression instanceof PsiCallExpression)) return false;
final PsiMethod elseMethod = ((PsiCallExpression)elseExpression).resolveMethod();
final PsiExpressionList elseArgsList = ((PsiCallExpression)elseExpression).getArgumentList();
if (elseArgsList == null) return false;
final PsiExpression[] elseExpressions = elseArgsList.getExpressions();
if (thenMethod != elseMethod || thenMethod == null) return false;
if (thenExpressions.length != elseExpressions.length) return false;
PsiExpression tExpr = null;
PsiExpression eExpr = null;
for (int i = 0; i < thenExpressions.length; i++) {
PsiExpression lExpr = thenExpressions[i];
PsiExpression rExpr = elseExpressions[i];
if (!PsiEquivalenceUtil.areElementsEquivalent(lExpr, rExpr)) {
if (tExpr == null || eExpr == null) {
tExpr = lExpr;
eExpr = rExpr;
}
else {
return false;
}
}
}
setText("Push condition '" + conditionalExpression.getCondition().getText() + "' inside " +
(thenMethod.isConstructor() ? "constructor" : "method") + " call");
return true;
}
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
final PsiConditionalExpression conditionalExpression = PsiTreeUtil.getParentOfType(element, PsiConditionalExpression.class);
final PsiExpression thenExpression = (PsiExpression)conditionalExpression.getThenExpression().copy();
final PsiExpressionList thenArgsList = ((PsiCallExpression)thenExpression).getArgumentList();
final PsiExpression[] thenExpressions = thenArgsList.getExpressions();
final PsiExpression elseExpression = conditionalExpression.getElseExpression();
final PsiExpressionList elseArgsList = ((PsiCallExpression)elseExpression).getArgumentList();
final PsiExpression[] elseExpressions = elseArgsList.getExpressions();
for (int i = 0; i < thenExpressions.length; i++) {
PsiExpression lExpr = thenExpressions[i];
PsiExpression rExpr = elseExpressions[i];
if (!PsiEquivalenceUtil.areElementsEquivalent(lExpr, rExpr)) {
lExpr.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(
conditionalExpression.getCondition().getText() + "?" + lExpr.getText() + ":" + rExpr.getText(), lExpr));
break;
}
}
CodeStyleManager.getInstance(project).reformat(conditionalExpression.replace(thenExpression));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -382,7 +382,11 @@ public class JavaDocInfoGenerator {
@Nullable
private static PsiDocComment getDocComment(final PsiDocCommentOwner docOwner) {
PsiDocComment comment = ((PsiDocCommentOwner)docOwner.getNavigationElement()).getDocComment();
PsiElement navElement = docOwner.getNavigationElement();
if (!(navElement instanceof PsiDocCommentOwner)) {
throw new AssertionError("Wrong navElement: " + navElement + "; original = " + docOwner + " of class " + docOwner.getClass());
}
PsiDocComment comment = ((PsiDocCommentOwner)navElement).getDocComment();
if (comment == null) { //check for non-normalized fields
final PsiModifierList modifierList = docOwner.getModifierList();
if (modifierList != null) {
@@ -851,6 +855,9 @@ public class JavaDocInfoGenerator {
}
private static boolean isEmptyDescription(PsiDocComment comment) {
if (comment == null) {
return true;
}
PsiElement[] descriptionElements = comment.getDescriptionElements();
for (PsiElement description : descriptionElements) {
@@ -1489,7 +1496,7 @@ public class JavaDocInfoGenerator {
@SuppressWarnings({"HardCodedStringLiteral"})
public static int generateType(StringBuilder buffer, PsiType type, PsiElement context, boolean generateLink) {
if (type instanceof PsiPrimitiveType) {
String text = type.getCanonicalText();
String text = StringUtil.escapeXml(type.getCanonicalText());
buffer.append(text);
return text.length();
}
@@ -1532,7 +1539,7 @@ public class JavaDocInfoGenerator {
PsiSubstitutor psiSubst = result.getSubstitutor();
if (psiClass == null) {
String text = "<font color=red>" + type.getCanonicalText() + "</font>";
String text = "<font color=red>" + StringUtil.escapeXml(type.getCanonicalText()) + "</font>";
buffer.append(text);
return text.length();
}
@@ -1540,7 +1547,7 @@ public class JavaDocInfoGenerator {
String qName = psiClass.getQualifiedName();
if (qName == null || psiClass instanceof PsiTypeParameter) {
String text = type.getCanonicalText();
String text = StringUtil.escapeXml(type.getCanonicalText());
buffer.append(text);
return text.length();
}
@@ -1589,7 +1596,7 @@ public class JavaDocInfoGenerator {
if (type instanceof PsiDisjunctionType) {
if (!generateLink) {
final String text = type.getCanonicalText();
final String text = StringUtil.escapeXml(type.getCanonicalText());
buffer.append(text);
return text.length();
}
@@ -158,10 +158,6 @@ public class PsiTypeLookupItem extends LookupItem {
PsiTypeLookupItem item = doCreateItem(type, context, dim);
if (dim > 0) {
item.setAttribute(TAIL_TEXT_ATTR, " " + StringUtil.repeat("[]", dim));
item.setAttribute(TAIL_TEXT_SMALL_ATTR, "");
}
item.setAttribute(TYPE, original);
return item;
}
@@ -187,10 +183,10 @@ public class PsiTypeLookupItem extends LookupItem {
Set<String> allStrings = new HashSet<String>();
String lookupString = psiClass.getName();
allStrings.add(lookupString);
if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass)) {
if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass) && !PsiUtil.isInnerClass(psiClass)) {
// inner class name should be shown qualified if its not accessible by single name
PsiClass aClass = psiClass.getContainingClass();
while (aClass != null) {
while (aClass != null && !PsiUtil.isInnerClass(aClass)) {
lookupString = aClass.getName() + '.' + lookupString;
allStrings.add(lookupString);
aClass = aClass.getContainingClass();
@@ -228,10 +224,9 @@ public class PsiTypeLookupItem extends LookupItem {
presentation.setItemText(((PsiType)object).getCanonicalText());
presentation.setItemTextBold(getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null || object instanceof PsiPrimitiveType);
String tailText = (String)getAttribute(LookupItem.TAIL_TEXT_ATTR);
if (tailText != null) {
presentation.setTailText(tailText, getAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR) != null);
}
}
if (myBracketsCount > 0) {
presentation.setTailText(StringUtil.repeat("[]", myBracketsCount) + StringUtil.notNullize(presentation.getTailText()), true);
}
}
@@ -18,10 +18,7 @@ package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.*;
@@ -702,6 +699,16 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
return NOT_FOUND;
}
private static class ApplyNotNullInstruction extends Instruction {
@Override
public DfaInstructionState[] accept(DataFlowRunner runner, DfaMemoryState state, InstructionVisitor visitor) {
DfaValue value = state.pop();
DfaValueFactory factory = runner.getFactory();
state.applyCondition(factory.getRelationFactory().create(value, factory.getConstFactory().getNull(), JavaTokenType.EQEQ, true));
return nextInstruction(runner, state);
}
}
class CatchDescriptor {
private final PsiType myType;
private PsiParameter myParameter;
@@ -1182,6 +1189,21 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
if (!myCatchStack.isEmpty()) {
addMethodThrows(expression.resolveMethod());
}
if (paramExprs.length == 1 && method instanceof PsiMethod &&
"equals".equals(((PsiMethod)method).getName()) && parameters.length == 1 &&
parameters[0].getType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT) &&
PsiType.BOOLEAN.equals(((PsiMethod)method).getReturnType())) {
addInstruction(new PushInstruction(myFactory.getConstFactory().getFalse(), null));
addInstruction(new SwapInstruction());
addInstruction(new ConditionalGotoInstruction(getEndOffset(expression), true, null));
addInstruction(new PopInstruction());
addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null));
paramExprs[0].accept(this);
addInstruction(new ApplyNotNullInstruction());
}
}
finally {
finishElement(expression);
@@ -34,7 +34,6 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
import com.intellij.ide.DataManager;
import com.intellij.lang.ASTFactory;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -42,7 +41,6 @@ import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Pair;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
@@ -71,11 +69,6 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
return new OptionsPanel();
}
void test(@NotNull List l) {
final List list = null;
test(list);
}
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new JavaElementVisitor() {
@@ -507,6 +507,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
public boolean isNotNull(DfaVariableValue dfaVar) {
if (getVariableState(dfaVar).isNotNull()) {
return true;
}
DfaConstValue dfaNull = myFactory.getConstFactory().getNull();
Integer c1Index = getOrCreateEqClassIndex(dfaVar);
Integer c2Index = getOrCreateEqClassIndex(dfaNull);
@@ -266,13 +266,21 @@ public class StandardInstructionVisitor extends InstructionVisitor {
}
boolean negated = memState.canBeNaN(dfaLeft) || memState.canBeNaN(dfaRight);
DfaRelationValue dfaRelation = factory.getRelationFactory().create(dfaLeft, dfaRight, opSign, negated);
DfaRelationValue.Factory relationFactory = factory.getRelationFactory();
DfaRelationValue dfaRelation = relationFactory.create(dfaLeft, dfaRight, opSign, negated);
if (dfaRelation != null) {
myCanBeNullInInstanceof.add(instruction);
ArrayList<DfaInstructionState> states = new ArrayList<DfaInstructionState>();
final DfaMemoryState trueCopy = memState.createCopy();
if (trueCopy.applyCondition(dfaRelation)) {
if (dfaLeft instanceof DfaVariableValue && dfaRight instanceof DfaVariableValue) {
if (trueCopy.isNotNull((DfaVariableValue)dfaLeft)) {
trueCopy.applyCondition(relationFactory.create(dfaRight, factory.getConstFactory().getNull(), JavaTokenType.EQEQ, true));
} else if (trueCopy.isNotNull((DfaVariableValue)dfaRight)) {
trueCopy.applyCondition(relationFactory.create(dfaLeft, factory.getConstFactory().getNull(), JavaTokenType.EQEQ, true));
}
}
trueCopy.push(factory.getConstFactory().getTrue());
instruction.setTrueReachable();
states.add(new DfaInstructionState(next, trueCopy));
@@ -26,6 +26,7 @@ package com.intellij.codeInspection.ex;
import com.intellij.ExtensionPoints;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInspection.reference.*;
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
import com.intellij.ide.DataManager;
@@ -367,6 +368,7 @@ public class EntryPointsManagerImpl implements PersistentStateComponent<Element>
protected void doOKAction() {
ADDITIONAL_ANNOTATIONS.clear();
ADDITIONAL_ANNOTATIONS.addAll(list);
DaemonCodeAnalyzer.getInstance(myProject).restart();
super.doOKAction();
}
}.show();
@@ -71,9 +71,10 @@ public class TestOnlyInspection extends BaseJavaLocalInspectionTool {
return isAnnotatedAsTestOnly(m);
}
private boolean isAnnotatedAsTestOnly(@Nullable PsiMethod m) {
private static boolean isAnnotatedAsTestOnly(@Nullable PsiMethod m) {
if (m == null) return false;
return AnnotationUtil.isAnnotated(m, AnnotationUtil.TEST_ONLY, false);
return AnnotationUtil.isAnnotated(m, AnnotationUtil.TEST_ONLY, false) ||
AnnotationUtil.isAnnotated(m, "com.google.common.annotations.VisibleForTesting", false);
}
private boolean isInsideTestClass(PsiCallExpression e) {
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.util;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionsBundle;
@@ -31,6 +32,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
@@ -216,7 +218,8 @@ public class SpecialAnnotationsUtil {
for (PsiAnnotation psiAnnotation : psiAnnotations) {
@NonNls final String name = psiAnnotation.getQualifiedName();
if (name == null) continue;
if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("org.jetbrains.")) continue;
if (name.startsWith("java.") || name.startsWith("javax.") ||
(name.startsWith("org.jetbrains.") && !AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(name)))) continue;
if (!processor.process(name)) break;
}
}
@@ -21,7 +21,8 @@ import com.intellij.analysis.JavaAnalysisScope;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.*;
@@ -49,7 +50,8 @@ public class CyclicDependenciesAction extends AnAction{
public void update(AnActionEvent event) {
Presentation presentation = event.getPresentation();
presentation.setEnabled(
getInspectionScope(event.getDataContext()) != null || event.getData(LangDataKeys.PSI_FILE) != null);
getInspectionScope(event.getDataContext()) != null ||
event.getData(PlatformDataKeys.PROJECT) != null);
}
public void actionPerformed(AnActionEvent e) {
@@ -57,15 +59,11 @@ public class CyclicDependenciesAction extends AnAction{
final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
final Module module = LangDataKeys.MODULE.getData(dataContext);
if (project != null) {
PsiFile psiFile = LangDataKeys.PSI_FILE.getData(dataContext);
if (psiFile != null && !(psiFile instanceof PsiJavaFile)) {
return;
}
AnalysisScope scope = getInspectionScope(dataContext);
if (scope == null || scope.getScopeType() != AnalysisScope.MODULES){
ProjectModuleOrPackageDialog dlg = null;
if (module != null) {
dlg = new ProjectModuleOrPackageDialog(ModuleUtil.getModuleNameInReadAction(module), scope);
dlg = new ProjectModuleOrPackageDialog(ModuleManager.getInstance(project).getModules().length == 1 ? null : ModuleUtilCore.getModuleNameInReadAction(module), scope);
dlg.show();
if (!dlg.isOK()) return;
}
@@ -104,12 +102,12 @@ public class CyclicDependenciesAction extends AnAction{
//Possible scopes: package, project, module.
Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext);
if (projectContext != null) {
return new AnalysisScope(projectContext);
return null;
}
Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
if (moduleContext != null) {
return new AnalysisScope(moduleContext);
return null;
}
Module [] modulesArray = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext);
@@ -128,12 +126,9 @@ public class CyclicDependenciesAction extends AnAction{
PsiDirectory[] dirs = pack.getDirectories(GlobalSearchScope.projectScope(pack.getProject()));
if (dirs.length == 0) return null;
return new JavaAnalysisScope(pack, LangDataKeys.MODULE.getData(dataContext));
} else if (psiTarget != null){
return null;
}
return getProjectScope(dataContext);
return null;
}
@Nullable
@@ -173,7 +168,6 @@ public class CyclicDependenciesAction extends AnAction{
init();
setTitle(AnalysisScopeBundle.message("cyclic.dependencies.scope.dialog.title", myTitle));
setHorizontalStretch(1.75f);
myModuleButton.setSelected(true);
}
public boolean isIncludeTestSources() {
@@ -190,11 +184,19 @@ public class CyclicDependenciesAction extends AnAction{
myModuleButton.setText(AnalysisScopeBundle.message("cyclic.dependencies.scope.dialog.module.button", myAnalysisVerb, myModuleName));
group.add(myModuleButton);
}
myModuleButton.setVisible(myModuleName != null);
mySelectedScopeButton.setVisible(mySelectedScope != null);
if (mySelectedScope != null) {
mySelectedScopeButton.setText(mySelectedScope.getShortenName());
group.add(mySelectedScopeButton);
}
if (mySelectedScope != null) {
mySelectedScopeButton.setSelected(true);
} else if (myModuleName != null) {
myModuleButton.setSelected(true);
} else {
myProjectButton.setSelected(true);
}
return myWholePanel;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -72,26 +72,25 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
String navigateInfo = null;
if (element instanceof PsiClass) {
navigateInfo = generateClassInfo((PsiClass)element);
return generateClassInfo((PsiClass)element);
}
else if (element instanceof PsiMethod) {
navigateInfo = generateMethodInfo((PsiMethod)element, calcSubstitutor(originalElement));
return generateMethodInfo((PsiMethod)element, calcSubstitutor(originalElement));
}
else if (element instanceof PsiField) {
navigateInfo = generateFieldInfo((PsiField)element, calcSubstitutor(originalElement));
return generateFieldInfo((PsiField)element, calcSubstitutor(originalElement));
}
else if (element instanceof PsiVariable) {
navigateInfo = generateVariableInfo((PsiVariable)element);
return generateVariableInfo((PsiVariable)element);
}
else if (element instanceof PsiPackage) {
navigateInfo = generatePackageInfo((PsiPackage)element);
return generatePackageInfo((PsiPackage)element);
}
else if (element instanceof BeanPropertyElement) {
navigateInfo = generateMethodInfo(((BeanPropertyElement) element).getMethod(), PsiSubstitutor.EMPTY);
return generateMethodInfo(((BeanPropertyElement) element).getMethod(), PsiSubstitutor.EMPTY);
}
return StringUtil.escapeXml(StringUtil.unescapeXml(navigateInfo));
return null;
}
private static PsiSubstitutor calcSubstitutor(PsiElement originalElement) {
@@ -0,0 +1,195 @@
/*
* Copyright 2000-2012 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 com.intellij.psi.codeStyle.arrangement;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaArrangementVisitor extends JavaElementVisitor {
private static final Map<String, ArrangementModifier> MODIFIERS = new HashMap<String, ArrangementModifier>();
static {
MODIFIERS.put(PsiModifier.PUBLIC, ArrangementModifier.PUBLIC);
MODIFIERS.put(PsiModifier.PROTECTED, ArrangementModifier.PROTECTED);
MODIFIERS.put(PsiModifier.PRIVATE, ArrangementModifier.PRIVATE);
MODIFIERS.put(PsiModifier.PACKAGE_LOCAL, ArrangementModifier.PACKAGE_PRIVATE);
MODIFIERS.put(PsiModifier.STATIC, ArrangementModifier.STATIC);
MODIFIERS.put(PsiModifier.FINAL, ArrangementModifier.FINAL);
}
private final Stack<JavaElementArrangementEntry> myStack = new Stack<JavaElementArrangementEntry>();
@NotNull private final List<JavaElementArrangementEntry> myRootEntries;
@NotNull private Document myDocument;
@NotNull private Collection<TextRange> myRanges;
public JavaArrangementVisitor(@NotNull List<JavaElementArrangementEntry> entries,
@NotNull Document document,
@NotNull Collection<TextRange> ranges)
{
myRootEntries = entries;
myDocument = document;
myRanges = ranges;
}
@Override
public void visitClass(PsiClass aClass) {
JavaElementArrangementEntry entry = createNewEntry(aClass.getTextRange(), ArrangementEntryType.CLASS, aClass.getName(), true);
processEntry(entry, aClass, aClass);
}
@Override
public void visitAnonymousClass(PsiAnonymousClass aClass) {
JavaElementArrangementEntry entry = createNewEntry(aClass.getTextRange(), ArrangementEntryType.CLASS, aClass.getName(), false);
processEntry(entry, null, aClass);
}
@Override
public void visitJavaFile(PsiJavaFile file) {
for (PsiClass psiClass : file.getClasses()) {
visitClass(psiClass);
}
}
@Override
public void visitField(PsiField field) {
JavaElementArrangementEntry entry = createNewEntry(field.getTextRange(), ArrangementEntryType.FIELD, field.getName(), true);
processEntry(entry, field, field.getInitializer());
}
@Override
public void visitMethod(PsiMethod method) {
JavaElementArrangementEntry entry = createNewEntry(method.getTextRange(), ArrangementEntryType.METHOD, method.getName(), true);
processEntry(entry, method, method.getBody());
}
@Override
public void visitExpressionStatement(PsiExpressionStatement statement) {
statement.getExpression().acceptChildren(this);
}
@Override
public void visitNewExpression(PsiNewExpression expression) {
PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
if (anonymousClass == null) {
return;
}
JavaElementArrangementEntry entry =
createNewEntry(anonymousClass.getTextRange(), ArrangementEntryType.CLASS, anonymousClass.getName(), false);
processEntry(entry, null, anonymousClass);
}
@Override
public void visitExpressionList(PsiExpressionList list) {
for (PsiExpression expression : list.getExpressions()) {
expression.acceptChildren(this);
}
}
@Override
public void visitDeclarationStatement(PsiDeclarationStatement statement) {
for (PsiElement element : statement.getDeclaredElements()) {
element.acceptChildren(this);
}
}
private void processEntry(@Nullable JavaElementArrangementEntry entry,
@Nullable PsiModifierListOwner modifier,
@Nullable PsiElement nextPsiRoot)
{
if (entry == null) {
return;
}
if (modifier != null) {
parseModifiers(modifier.getModifierList(), entry);
}
if (nextPsiRoot == null) {
return;
}
myStack.push(entry);
try {
nextPsiRoot.acceptChildren(this);
}
finally {
myStack.pop();
}
}
@Nullable
private JavaElementArrangementEntry createNewEntry(@NotNull TextRange range,
@NotNull ArrangementEntryType type,
@Nullable String name,
boolean canArrange)
{
if (!isWithinBounds(range)) {
return null;
}
DefaultArrangementEntry current = getCurrent();
JavaElementArrangementEntry entry;
if (canArrange) {
TextRange expandedRange = ArrangementUtil.expandToLine(range, myDocument.getCharsSequence());
TextRange rangeToUse = expandedRange == null ? range : expandedRange;
entry = new JavaElementArrangementEntry(current, rangeToUse, type, name, expandedRange != null);
}
else {
entry = new JavaElementArrangementEntry(current, range, type, name, false);
}
if (current == null) {
myRootEntries.add(entry);
}
else {
current.addChild(entry);
}
return entry;
}
private boolean isWithinBounds(@NotNull TextRange range) {
for (TextRange textRange : myRanges) {
if (textRange.intersects(range)) {
return true;
}
}
return false;
}
@Nullable
private DefaultArrangementEntry getCurrent() {
return myStack.isEmpty() ? null : myStack.peek();
}
private static void parseModifiers(@Nullable PsiModifierList modifierList, @NotNull JavaElementArrangementEntry entry) {
if (modifierList == null) {
return;
}
for (String modifier : PsiModifier.MODIFIERS) {
if (modifierList.hasModifierProperty(modifier)) {
entry.addModifier(MODIFIERS.get(modifier));
}
}
}
}
@@ -0,0 +1,93 @@
/*
* Copyright 2000-2012 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 com.intellij.psi.codeStyle.arrangement;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.psi.codeStyle.arrangement.match.ModifierAwareArrangementEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.EnumSet;
import java.util.Set;
/**
* @author Denis Zhdanov
* @since 7/20/12 4:50 PM
*/
public class JavaElementArrangementEntry extends DefaultArrangementEntry
implements TypeAwareArrangementEntry, NameAwareArrangementEntry,ModifierAwareArrangementEntry
{
private final Set<ArrangementModifier> myModifiers = EnumSet.noneOf(ArrangementModifier.class);
@NotNull private final ArrangementEntryType myType;
@Nullable private final String myName;
public JavaElementArrangementEntry(@Nullable ArrangementEntry parent,
@NotNull TextRange range,
@NotNull ArrangementEntryType type,
@Nullable String name,
boolean canBeMatched)
{
this(parent, range.getStartOffset(), range.getEndOffset(), type, name, canBeMatched);
}
public JavaElementArrangementEntry(@Nullable ArrangementEntry parent,
int startOffset,
int endOffset,
@NotNull ArrangementEntryType type,
@Nullable String name,
boolean canBeArranged)
{
super(parent, startOffset, endOffset, canBeArranged);
myType = type;
myName = name;
}
@NotNull
@Override
public Set<ArrangementModifier> getModifiers() {
return myModifiers;
}
public void addModifier(@NotNull ArrangementModifier modifier) {
myModifiers.add(modifier);
}
@Nullable
@Override
public String getName() {
return myName;
}
@NotNull
@Override
public ArrangementEntryType getType() {
return myType;
}
@Override
public String toString() {
return String.format(
"[%d; %d): %s %s %s",
getStartOffset(), getEndOffset(), StringUtil.join(myModifiers, " ").toLowerCase(), myType.toString().toLowerCase(),
myName == null ? "<no name>" : myName
);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2012 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 com.intellij.psi.codeStyle.arrangement;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Denis Zhdanov
* @since 7/20/12 2:31 PM
*/
public class JavaRearranger implements Rearranger<JavaElementArrangementEntry> {
@NotNull
@Override
public Collection<JavaElementArrangementEntry> parse(@NotNull PsiElement root,
@NotNull Document document,
@NotNull Collection<TextRange> ranges)
{
// Following entries are subject to arrangement: class, interface, field, method.
List<JavaElementArrangementEntry> result = new ArrayList<JavaElementArrangementEntry>();
root.accept(new JavaArrangementVisitor(result, document, ranges));
return result;
}
}
@@ -7,6 +7,7 @@ import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -37,7 +38,7 @@ public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, Method
processConstructorReferences(consumer, method, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
}
if (method instanceof PsiAnnotationMethod &&
if (PsiUtil.isAnnotationMethod(method) &&
PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) &&
method.getParameterList().getParametersCount() == 0) {
ReferencesSearch.search(method.getContainingClass(), p.getScope()).forEach(PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -16,11 +16,14 @@
package com.intellij.psi.impl.source.codeStyle;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.jsp.JavaJspRecursiveElementVisitor;
import com.intellij.psi.jsp.JspFile;
@@ -96,13 +99,16 @@ public class BraceEnforcer extends JavaJspRecursiveElementVisitor {
private void processStatement(PsiStatement statement, PsiStatement blockCandidate, int options) {
if (blockCandidate instanceof PsiBlockStatement || blockCandidate == null) return;
if (options == CodeStyleSettings.FORCE_BRACES_ALWAYS ||
options == CodeStyleSettings.FORCE_BRACES_IF_MULTILINE && PostFormatProcessorHelper.isMultiline(statement)) {
replaceWithBlock(statement, blockCandidate);
boolean forceNewLine = !FormatterUtil.isFormatterCalledExplicitly() && !ApplicationManager.getApplication().isUnitTestMode();
if (forceNewLine
|| options == CommonCodeStyleSettings.FORCE_BRACES_ALWAYS
|| (options == CommonCodeStyleSettings.FORCE_BRACES_IF_MULTILINE && PostFormatProcessorHelper.isMultiline(statement)))
{
replaceWithBlock(statement, blockCandidate, forceNewLine);
}
}
private void replaceWithBlock(@NotNull PsiStatement statement, PsiStatement blockCandidate) {
private void replaceWithBlock(@NotNull PsiStatement statement, PsiStatement blockCandidate, boolean forceNewLine) {
if (!statement.isValid()) {
LOG.assertTrue(false);
}
@@ -123,7 +129,7 @@ public class BraceEnforcer extends JavaJspRecursiveElementVisitor {
int lastLineCommentIndex = oldText.indexOf("//", lastLineFeedIndex);
StringBuilder buf = new StringBuilder(oldText.length() + 5);
buf.append("{ ").append(oldText);
if (lastLineCommentIndex >= 0) {
if (forceNewLine || lastLineCommentIndex >= 0) {
buf.append("\n");
}
buf.append(" }");
@@ -17,88 +17,18 @@ package com.intellij.psi.impl.source.resolve;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import java.util.Arrays;
import java.util.List;
/**
* @author yole
*/
public class CompletionParameterTypeInferencePolicy extends ParameterTypeInferencePolicy {
public class CompletionParameterTypeInferencePolicy extends ProcessCandidateParameterTypeInferencePolicy {
public static final CompletionParameterTypeInferencePolicy INSTANCE = new CompletionParameterTypeInferencePolicy();
private CompletionParameterTypeInferencePolicy() {
}
@Override
public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall,
PsiExpressionList expressionList,
PsiCallExpression contextCall,
PsiTypeParameter typeParameter) {
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(contextCall);
try {
//can't call resolve() since it obtains full substitution, that may result in infinite recursion
PsiScopesUtil.setupAndRunProcessor(processor, contextCall, false);
PsiExpression[] expressions = expressionList.getExpressions();
int i = ArrayUtil.find(expressions, innerMethodCall);
assert i >= 0;
final JavaResolveResult[] results = processor.getResult();
PsiMethod owner = (PsiMethod)typeParameter.getOwner();
if (owner == null) return null;
final PsiType innerReturnType = owner.getReturnType();
for (final JavaResolveResult result : results) {
final PsiSubstitutor substitutor;
if (result instanceof MethodCandidateInfo) {
List<PsiExpression> leftArgs = Arrays.asList(expressions).subList(0, i);
substitutor = ((MethodCandidateInfo)result).inferTypeArguments(this, leftArgs.toArray(new PsiExpression[leftArgs.size()]));
} else {
substitutor = result.getSubstitutor();
}
final PsiElement element = result.getElement();
if (element instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)element;
final PsiParameter[] parameters = method.getParameterList().getParameters();
PsiParameter parameter = null;
if (parameters.length > i) {
parameter = parameters[i];
}
else if (method.isVarArgs()) {
parameter = parameters[parameters.length - 1];
}
if (parameter != null) {
final PsiParameter finalParameter = parameter;
PsiType type = PsiResolveHelperImpl.ourGuard.doPreventingRecursion(innerMethodCall, true, new Computable<PsiType>() {
@Override
public PsiType compute() {
return substitutor.substitute(finalParameter.getType());
}
});
final Pair<PsiType, ConstraintType> constraint =
PsiResolveHelperImpl.getSubstitutionForTypeParameterConstraint(typeParameter, innerReturnType, type, false,
PsiUtil.getLanguageLevel(innerMethodCall));
if (constraint != null) return constraint;
}
}
}
}
catch (MethodProcessorSetupFailedException ev) {
return null;
}
return null;
}
@Override
public PsiType getDefaultExpectedType(PsiCallExpression methodCall) {
ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(methodCall, true);
@@ -71,7 +71,7 @@ public class KnownElementWeigher extends ProximityWeigher {
}
private static Comparable getJdkClassProximity(@Nullable PsiClass element) {
if (element == null) {
if (element == null || element.getContainingClass() != null) {
return 0;
}
@@ -190,6 +190,23 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
}
}
final PsiReturnStatement[] returnStatements = RefactoringUtil.findReturnStatements(myMethod);
for (PsiReturnStatement statement : returnStatements) {
PsiExpression value = statement.getReturnValue();
if (value != null && !(value instanceof PsiCallExpression)) {
for (UsageInfo info : usagesIn) {
PsiReference reference = info.getReference();
if (reference != null) {
InlineUtil.TailCallType type = InlineUtil.getTailCallType(reference);
if (type == InlineUtil.TailCallType.Simple) {
conflicts.putValue(statement, "Inlined result won't be a valid statement");
break;
}
}
}
}
}
addInaccessibleMemberConflicts(myMethod, usagesIn, new ReferencedElementsCollector(), conflicts);
addInaccessibleSuperCallsConflicts(usagesIn, conflicts);
@@ -730,7 +747,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
if (returnValue == null) continue;
PsiStatement statement;
if (tailCallType == InlineUtil.TailCallType.Simple) {
if (returnValue instanceof PsiCallExpression) {
if (returnValue instanceof PsiExpression) {
PsiExpressionStatement exprStatement = (PsiExpressionStatement) myFactory.createStatementFromText("a;", null);
exprStatement.getExpression().replace(returnValue);
returnStatement.getParent().addBefore(exprStatement, returnStatement);
@@ -30,11 +30,9 @@ import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* @author ven
@@ -279,7 +277,7 @@ public class InlineUtil {
return result && nonTailCallUsages.isEmpty();
}
public static TailCallType getTailCallType(final PsiReference psiReference) {
public static TailCallType getTailCallType(@NotNull final PsiReference psiReference) {
PsiElement element = psiReference.getElement();
PsiExpression methodCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (methodCall == null) return TailCallType.None;
@@ -296,10 +294,11 @@ public class InlineUtil {
}
public static void substituteTypeParams(PsiElement scope, final PsiSubstitutor substitutor, final PsiElementFactory factory) {
final Map<PsiElement, PsiElement> replacement = new HashMap<PsiElement, PsiElement>();
scope.accept(new JavaRecursiveElementVisitor() {
@Override public void visitTypeElement(PsiTypeElement typeElement) {
super.visitTypeElement(typeElement);
PsiType type = typeElement.getType();
if (type instanceof PsiClassType) {
JavaResolveResult resolveResult = ((PsiClassType)type).resolveGenerics();
PsiElement resolved = resolveResult.getElement();
@@ -309,17 +308,20 @@ public class InlineUtil {
newType = PsiType.getJavaLangObject(resolved.getManager(), resolved.getResolveScope());
}
try {
typeElement.replace(factory.createTypeElement(newType));
return;
replacement.put(typeElement, factory.createTypeElement(newType));
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
super.visitTypeElement(typeElement);
}
});
for (PsiElement element : replacement.keySet()) {
if (element.isValid()) {
element.replace(replacement.get(element));
}
}
}
private static PsiElement replaceDiamondWithInferredTypesIfNeeded(PsiExpression initializer, PsiElement ref) {
@@ -27,10 +27,12 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.impl.content.BaseLabel;
import com.intellij.psi.*;
import com.intellij.refactoring.util.RefactoringDescriptionLocation;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.regex.Pattern;
@@ -118,7 +120,7 @@ public class SliceManager implements PersistentStateComponent<SliceManager.Store
public void slice(@NotNull PsiElement element, boolean dataFlowToThis, SliceHandler handler) {
String dialogTitle = getElementDescription((dataFlowToThis ? BACK_TOOLWINDOW_ID : FORTH_TOOLWINDOW_ID) + " ", element, null);
dialogTitle = Pattern.compile("<[^<>]*>").matcher(dialogTitle).replaceAll("");
dialogTitle = Pattern.compile("(<style>.*</style>)|<[^<>]*>").matcher(dialogTitle).replaceAll("");
SliceAnalysisParams params = handler.askForParams(element, dataFlowToThis, myStoredSettings, dialogTitle);
if (params == null) return;
@@ -172,7 +174,9 @@ public class SliceManager implements PersistentStateComponent<SliceManager.Store
if (element instanceof PsiReferenceExpression) elementToSlice = ((PsiReferenceExpression)element).resolve();
if (elementToSlice == null) elementToSlice = element;
String desc = ElementDescriptionUtil.getElementDescription(elementToSlice, RefactoringDescriptionLocation.WITHOUT_PARENT);
return "<html>"+ (prefix == null ? "" : prefix) + StringUtil.first(desc, 100, true)+(suffix == null ? "" : suffix) + "</html>";
return "<html><head>" + UIUtil.getCssFontDeclaration(BaseLabel.getLabelFont()) + "</head><body>" +
(prefix == null ? "" : prefix) + StringUtil.first(desc, 100, true)+(suffix == null ? "" : suffix) +
"</body></html>";
}
public static SliceUsage createRootUsage(@NotNull PsiElement element, @NotNull SliceAnalysisParams params) {
@@ -98,6 +98,8 @@ public class ThreadDumpPanel extends JPanel {
splitter.setSecondComponent(consoleView.getComponent());
add(splitter, BorderLayout.CENTER);
new ListSpeedSearch(myThreadList).setComparator(new SpeedSearchComparator(false, true));
}
private static Icon getThreadStateIcon(final ThreadState threadState) {