Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2016-04-26 14:28:44 +03:00
94 changed files with 1075 additions and 476 deletions
@@ -41,7 +41,6 @@ import java.util.Collections;
import java.util.stream.Collectors;
public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
@NotNull
@Override
public FileType getFileType() {
return JavaFileType.INSTANCE;
@@ -70,10 +69,9 @@ public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
@NotNull
@Override
public XExpression createExpression(@NotNull Project project, @NotNull Document document, @Nullable Language language, @NotNull EvaluationMode mode) {
PsiDocumentManager.getInstance(project).commitDocument(document);
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (psiFile != null) {
return new XExpressionImpl(psiFile.getText(), language, StringUtil.nullize(((JavaCodeFragment)psiFile).importsToString()), mode);
return new XExpressionImpl(document.getText(), language, StringUtil.nullize(((JavaCodeFragment)psiFile).importsToString()), mode);
}
return super.createExpression(project, document, language, mode);
}
@@ -270,16 +270,9 @@ public class JavaCompletionUtil {
final int parameterIndex = lambdaExpression.getParameterList().getParameterIndex((PsiParameter)resolve);
final Set<LookupElement> set = new LinkedHashSet<LookupElement>();
final boolean overloadsFound = LambdaUtil.processParentOverloads(lambdaExpression, functionalInterfaceType -> {
PsiType qualifierType = LambdaUtil.getLambdaParameterFromType(functionalInterfaceType, parameterIndex);
PsiType qualifierType = removeTopLevelWildcards(LambdaUtil.getLambdaParameterFromType(functionalInterfaceType, parameterIndex));
if (qualifierType == null) return;
if (qualifierType instanceof PsiWildcardType) {
PsiType bound = ((PsiWildcardType)qualifierType).getBound();
if (bound != null) {
qualifierType = bound;
}
}
PsiReferenceExpression fakeRef = createReference("xxx.xxx", createContextWithXxxVariable(element, qualifierType));
set.addAll(processJavaQualifiedReference(fakeRef.getReferenceNameElement(), fakeRef, elementFilter, options, matcher, parameters));
});
@@ -288,10 +281,21 @@ public class JavaCompletionUtil {
}
}
}
}
}
return processJavaQualifiedReference(element, javaReference, elementFilter, options, matcher, parameters);
}
@Nullable
private static PsiType removeTopLevelWildcards(@Nullable PsiType qualifierType) {
if (qualifierType instanceof PsiCapturedWildcardType) {
return removeTopLevelWildcards(((PsiCapturedWildcardType)qualifierType).getWildcard());
}
if (qualifierType instanceof PsiWildcardType) {
return removeTopLevelWildcards(((PsiWildcardType)qualifierType).getBound());
}
return qualifierType;
}
private static Set<LookupElement> processJavaQualifiedReference(PsiElement element, PsiJavaReference javaReference, ElementFilter elementFilter,
JavaCompletionProcessor.Options options,
final PrefixMatcher matcher, CompletionParameters parameters) {
@@ -16,6 +16,8 @@
package com.intellij.psi;
import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
@@ -51,6 +53,12 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
super(manager, file, eventSystemEnabled, JavaClassFileType.INSTANCE);
}
@NotNull
@Override
public Language getBaseLanguage() {
return JavaLanguage.INSTANCE;
}
@Override
protected PsiFile createFile(@NotNull Project project, @NotNull VirtualFile file, @NotNull FileType fileType) {
FileIndexFacade fileIndex = ServiceManager.getService(project, FileIndexFacade.class);
@@ -28,10 +28,7 @@ import com.intellij.psi.impl.source.ClassInnerStuffCache;
import com.intellij.psi.impl.source.PsiImmediateClassType;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.scope.ElementClassFilter;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.NameHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.scope.*;
import com.intellij.psi.scope.processor.FilterScopeProcessor;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
import com.intellij.psi.search.*;
@@ -42,7 +39,6 @@ import com.intellij.util.*;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -150,15 +146,9 @@ public class PsiClassImplUtil {
if (name == null) return Collections.emptyList();
if (checkBases) {
Map<String, Pair<PsiMember, PsiSubstitutor>[]> allMethodsMap = getMap(aClass, type);
Pair<PsiMember, PsiSubstitutor>[] list = allMethodsMap.get(name);
PsiMember[] list = getMap(aClass, type).get(name);
if (list == null) return Collections.emptyList();
List<PsiMember> ret = new ArrayList<PsiMember>(list.length);
for (final Pair<PsiMember, PsiSubstitutor> info : list) {
ret.add(info.getFirst());
}
return ret;
return Arrays.asList(list);
}
else {
PsiMember[] members = null;
@@ -186,10 +176,7 @@ public class PsiClassImplUtil {
@NotNull
public static <T extends PsiMember> List<Pair<T, PsiSubstitutor>> getAllWithSubstitutorsByMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
Map<String, Pair<PsiMember, PsiSubstitutor>[]> allMap = getMap(aClass, type);
Pair<PsiMember, PsiSubstitutor>[] pairs = allMap.get(ALL);
//noinspection unchecked
return Arrays.<Pair<T, PsiSubstitutor>>asList((Pair[])pairs);
return withSubstitutors(aClass, getMap(aClass, type).get(ALL));
}
@NotNull
@@ -211,7 +198,7 @@ public class PsiClassImplUtil {
public enum MemberType {CLASS, FIELD, METHOD}
private static Map<String, Pair<PsiMember, PsiSubstitutor>[]> getMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
private static Map<String, PsiMember[]> getMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
ParameterizedCachedValue<Map<GlobalSearchScope, MembersMap>, PsiClass> value = getValues(aClass);
return value.getValue(aClass).get(aClass.getResolveScope()).get(type);
}
@@ -358,7 +345,7 @@ public class PsiClassImplUtil {
return factory.createMethodFromText(text, null).getSignature(PsiSubstitutor.EMPTY);
}
private static class MembersMap extends ConcurrentFactoryMap<MemberType, Map<String, Pair<PsiMember, PsiSubstitutor>[]>> {
private static class MembersMap extends ConcurrentFactoryMap<MemberType, Map<String, PsiMember[]>> {
private final PsiClass myPsiClass;
private final GlobalSearchScope myResolveScope;
@@ -369,10 +356,10 @@ public class PsiClassImplUtil {
@Nullable
@Override
protected Map<String, Pair<PsiMember, PsiSubstitutor>[]> create(final MemberType key) {
final Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = new THashMap<String, List<Pair<PsiMember, PsiSubstitutor>>>();
protected Map<String, PsiMember[]> create(final MemberType key) {
final Map<String, List<PsiMember>> map = ContainerUtil.newTroveMap();
final List<Pair<PsiMember, PsiSubstitutor>> allMembers = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
final List<PsiMember> allMembers = ContainerUtil.newArrayList();
map.put(ALL, allMembers);
ElementClassFilter filter = key == MemberType.CLASS ? ElementClassFilter.CLASS :
@@ -392,15 +379,14 @@ public class PsiClassImplUtil {
if (key == MemberType.CLASS && element instanceof PsiClass ||
key == MemberType.METHOD && element instanceof PsiMethod ||
key == MemberType.FIELD && element instanceof PsiField) {
Pair<PsiMember, PsiSubstitutor> info = Pair.create((PsiMember)element, substitutor);
allMembers.add(info);
allMembers.add((PsiMember)element);
String currentName = ((PsiMember)element).getName();
List<Pair<PsiMember, PsiSubstitutor>> listByName = map.get(currentName);
List<PsiMember> listByName = map.get(currentName);
if (listByName == null) {
listByName = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(1);
listByName = ContainerUtil.newArrayList();
map.put(currentName, listByName);
}
listByName.add(info);
listByName.add((PsiMember)element);
}
}
@@ -413,10 +399,10 @@ public class PsiClassImplUtil {
processDeclarationsInClassNotCached(myPsiClass, processor, ResolveState.initial(), null, null, myPsiClass, false,
PsiUtil.getLanguageLevel(myPsiClass), myResolveScope);
Map<String, Pair<PsiMember, PsiSubstitutor>[]> result = ContainerUtil.newTroveMap();
Map<String, PsiMember[]> result = ContainerUtil.newTroveMap();
for (String name : map.keySet()) {
//noinspection unchecked
result.put(name, map.get(name).toArray(new Pair[0]));
result.put(name, map.get(name).toArray(PsiMember.EMPTY_ARRAY));
}
return result;
}
@@ -494,20 +480,32 @@ public class PsiClassImplUtil {
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, languageLevel, resolveScope);
}
private static boolean processCachedMembersByName(@NotNull PsiClass aClass,
private static boolean processCachedMembersByName(@NotNull final PsiClass aClass,
@NotNull PsiScopeProcessor processor,
@NotNull ResolveState state,
@Nullable Set<PsiClass> visited,
PsiElement last,
@NotNull PsiElement place,
boolean isRaw,
@NotNull PsiSubstitutor substitutor,
@NotNull final PsiElement place,
final boolean isRaw,
@NotNull final PsiSubstitutor substitutor,
@NotNull MembersMap value,
String name,
@NotNull LanguageLevel languageLevel) {
final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
@NotNull final LanguageLevel languageLevel) {
Function<PsiMember, PsiSubstitutor> finalSubstitutor = new Function<PsiMember, PsiSubstitutor>() {
final ScopedClassHierarchy hierarchy = ScopedClassHierarchy.getHierarchy(aClass, place.getResolveScope());
final PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
@Override
public PsiSubstitutor fun(PsiMember member) {
PsiClass containingClass = ObjectUtils.assertNotNull(member.getContainingClass());
PsiSubstitutor superSubstitutor = hierarchy.getSuperMembersSubstitutor(containingClass, languageLevel);
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass,
superSubstitutor == null ? PsiSubstitutor.EMPTY : superSubstitutor,
aClass, substitutor, factory, languageLevel);
return member instanceof PsiMethod ? checkRaw(isRaw, factory, (PsiMethod)member, finalSubstitutor) : finalSubstitutor;
}
};
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
final PsiField fieldByName = aClass.findFieldByName(name, false);
@@ -516,23 +514,20 @@ public class PsiClassImplUtil {
if (!processor.execute(fieldByName, state)) return false;
}
else {
final Map<String, Pair<PsiMember, PsiSubstitutor>[]> allFieldsMap = value.get(MemberType.FIELD);
final Map<String, PsiMember[]> allFieldsMap = value.get(MemberType.FIELD);
final Pair<PsiMember, PsiSubstitutor>[] list = allFieldsMap.get(name);
final PsiMember[] list = allFieldsMap.get(name);
if (list != null) {
boolean resolved = false;
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
PsiMember candidateField = candidate.getFirst();
for (final PsiMember candidateField : list) {
PsiClass containingClass = candidateField.getContainingClass();
if (containingClass == null) {
LOG.error("No class for field " + candidateField.getName() + " of " + candidateField.getClass());
continue;
}
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, factory, languageLevel);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) {
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor.fun(candidateField)))) {
resolved = true;
}
}
@@ -556,19 +551,16 @@ public class PsiClassImplUtil {
if (!processor.execute(classByName, state)) return false;
}
else {
Map<String, Pair<PsiMember, PsiSubstitutor>[]> allClassesMap = value.get(MemberType.CLASS);
Map<String, PsiMember[]> allClassesMap = value.get(MemberType.CLASS);
Pair<PsiMember, PsiSubstitutor>[] list = allClassesMap.get(name);
PsiMember[] list = allClassesMap.get(name);
if (list != null) {
boolean resolved = false;
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
PsiMember inner = candidate.getFirst();
for (final PsiMember inner : list) {
PsiClass containingClass = inner.getContainingClass();
if (containingClass != null) {
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, factory, languageLevel);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor))) {
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor.fun(inner)))) {
resolved = true;
}
}
@@ -590,13 +582,13 @@ public class PsiClassImplUtil {
return true;
}
}
Map<String, Pair<PsiMember, PsiSubstitutor>[]> allMethodsMap = value.get(MemberType.METHOD);
Pair<PsiMember, PsiSubstitutor>[] list = allMethodsMap.get(name);
Map<String, PsiMember[]> allMethodsMap = value.get(MemberType.METHOD);
PsiMember[] list = allMethodsMap.get(name);
if (list != null) {
boolean resolved = false;
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
for (final PsiMember candidate : list) {
ProgressIndicatorProvider.checkCanceled();
PsiMethod candidateMethod = (PsiMethod)candidate.getFirst();
PsiMethod candidateMethod = (PsiMethod)candidate;
if (processor instanceof MethodResolverProcessor) {
if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
}
@@ -605,19 +597,16 @@ public class PsiClassImplUtil {
continue;
}
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, factory, languageLevel);
finalSubstitutor = checkRaw(isRaw, factory, candidateMethod, finalSubstitutor);
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor))) {
if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor.fun(candidateMethod)))) {
resolved = true;
}
}
if (resolved) return false;
if (visited != null) {
for (Pair<PsiMember, PsiSubstitutor> aList : list) {
visited.add(aList.getFirst().getContainingClass());
for (PsiMember aList : list) {
visited.add(aList.getContainingClass());
}
}
}
@@ -658,14 +647,14 @@ public class PsiClassImplUtil {
}
private static boolean processDeclarationsInClassNotCached(@NotNull PsiClass aClass,
@NotNull PsiScopeProcessor processor,
@NotNull ResolveState state,
@NotNull final PsiScopeProcessor processor,
@NotNull final ResolveState state,
@Nullable Set<PsiClass> visited,
PsiElement last,
@NotNull PsiElement place,
boolean isRaw,
@NotNull LanguageLevel languageLevel,
@NotNull GlobalSearchScope resolveScope) {
final PsiElement last,
@NotNull final PsiElement place,
final boolean isRaw,
@NotNull final LanguageLevel languageLevel,
@NotNull final GlobalSearchScope resolveScope) {
if (visited == null) visited = new THashSet<PsiClass>();
if (!visited.add(aClass)) return true;
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
@@ -722,8 +711,16 @@ public class PsiClassImplUtil {
}
}
return last instanceof PsiReferenceList || processSuperTypes(aClass, processor, visited, last, place, state, isRaw, factory,
languageLevel, resolveScope);
if (last instanceof PsiReferenceList) return true;
final Set<PsiClass> visited1 = visited;
return processSuperTypes(aClass, state.get(PsiSubstitutor.KEY), factory, languageLevel, resolveScope, new PairProcessor<PsiClass, PsiSubstitutor>() {
@Override
public boolean process(PsiClass superClass, PsiSubstitutor finalSubstitutor) {
return processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited1, last, place,
languageLevel, isRaw, resolveScope);
}
});
}
@Nullable
@@ -739,23 +736,19 @@ public class PsiClassImplUtil {
return ScopedClassHierarchy.getHierarchy(aClass, resolveScope).getImmediateSupersWithCapturing();
}
private static boolean processSuperTypes(@NotNull PsiClass aClass,
@NotNull PsiScopeProcessor processor,
@Nullable Set<PsiClass> visited,
PsiElement last,
@NotNull PsiElement place,
@NotNull ResolveState state,
boolean isRaw,
@NotNull PsiElementFactory factory,
@NotNull LanguageLevel languageLevel, GlobalSearchScope resolveScope) {
static boolean processSuperTypes(@NotNull PsiClass aClass,
PsiSubstitutor substitutor,
@NotNull PsiElementFactory factory,
@NotNull LanguageLevel languageLevel,
GlobalSearchScope resolveScope,
PairProcessor<PsiClass, PsiSubstitutor> processor) {
boolean resolved = false;
for (PsiClassType.ClassResolveResult superTypeResolveResult : getScopeCorrectedSuperTypes(aClass, resolveScope)) {
PsiClass superClass = superTypeResolveResult.getElement();
assert superClass != null;
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass,
state.get(PsiSubstitutor.KEY), factory, languageLevel);
if (!processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited, last, place,
languageLevel, isRaw, resolveScope)) {
substitutor, factory, languageLevel);
if (!processor.process(superClass, finalSubstitutor)) {
resolved = true;
}
}
@@ -986,11 +979,24 @@ public class PsiClassImplUtil {
}
return ret;
}
Pair<PsiMember, PsiSubstitutor>[] list = getMap(psiClass, MemberType.METHOD).get(name);
//noinspection unchecked
return list == null ?
Collections.<Pair<PsiMethod, PsiSubstitutor>>emptyList() :
Arrays.<Pair<PsiMember, PsiSubstitutor>>asList((Pair[])list);
PsiMember[] list = getMap(psiClass, MemberType.METHOD).get(name);
if (list == null) return Collections.emptyList();
return withSubstitutors(psiClass, list);
}
@NotNull
private static <T extends PsiMember> List<Pair<T, PsiSubstitutor>> withSubstitutors(@NotNull final PsiClass psiClass, PsiMember[] members) {
final ScopedClassHierarchy hierarchy = ScopedClassHierarchy.getHierarchy(psiClass, psiClass.getResolveScope());
final LanguageLevel level = PsiUtil.getLanguageLevel(psiClass);
return ContainerUtil.map(members, new Function<PsiMember, Pair<T, PsiSubstitutor>>() {
@Override
public Pair<T, PsiSubstitutor> fun(PsiMember member) {
PsiClass containingClass = member.getContainingClass();
PsiSubstitutor substitutor = containingClass == null ? null : hierarchy.getSuperMembersSubstitutor(containingClass, level);
//noinspection unchecked
return Pair.create((T)member, substitutor == null ? PsiSubstitutor.EMPTY : substitutor);
}
});
}
@NotNull
@@ -18,6 +18,7 @@ package com.intellij.psi.impl;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchScopeUtil;
@@ -25,8 +26,10 @@ import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.PairProcessor;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,6 +64,14 @@ class ScopedClassHierarchy {
private final GlobalSearchScope myResolveScope;
private volatile Map<PsiClass, PsiClassType.ClassResolveResult> mySupersWithSubstitutors;
private volatile List<PsiClassType.ClassResolveResult> myImmediateSupersWithCapturing;
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final Map<LanguageLevel, Map<PsiClass, PsiSubstitutor>> myAllSupersWithCapturing = new ConcurrentFactoryMap<LanguageLevel, Map<PsiClass, PsiSubstitutor>>() {
@Nullable
@Override
protected Map<PsiClass, PsiSubstitutor> create(LanguageLevel key) {
return calcAllMemberSupers(key);
}
};
private ScopedClassHierarchy(PsiClass psiClass, GlobalSearchScope resolveScope) {
myPlaceClass = psiClass;
@@ -171,4 +182,26 @@ class ScopedClassHierarchy {
}
return list;
}
@NotNull
private Map<PsiClass, PsiSubstitutor> calcAllMemberSupers(final LanguageLevel level) {
final Map<PsiClass, PsiSubstitutor> map = ContainerUtil.newTroveMap();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myPlaceClass.getProject());
new PairProcessor<PsiClass, PsiSubstitutor>() {
@Override
public boolean process(PsiClass eachClass, PsiSubstitutor eachSubstitutor) {
if (!map.containsKey(eachClass)) {
map.put(eachClass, eachSubstitutor);
PsiClassImplUtil.processSuperTypes(eachClass, eachSubstitutor, factory, level, myResolveScope, this);
}
return true;
}
}.process(myPlaceClass, PsiSubstitutor.EMPTY);
return map;
}
@Nullable
PsiSubstitutor getSuperMembersSubstitutor(@NotNull PsiClass superClass, @NotNull LanguageLevel level) {
return myAllSupersWithCapturing.get(level).get(superClass);
}
}
@@ -0,0 +1,8 @@
import java.util.stream.*;
import java.util.*;
class Foo {
void main(Stream<? super String> stream) {
stream.collect(Collectors.toMap(o -> o.sub<caret>))
}
}
@@ -244,6 +244,10 @@ class Test88 {
configureByTestName()
myFixture.assertPreferredCompletionItems(0, 'substring', 'substring', 'subSequence')
}
public void testLambdaWithCapturedSuperWildcardInAmbiguousCall() {
configureByTestName()
myFixture.assertPreferredCompletionItems(0, 'substring', 'substring', 'subSequence')
}
public void testUnexpectedLambdaInAmbiguousCall() { doAntiTest() }
public void testNoCollectorsInComment() { doAntiTest() }
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.IoTestUtil;
@@ -100,6 +101,12 @@ public class ClsPsiTest extends LightIdeaTestCase {
assertFalse(aClass.isDeprecated());
}
public void testViewProviderHasJavaLanguage() {
PsiJavaFile file = getFile("MyClass");
assertEquals(JavaLanguage.INSTANCE, file.getLanguage());
assertEquals(JavaLanguage.INSTANCE, file.getViewProvider().getBaseLanguage());
}
public void testClassMembers() {
PsiClass aClass = getFile("MyClass").getClasses()[0];
@@ -26,6 +26,7 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.OrderEnumerator;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.impl.ResolveScopeManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.ModuleTestCase;
import com.intellij.testFramework.PsiTestUtil;
@@ -309,4 +310,23 @@ public class ModuleScopesTest extends ModuleTestCase {
assertEquals(deps, deps2);
assertEquals(depsTests, depsTests2);
}
public void testHonorExportsWhenCalculatingLibraryScope() throws IOException {
Module a = createModule("a.iml", StdModuleTypes.JAVA);
Module b = createModule("b.iml", StdModuleTypes.JAVA);
Module c = createModule("c.iml", StdModuleTypes.JAVA);
ModuleRootModificationUtil.addDependency(a, b, DependencyScope.COMPILE, true);
ModuleRootModificationUtil.addDependency(b, c, DependencyScope.COMPILE, true);
final VirtualFile libFile1 = myFixture.createFile("lib1/a.txt", "");
final VirtualFile libFile2 = myFixture.createFile("lib2/a.txt", "");
ModuleRootModificationUtil.addModuleLibrary(a, "l", Collections.singletonList(libFile1.getParent().getUrl()),
Collections.emptyList(), Collections.emptyList(), DependencyScope.COMPILE, true);
ModuleRootModificationUtil.addModuleLibrary(c, "l", Collections.singletonList(libFile2.getParent().getUrl()),
Collections.emptyList(), Collections.emptyList(), DependencyScope.COMPILE, true);
assertTrue(ResolveScopeManager.getElementResolveScope(getPsiManager().findFile(libFile1)).contains(libFile2));
assertTrue(ResolveScopeManager.getElementResolveScope(getPsiManager().findFile(libFile2)).contains(libFile1));
}
}
@@ -19,6 +19,7 @@ import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -33,6 +34,7 @@ import java.util.Collections;
import java.util.List;
public class TextEditorBackgroundHighlighter implements BackgroundEditorHighlighter {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.TextEditorBackgroundHighlighter");
private static final int[] EXCEPT_OVERRIDDEN = {
Pass.UPDATE_FOLDING,
Pass.POPUP_HINTS,
@@ -75,7 +77,7 @@ public class TextEditorBackgroundHighlighter implements BackgroundEditorHighligh
@NotNull
List<TextEditorHighlightingPass> getPasses(@NotNull int[] passesToIgnore) {
if (myProject.isDisposed()) return Collections.emptyList();
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
LOG.assertTrue(!PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments());
renewFile();
if (myFile == null) return Collections.emptyList();
if (myCompiled) {
@@ -293,12 +293,12 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
}
public List<PsiFile> getCachedPsiFiles() {
return ContainerUtil.createMaybeSingletonList(getCachedPsi(myBaseLanguage));
return ContainerUtil.createMaybeSingletonList(getCachedPsi(getBaseLanguage()));
}
@NotNull
public List<FileElement> getKnownTreeRoots() {
PsiFile psiFile = getCachedPsi(myBaseLanguage);
PsiFile psiFile = getCachedPsi(getBaseLanguage());
if (!(psiFile instanceof PsiFileImpl)) return Collections.emptyList();
FileElement element = ((PsiFileImpl)psiFile).getTreeElement();
return ContainerUtil.createMaybeSingletonList(element);
@@ -457,7 +457,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
@NotNull
@Override
public SingleRootFileViewProvider createCopy(@NotNull final VirtualFile copy) {
return new SingleRootFileViewProvider(getManager(), copy, false, myBaseLanguage);
return new SingleRootFileViewProvider(getManager(), copy, false, getBaseLanguage());
}
@Override
@@ -572,7 +572,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
}
public void markInvalidated() {
PsiFile psiFile = getCachedPsi(myBaseLanguage);
PsiFile psiFile = getCachedPsi(getBaseLanguage());
if (psiFile instanceof PsiFileEx) {
((PsiFileEx)psiFile).markInvalidated();
}
@@ -15,9 +15,10 @@
*/
package com.intellij.diff.actions;
import com.intellij.diff.util.DiffUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.TextEditor;
@@ -35,6 +36,7 @@ public class ProxyUndoRedoAction extends DumbAwareAction {
private final boolean myUndo;
private ProxyUndoRedoAction(@NotNull UndoManager manager, @NotNull TextEditor editor, boolean undo) {
ActionUtil.copyFrom(this, undo ? IdeActions.ACTION_UNDO : IdeActions.ACTION_REDO);
myUndoManager = manager;
myEditor = editor;
myUndo = undo;
@@ -44,8 +46,8 @@ public class ProxyUndoRedoAction extends DumbAwareAction {
UndoManager undoManager = project != null ? UndoManager.getInstance(project) : UndoManager.getGlobalInstance();
TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
if (undoManager != null) {
EmptyAction.setupAction(new ProxyUndoRedoAction(undoManager, textEditor, true), IdeActions.ACTION_UNDO, component);
EmptyAction.setupAction(new ProxyUndoRedoAction(undoManager, textEditor, false), IdeActions.ACTION_REDO, component);
DiffUtil.registerAction(new ProxyUndoRedoAction(undoManager, textEditor, true), component);
DiffUtil.registerAction(new ProxyUndoRedoAction(undoManager, textEditor, false), component);
}
}
@@ -17,7 +17,7 @@ package com.intellij.diff.actions.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.NotNull;
@@ -34,7 +34,7 @@ public class FocusOppositePaneAction extends AnAction implements DumbAware {
myScrollToPosition = scrollToPosition;
setEnabledInModalContext(true);
EmptyAction.setupAction(this, getActionId(), null);
ActionUtil.copyFrom(this, getActionId());
}
@Override
@@ -16,12 +16,12 @@
package com.intellij.diff.actions.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.project.DumbAware;
public abstract class GoToChangePopupAction extends AnAction implements DumbAware {
public GoToChangePopupAction() {
setEnabledInModalContext(true);
EmptyAction.setupAction(this, "GotoChangedFile", null);
ActionUtil.copyFrom(this, "GotoChangedFile");
}
}
@@ -16,12 +16,12 @@
package com.intellij.diff.actions.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.project.DumbAware;
public abstract class NextChangeAction extends AnAction implements DumbAware {
public NextChangeAction() {
setEnabledInModalContext(true);
EmptyAction.setupAction(this, "Diff.NextChange", null);
ActionUtil.copyFrom(this, "Diff.NextChange");
}
}
@@ -16,13 +16,13 @@
package com.intellij.diff.actions.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.project.DumbAware;
public abstract class NextDifferenceAction extends AnAction implements DumbAware {
public NextDifferenceAction() {
setEnabledInModalContext(true);
EmptyAction.setupAction(this, IdeActions.ACTION_NEXT_DIFF, null);
ActionUtil.copyFrom(this, IdeActions.ACTION_NEXT_DIFF);
}
}
@@ -24,7 +24,7 @@ import com.intellij.ide.actions.EditSourceAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.DumbAware;
@@ -38,7 +38,7 @@ public class OpenInEditorAction extends EditSourceAction implements DumbAware {
@Nullable private final Runnable myAfterRunnable;
public OpenInEditorAction(@Nullable Runnable afterRunnable) {
EmptyAction.setupAction(this, "EditSource", null);
ActionUtil.copyFrom(this, "EditSource");
myAfterRunnable = afterRunnable;
}
@@ -16,12 +16,12 @@
package com.intellij.diff.actions.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.project.DumbAware;
public abstract class PrevChangeAction extends AnAction implements DumbAware {
public PrevChangeAction() {
setEnabledInModalContext(true);
EmptyAction.setupAction(this, "Diff.PrevChange", null);
ActionUtil.copyFrom(this, "Diff.PrevChange");
}
}
@@ -16,13 +16,13 @@
package com.intellij.diff.actions.impl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.project.DumbAware;
public abstract class PrevDifferenceAction extends AnAction implements DumbAware {
public PrevDifferenceAction() {
setEnabledInModalContext(true);
EmptyAction.setupAction(this, IdeActions.ACTION_PREVIOUS_DIFF, null);
ActionUtil.copyFrom(this, IdeActions.ACTION_PREVIOUS_DIFF);
}
}
@@ -19,6 +19,7 @@ import com.intellij.diff.tools.util.base.HighlightingLevel;
import com.intellij.diff.tools.util.base.TextDiffSettingsHolder;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.editor.impl.EditorImpl;
@@ -159,7 +160,7 @@ public class SetEditorSettingsAction extends ActionGroup implements DumbAware {
private abstract class EditorSettingToggleAction extends ToggleAction implements DumbAware, EditorSettingAction {
private EditorSettingToggleAction(@NotNull String actionId) {
EmptyAction.setupAction(this, actionId, null);
ActionUtil.copyFrom(this, actionId);
}
@Override
@@ -510,7 +510,7 @@ public abstract class DiffRequestProcessor implements Disposable {
private class ShowInExternalToolAction extends DumbAwareAction {
public ShowInExternalToolAction() {
EmptyAction.setupAction(this, "Diff.ShowInExternalTool", null);
ActionUtil.copyFrom(this, "Diff.ShowInExternalTool");
}
@Override
@@ -595,7 +595,7 @@ public abstract class DiffRequestProcessor implements Disposable {
private class ShowActionGroupPopupAction extends DumbAwareAction {
public ShowActionGroupPopupAction() {
EmptyAction.setupAction(this, "Diff.ShowSettingsPopup", null);
ActionUtil.copyFrom(this, "Diff.ShowSettingsPopup");
}
@Override
@@ -35,6 +35,7 @@ import com.intellij.diff.tools.util.base.TextDiffViewerUtil;
import com.intellij.diff.util.*;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ReadAction;
@@ -1161,7 +1162,7 @@ public class TextMergeViewer implements MergeTool.MergeViewer {
public IgnoreSelectedChangesSideAction(@NotNull Side side, boolean shortcut) {
super(shortcut);
mySide = side;
EmptyAction.setupAction(this, mySide.select("Diff.IgnoreLeftSide", "Diff.IgnoreRightSide"), null);
ActionUtil.copyFrom(this, mySide.select("Diff.IgnoreLeftSide", "Diff.IgnoreRightSide"));
}
@Override
@@ -1222,7 +1223,7 @@ public class TextMergeViewer implements MergeTool.MergeViewer {
public ApplySelectedChangesAction(@NotNull Side side, boolean shortcut) {
super(shortcut);
mySide = side;
EmptyAction.setupAction(this, mySide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide"), null);
ActionUtil.copyFrom(this, mySide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide"));
}
@Override
@@ -26,7 +26,7 @@ import com.intellij.diff.util.DiffDividerDrawUtil.DividerPaintable;
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.editor.Editor;
@@ -266,7 +266,7 @@ public abstract class ThreesideTextDiffViewerEx extends ThreesideTextDiffViewer
private class PrevConflictAction extends DumbAwareAction {
public PrevConflictAction() {
EmptyAction.setupAction(this, "Diff.PreviousConflict", null);
ActionUtil.copyFrom(this, "Diff.PreviousConflict");
}
@Override
@@ -278,7 +278,7 @@ public abstract class ThreesideTextDiffViewerEx extends ThreesideTextDiffViewer
private class NextConflictAction extends DumbAwareAction {
public NextConflictAction() {
EmptyAction.setupAction(this, "Diff.NextConflict", null);
ActionUtil.copyFrom(this, "Diff.NextConflict");
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.openapi.diff.impl.dir.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
/**
@@ -25,7 +25,7 @@ import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
public class EnableEqual extends DirDiffAction {
public EnableEqual(DirDiffTableModel model) {
super(model);
EmptyAction.setupAction(this, "DirDiffMenu.EnableEqual", null);
ActionUtil.copyFrom(this, "DirDiffMenu.EnableEqual");
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.openapi.diff.impl.dir.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
/**
@@ -25,7 +25,7 @@ import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
public class EnableLeft extends DirDiffAction {
protected EnableLeft(DirDiffTableModel model) {
super(model);
EmptyAction.setupAction(this, "DirDiffMenu.EnableLeft", null);
ActionUtil.copyFrom(this, "DirDiffMenu.EnableLeft");
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.openapi.diff.impl.dir.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
/**
@@ -25,7 +25,7 @@ import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
public class EnableNotEqual extends DirDiffAction {
protected EnableNotEqual(DirDiffTableModel model) {
super(model);
EmptyAction.setupAction(this, "DirDiffMenu.EnableNotEqual", null);
ActionUtil.copyFrom(this, "DirDiffMenu.EnableNotEqual");
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.openapi.diff.impl.dir.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
/**
@@ -25,7 +25,7 @@ import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
public class EnableRight extends DirDiffAction {
protected EnableRight(DirDiffTableModel model) {
super(model);
EmptyAction.setupAction(this, "DirDiffMenu.EnableRight", null);
ActionUtil.copyFrom(this, "DirDiffMenu.EnableRight");
}
@Override
@@ -20,6 +20,7 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.project.Project;
@@ -34,7 +35,6 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerEx;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -115,12 +115,7 @@ public abstract class DvcsPlatformFacadeImpl implements DvcsPlatformFacade {
@Override
public void saveAllDocuments() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
FileDocumentManager.getInstance().saveAllDocuments();
}
});
TransactionGuard.getInstance().submitTransactionAndWait(() -> FileDocumentManager.getInstance().saveAllDocuments());
}
@NotNull
@@ -164,15 +164,23 @@ public class InitialConfigurationDialog extends DialogWrapper {
final boolean canCreateLauncherScript = canCreateLauncherScript();
myCreateScriptPanel.setVisible(canCreateLauncherScript);
myCreateScriptCheckbox.setVisible(canCreateLauncherScript);
myCreateScriptCheckbox.setSelected(false);
if (canCreateLauncherScript) {
myScriptPathTextField.setText(CreateLauncherScriptAction.defaultScriptPath());
myScriptPathTextField.setEnabled(false);
myCreateScriptCheckbox.addChangeListener(e -> myScriptPathTextField.setEnabled(myCreateScriptCheckbox.isSelected()));
}
final boolean canCreateDesktopEntry = canCreateDesktopEntry();
myCreateEntryPanel.setVisible(canCreateDesktopEntry);
myCreateEntryCheckBox.setVisible(canCreateDesktopEntry);
myCreateEntryCheckBox.setSelected(canCreateDesktopEntry);
myGlobalEntryCheckBox.setSelected(false);
if (canCreateDesktopEntry) {
myGlobalEntryCheckBox.setEnabled(true);
myCreateEntryCheckBox.addChangeListener(e -> myGlobalEntryCheckBox.setEnabled(myCreateEntryCheckBox.isSelected()));
}
myPreferencesLabel.setText("You can use " + CommonBundle.settingsActionPath() + " to configure any of these settings later.");
@@ -75,6 +75,9 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
myEnvVars.setData(envData);
}
/**
* Consider using {@link EnvironmentVariablesData#readExternal(Element)} instead for simplicity and better performance.
*/
public static void readExternal(Element element, Map<String, String> envs) {
final Element envsElement = element.getChild(ENVS);
if (envsElement != null) {
@@ -108,6 +111,9 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
}
}
/**
* Consider using {@link EnvironmentVariablesData#writeExternal(Element)} instead for simplicity and better performance.
*/
public static void writeExternal(@NotNull Element element, @NotNull Map<String, String> envs) {
final Element envsElement = new Element(ENVS);
for (String envName : envs.keySet()) {
@@ -35,7 +35,7 @@ import java.util.Map;
*/
public class EnvironmentVariablesData {
public static final EnvironmentVariablesData DEFAULT = new EnvironmentVariablesData(ImmutableMap.<String, String>of(), true);
public static final EnvironmentVariablesData DEFAULT = new EnvironmentVariablesData(ImmutableMap.of(), true);
@NonNls private static final String ENVS = "envs";
@NonNls private static final String PASS_PARENT_ENVS = "pass-parent-envs";
@NonNls private static final String ENV = EnvironmentVariablesComponent.ENV;
@@ -77,6 +77,11 @@ public class EnvironmentVariablesData {
return result;
}
@Override
public String toString() {
return "envs=" + myEnvs + ", passParentEnvs=" + myPassParentEnvs;
}
@NotNull
public static EnvironmentVariablesData readExternal(@NotNull Element element) {
Element envsElement = element.getChild(ENVS);
@@ -15,11 +15,11 @@
*/
package com.intellij.util;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -86,27 +86,18 @@ public class SequentialModalProgressTask extends Task.Modal {
task.stop();
break;
}
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
long start = System.currentTimeMillis();
try {
while (!task.isDone() && System.currentTimeMillis() - start < myMinIterationTime) {
task.iteration();
}
}
catch (RuntimeException e) {
task.stop();
throw e;
ApplicationManager.getApplication().invokeAndWait(() -> {
long start = System.currentTimeMillis();
try {
while (!task.isDone() && System.currentTimeMillis() - start < myMinIterationTime) {
task.iteration();
}
}
});
//if (ApplicationManager.getApplication().isDispatchThread()) {
// runnable.run();
//}
//else {
// ApplicationManagerEx.getApplicationEx().suspendReadAccessAndRunWriteAction(runnable);
//}
catch (RuntimeException e) {
task.stop();
throw e;
}
}, indicator.getModalityState());
}
}
@@ -68,6 +68,7 @@ public class CustomizeDesktopEntryStep extends AbstractCustomizeWizardStep {
myCreateEntryCheckBox.setSelected(!"true".equals(System.getProperty("idea.debug.mode")));
myGlobalEntryCheckBox.setSelected(false);
myGlobalEntryCheckBox.setEnabled(myCreateEntryCheckBox.isSelected());
}
@Override
@@ -40,6 +40,7 @@ public class CustomizeLauncherScriptStep extends AbstractCustomizeWizardStep {
myCreateScriptCheckBox.setSelected(false);
myCreateScriptCheckBox.addChangeListener(e -> myScriptPathTextField.setEnabled(myCreateScriptCheckBox.isSelected()));
myScriptPathTextField.setEnabled(false);
myScriptPathTextField.setText(CreateLauncherScriptAction.defaultScriptPath());
JPanel content = new JPanel(createSmallBorderLayout());
@@ -454,11 +454,10 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
@Override
protected void createComponents(@Nullable final ProgressIndicator indicator) {
protected void createComponents(@Nullable ProgressIndicator indicator) {
// we cannot wrap "init()" call because ProgressManager instance could be created only after component registration (our "componentsRegistered" callback)
Runnable task = () -> ApplicationImpl.super.createComponents(indicator);
if (indicator == null) {
// no splash, no need to to use progress manager
task.run();
@@ -25,7 +25,7 @@ import com.intellij.util.ui.JBInsets;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.JComponent;
import javax.swing.*;
import java.awt.*;
import java.util.IdentityHashMap;
import java.util.Iterator;
@@ -137,7 +137,7 @@ public abstract class CardLayoutPanel<K, UI, V extends Component> extends JCompo
}
else callback.setRejected();
}
}, ModalityState.any());
}, ModalityState.stateForComponent(CardLayoutPanel.this));
}
else callback.setRejected();
}
@@ -20,6 +20,8 @@ import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.util.text.StringUtil;
@@ -43,8 +45,10 @@ import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
public class ListPopupImpl extends WizardPopup implements ListPopup {
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.list.ListPopupImpl");
private MyList myList;
@@ -376,15 +380,27 @@ public class ListPopupImpl extends WizardPopup implements ListPopup {
valuesSelected(selectedValues);
AtomicBoolean insideOnChosen = new AtomicBoolean(true);
ApplicationManager.getApplication().invokeLater(() -> {
if (insideOnChosen.get()) {
LOG.error("Showing dialogs from popup onChosen can result in focus issues. Please put the handler into BaseStep.doFinalStep or PopupStep.getFinalRunnable.");
}
}, ModalityState.any());
final PopupStep nextStep;
if (listStep instanceof MultiSelectionListPopupStep<?>) {
nextStep = ((MultiSelectionListPopupStep<Object>)listStep).onChosen(Arrays.asList(selectedValues), handleFinalChoices);
try {
if (listStep instanceof MultiSelectionListPopupStep<?>) {
nextStep = ((MultiSelectionListPopupStep<Object>)listStep).onChosen(Arrays.asList(selectedValues), handleFinalChoices);
}
else if (e != null && listStep instanceof ListPopupStepEx<?>) {
nextStep = ((ListPopupStepEx<Object>)listStep).onChosen(selectedValues[0], handleFinalChoices, e.getModifiers());
}
else {
nextStep = listStep.onChosen(selectedValues[0], handleFinalChoices);
}
}
else if (e != null && listStep instanceof ListPopupStepEx<?>) {
nextStep = ((ListPopupStepEx<Object>)listStep).onChosen(selectedValues[0], handleFinalChoices, e.getModifiers());
}
else {
nextStep = listStep.onChosen(selectedValues[0], handleFinalChoices);
finally {
insideOnChosen.set(false);
}
return handleNextStep(nextStep, selectedValues.length == 1 ? selectedValues[0] : null, e);
}
@@ -18,6 +18,9 @@ package com.intellij.ui.popup.tree;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.treeView.AlphaComparator;
import com.intellij.ide.util.treeView.NodeRenderer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.PopupStep;
@@ -41,8 +44,10 @@ import java.awt.event.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class TreePopupImpl extends WizardPopup implements TreePopup {
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.tree.TreePopupImpl");
private MyTree myWizardTree;
private MouseMotionListener myMouseMotionListener;
@@ -349,7 +354,20 @@ public class TreePopupImpl extends WizardPopup implements TreePopup {
return;
}
final PopupStep queriedStep = myStep.onChosen(userObject, handleFinalChoices);
AtomicBoolean insideOnChosen = new AtomicBoolean(true);
ApplicationManager.getApplication().invokeLater(() -> {
if (insideOnChosen.get()) {
LOG.error("Showing dialogs from popup onChosen can result in focus issues. Please put the handler into BaseStep.doFinalStep or PopupStep.getFinalRunnable.");
}
}, ModalityState.any());
final PopupStep queriedStep;
try {
queriedStep = myStep.onChosen(userObject, handleFinalChoices);
}
finally {
insideOnChosen.set(false);
}
if (queriedStep == PopupStep.FINAL_CHOICE || !hasNextStep) {
setFinalRunnable(myStep.getFinalRunnable());
setOk(true);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -23,9 +23,10 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.testFramework.PlatformTestCase;
import java.io.File;
import java.io.IOException;
public class LocatorTest extends PlatformTestCase {
public void test() throws Exception {
public void test() throws IOException {
File locatorFile = new File(PathManager.getSystemPath() + "/" + ApplicationEx.LOCATOR_FILE_NAME);
assertTrue("doesn't exist: " + locatorFile.getPath(), locatorFile.exists());
assertTrue("can't read: " + locatorFile.getPath(), locatorFile.canRead());
@@ -35,4 +36,4 @@ public class LocatorTest extends PlatformTestCase {
assertEquals(home, PathManager.getHomePath());
}
}
}
@@ -249,7 +249,7 @@ public class RootIndex {
final Module depModule = moduleOrderEntry.getModule();
if (depModule != null) {
Node node = graph.myNodes.get(depModule);
OrderEnumerator en = OrderEnumerator.orderEntries(depModule).exportedOnly();
OrderEnumerator en = OrderEnumerator.orderEntries(depModule).exportedOnly().recursively();
if (node == null) {
node = new Node();
node.myKey = depModule;
@@ -35,8 +35,8 @@ import com.intellij.notification.NotificationType;
import com.intellij.notification.impl.NotificationsManagerImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -86,7 +86,7 @@ public class AnnotateDiffViewerAction extends ToggleAction implements DumbAware
};
public AnnotateDiffViewerAction() {
EmptyAction.setupAction(this, "Annotate", null);
ActionUtil.copyFrom(this, "Annotate");
setEnabledInModalContext(true);
}
@@ -55,11 +55,6 @@ public abstract class ShowChangeMarkerAction extends AbstractVcsAction {
};
}
@Override
protected boolean forceSyncUpdate(final AnActionEvent e) {
return true;
}
public ShowChangeMarkerAction() {
myChangeMarkerContext = new ChangeMarkerContext() {
@Override
@@ -118,6 +113,11 @@ public abstract class ShowChangeMarkerAction extends AbstractVcsAction {
LineStatusTrackerDrawing.moveToRange(range, editor, lineStatusTracker);
}
@Override
protected boolean forceSyncUpdate(final AnActionEvent e) {
return true;
}
protected interface ChangeMarkerContext {
Range getRange(VcsContext dataContext);
@@ -15,24 +15,23 @@
*/
package com.intellij.openapi.vcs.actions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.vcs.ex.LineStatusTracker;
import com.intellij.openapi.vcs.ex.Range;
/**
* author: lesya
*/
public class ShowNextChangeMarkerAction extends ShowChangeMarkerAction {
public ShowNextChangeMarkerAction(final Range range, final LineStatusTracker lineStatusTracker, final Editor editor) {
super(range, lineStatusTracker, editor);
ActionUtil.copyFrom(this, "VcsShowNextChangeMarker");
}
@SuppressWarnings("unused")
public ShowNextChangeMarkerAction() {
super();
}
protected Range extractRange(LineStatusTracker lineStatusTracker, int line, Editor editor) {
return lineStatusTracker.getNextRange(line);
}
}
@@ -15,19 +15,20 @@
*/
package com.intellij.openapi.vcs.actions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.vcs.ex.LineStatusTracker;
import com.intellij.openapi.vcs.ex.Range;
/**
* author: lesya
*/
public class ShowPrevChangeMarkerAction extends ShowChangeMarkerAction {
public ShowPrevChangeMarkerAction(final Range range, final LineStatusTracker lineStatusTracker, final Editor editor) {
super(range, lineStatusTracker, editor);
ActionUtil.copyFrom(this, "VcsShowPrevChangeMarker");
}
@SuppressWarnings("unused")
public ShowPrevChangeMarkerAction() {
super();
}
protected Range extractRange(LineStatusTracker lineStatusTracker, int line, Editor editor) {
@@ -15,14 +15,14 @@
*/
package com.intellij.openapi.vcs.changes.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase;
@@ -36,8 +36,7 @@ import java.util.Arrays;
*/
public class RollbackDialogAction extends AnAction implements DumbAware {
public RollbackDialogAction() {
super(VcsBundle.message("changes.action.rollback.text"), VcsBundle.message("changes.action.rollback.description"),
AllIcons.Actions.Rollback);
ActionUtil.copyFrom(this, IdeActions.CHANGES_VIEW_ROLLBACK);
}
public void actionPerformed(AnActionEvent e) {
@@ -20,6 +20,7 @@ import com.intellij.diff.util.DiffUserDataKeysEx;
import com.intellij.ide.DeleteProvider;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
@@ -369,7 +370,8 @@ public abstract class ChangesBrowserBase<T> extends JPanel implements TypeSafeDa
showDiff();
}
};
EmptyAction.setupAction(myDiffAction, "ChangesView.Diff", myViewer);
ActionUtil.copyFrom(myDiffAction, "ChangesView.Diff");
myDiffAction.registerCustomShortcutSet(myViewer, null);
toolBarGroup.add(myDiffAction);
}
@@ -324,7 +324,7 @@ public class MultipleChangeListBrowser extends ChangesBrowserBase<Object> {
EmptyAction.registerWithShortcutSet(IdeActions.MOVE_TO_ANOTHER_CHANGE_LIST, CommonShortcuts.getMove(), myViewer);
RollbackDialogAction rollback = new RollbackDialogAction();
EmptyAction.setupAction(rollback, IdeActions.CHANGES_VIEW_ROLLBACK, this);
rollback.registerCustomShortcutSet(this, null);
toolBarGroup.add(rollback);
EditSourceForDialogAction editSourceAction = new EditSourceForDialogAction(this);
@@ -19,17 +19,11 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAware;
import javax.swing.*;
/**
* @author irengrig
*/
public abstract class BaseLineStatusRangeAction extends AnAction implements DumbAware {
protected final LineStatusTracker myLineStatusTracker;
protected final Range myRange;
BaseLineStatusRangeAction(final String text, final Icon icon, final LineStatusTracker lineStatusTracker, final Range range) {
super(text, null, icon);
BaseLineStatusRangeAction(final LineStatusTracker lineStatusTracker, final Range range) {
myLineStatusTracker = lineStatusTracker;
myRange = range;
}
@@ -16,18 +16,16 @@
package com.intellij.openapi.vcs.ex;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.util.PlatformIcons;
import java.awt.datatransfer.StringSelection;
/**
* @author irengrig
*/
public class CopyLineStatusRangeAction extends BaseLineStatusRangeAction {
CopyLineStatusRangeAction(final LineStatusTracker lineStatusTracker, final Range range) {
super(VcsBundle.message("action.name.copy.old.text"), PlatformIcons.COPY_ICON, lineStatusTracker, range);
super(lineStatusTracker, range);
ActionUtil.copyFrom(this, IdeActions.ACTION_COPY);
}
public boolean isEnabled() {
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs.ex;
import com.intellij.diff.util.DiffUtil;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -80,11 +81,11 @@ public class LineStatusTrackerDrawing {
group.add(toggleWordDiff);
JComponent editorComponent = myEditor.getComponent();
EmptyAction.setupAction(localShowPrevAction, "VcsShowPrevChangeMarker", editorComponent);
EmptyAction.setupAction(localShowNextAction, "VcsShowNextChangeMarker", editorComponent);
EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent);
EmptyAction.setupAction(showDiff, "ChangesView.Diff", editorComponent);
EmptyAction.setupAction(copyRange, IdeActions.ACTION_COPY, editorComponent);
DiffUtil.registerAction(localShowPrevAction, editorComponent);
DiffUtil.registerAction(localShowNextAction, editorComponent);
DiffUtil.registerAction(rollback, editorComponent);
DiffUtil.registerAction(showDiff, editorComponent);
DiffUtil.registerAction(copyRange, editorComponent);
final List<AnAction> actionList = ActionUtil.getActions(editorComponent);
Disposer.register(parentDisposable, new Disposable() {
@@ -13,6 +13,8 @@
package com.intellij.openapi.vcs.ex;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Editor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -23,6 +25,7 @@ public class RollbackLineStatusRangeAction extends RollbackLineStatusAction {
@NotNull private final Range myRange;
public RollbackLineStatusRangeAction(@NotNull LineStatusTracker tracker, @NotNull Range range, @Nullable Editor editor) {
ActionUtil.copyFrom(this, IdeActions.SELECTED_CHANGES_ROLLBACK);
myTracker = tracker;
myEditor = editor;
myRange = range;
@@ -22,8 +22,8 @@ import com.intellij.diff.contents.DiffContent;
import com.intellij.diff.contents.DocumentContent;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.diff.requests.SimpleDiffRequest;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -35,7 +35,8 @@ import org.jetbrains.annotations.Nullable;
public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction {
public ShowLineStatusRangeDiffAction(@NotNull LineStatusTracker lineStatusTracker, @NotNull Range range, @Nullable Editor editor) {
super(VcsBundle.message("action.name.show.difference"), AllIcons.Actions.Diff, lineStatusTracker, range);
super(lineStatusTracker, range);
ActionUtil.copyFrom(this, "ChangesView.Diff");
}
@Override
@@ -19,6 +19,7 @@ import com.intellij.CommonBundle;
import com.intellij.dvcs.DvcsCommitAdditionalComponent;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.push.ui.VcsPushDialog;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -44,9 +45,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.textCompletion.DefaultTextCompletionValueDescriptor;
import com.intellij.util.textCompletion.TextCompletionProvider;
import com.intellij.util.textCompletion.TextFieldWithCompletion;
import com.intellij.util.textCompletion.ValuesCompletionProvider;
import com.intellij.util.textCompletion.ValuesCompletionProvider.ValuesCompletionProviderDumbAware;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.VcsUser;
import com.intellij.vcs.log.VcsUserRegistry;
@@ -227,11 +226,8 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
GitRepositoryManager manager = GitUtil.getRepositoryManager(myProject);
Collection<GitRepository> repositories = GitUtil.getRepositoriesFromRoots(manager, sortedChanges.keySet());
final List<GitRepository> preselectedRepositories = ContainerUtil.newArrayList(repositories);
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
new VcsPushDialog(myProject, preselectedRepositories, GitBranchUtil.getCurrentRepository(myProject)).show();
}
});
TransactionGuard.submitTransaction(myProject, () ->
new VcsPushDialog(myProject, preselectedRepositories, GitBranchUtil.getCurrentRepository(myProject)).show());
}
return exceptions;
}
@@ -18,6 +18,7 @@ package git4idea.merge;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -29,7 +30,6 @@ import com.intellij.openapi.vcs.merge.MergeProvider;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import git4idea.GitPlatformFacade;
import git4idea.GitUtil;
import git4idea.GitVcs;
@@ -224,12 +224,10 @@ public class GitConflictResolver {
}
private void showMergeDialog(final Collection<VirtualFile> initiallyUnmergedFiles) {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override public void run() {
final MergeProvider mergeProvider = myParams.reverse ?
new GitMergeProvider(myProject, true) : new GitMergeProvider(myProject, false);
myVcsHelper.showMergeDialog(new ArrayList<VirtualFile>(initiallyUnmergedFiles), mergeProvider, myParams.myMergeDialogCustomizer);
}
TransactionGuard.getInstance().submitTransactionAndWait(() -> {
final MergeProvider mergeProvider = myParams.reverse ?
new GitMergeProvider(myProject, true) : new GitMergeProvider(myProject, false);
myVcsHelper.showMergeDialog(new ArrayList<VirtualFile>(initiallyUnmergedFiles), mergeProvider, myParams.myMergeDialogCustomizer);
});
}
@@ -15,8 +15,6 @@
*/
package git4idea.ui;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vcs.changes.Change;
@@ -41,7 +39,7 @@ public class ChangesBrowserWithRollback extends ChangesBrowser {
super(project, null, changes, null, false, true, null, MyUseCase.LOCAL_CHANGES, null);
myOriginalChanges = changes;
RollbackDialogAction rollback = new RollbackDialogAction();
EmptyAction.setupAction(rollback, IdeActions.CHANGES_VIEW_ROLLBACK, this);
rollback.registerCustomShortcutSet(this, null);
addToolbarAction(rollback);
setChangesToDisplay(changes);
}
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2016 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.builder;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtilKt;
public abstract class BuilderMethodsContributor extends NonCodeMembersContributor {
@Override
public void processDynamicElements(@NotNull PsiType qualifierType,
PsiClass clazz,
@NotNull PsiScopeProcessor processor,
@NotNull PsiElement place,
@NotNull ResolveState state) {
if (clazz == null) return;
String name = ResolveUtil.getNameHint(processor);
if (name == null) return;
if (!ResolveUtilKt.shouldProcessDynamicMethods(processor)) return;
processDynamicMethods(qualifierType, clazz, name, place, e -> processor.execute(e, state));
}
abstract boolean processDynamicMethods(@NotNull PsiType qualifierType,
@NotNull PsiClass clazz,
@NotNull String name,
@NotNull PsiElement place,
@NotNull Processor<PsiElement> processor);
}
@@ -15,23 +15,22 @@
*/
package org.jetbrains.plugins.groovy.builder;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsClassImpl;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import static com.intellij.psi.CommonClassNames.JAVA_UTIL_MAP;
import static org.jetbrains.plugins.groovy.builder.JsonDelegateContributor.DELEGATE_FQN;
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrDelegatesToUtil.DELEGATES_TO_KEY;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE;
public class JsonBuilderContributor extends NonCodeMembersContributor {
public class JsonBuilderContributor extends BuilderMethodsContributor {
private static final String FQN = "groovy.json.JsonBuilder";
static final String ORIGIN_INFO = "via JsonBuilder";
@@ -43,51 +42,44 @@ public class JsonBuilderContributor extends NonCodeMembersContributor {
}
@Override
public void processDynamicElements(@NotNull PsiType qualifierType,
PsiClass clazz,
@NotNull PsiScopeProcessor processor,
@NotNull PsiElement place,
@NotNull ResolveState state) {
if (clazz == null) return;
String name = ResolveUtil.getNameHint(processor);
if (name == null) return;
if (!ResolveUtil.shouldProcessMethods(processor.getHint(ElementClassHint.KEY))) return;
boolean processDynamicMethods(@NotNull PsiType qualifierType,
@NotNull PsiClass clazz,
@NotNull String name,
@NotNull PsiElement place,
@NotNull Processor<PsiElement> processor) {
GrLightMethodBuilder method;
// ()
method = createMethod(name, clazz, place);
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// (Closure)
method = createMethod(name, clazz, place);
method.addAndGetParameter("c", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// (Map)
method = createMethod(name, clazz, place);
method.addParameter("map", JAVA_UTIL_MAP, false);
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// (Map, Closure)
method = createMethod(name, clazz, place);
method.addParameter("map", JAVA_UTIL_MAP, false);
method.addAndGetParameter("c", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// (Iterable, Closure)
method = createMethod(name, clazz, place);
method.addParameter("value", TypesUtil.createIterableType(place, null), false);
method.addAndGetParameter("c", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// (Object[], Closure)
method = createMethod(name, clazz, place);
method.addParameter("value", TypesUtil.getJavaLangObject(place).createArrayType(), false);
method.addAndGetParameter("c", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
processor.execute(method, state);
return processor.process(method);
}
@@ -98,7 +90,7 @@ public class JsonBuilderContributor extends NonCodeMembersContributor {
method.setOriginInfo(ORIGIN_INFO);
method.addModifier(PsiModifier.PUBLIC);
method.setReturnType(JAVA_UTIL_MAP, context.getResolveScope());
method.setContainingClass(clazz instanceof ClsClassImpl ? ((ClsClassImpl)clazz).getSourceMirrorClass() : clazz);
UtilsKt.setContainingClass(method, clazz);
return method;
}
}
@@ -16,20 +16,16 @@
package org.jetbrains.plugins.groovy.builder;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsClassImpl;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrDelegatesToUtil.DELEGATES_TO_KEY;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE;
public class JsonDelegateContributor extends NonCodeMembersContributor {
public class JsonDelegateContributor extends BuilderMethodsContributor {
static final String DELEGATE_FQN = "groovy.json.JsonDelegate";
@@ -40,18 +36,11 @@ public class JsonDelegateContributor extends NonCodeMembersContributor {
}
@Override
public void processDynamicElements(@NotNull PsiType qualifierType,
PsiClass clazz,
@NotNull PsiScopeProcessor processor,
@NotNull PsiElement place,
@NotNull ResolveState state) {
if (clazz == null) return;
String name = ResolveUtil.getNameHint(processor);
if (name == null) return;
if (!ResolveUtil.shouldProcessMethods(processor.getHint(ElementClassHint.KEY))) return;
boolean processDynamicMethods(@NotNull PsiType qualifierType,
@NotNull PsiClass clazz,
@NotNull String name,
@NotNull PsiElement place,
@NotNull Processor<PsiElement> processor) {
JavaPsiFacade facade = JavaPsiFacade.getInstance(place.getProject());
GrLightMethodBuilder method;
@@ -62,7 +51,7 @@ public class JsonDelegateContributor extends NonCodeMembersContributor {
genericType = facade.getElementFactory().createType(method.addTypeParameter("T"));
method.addParameter("value", genericType, false);
method.setReturnType(genericType);
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// List<T> (T[], Closure)
method = createMethod(name, clazz, place);
@@ -70,7 +59,7 @@ public class JsonDelegateContributor extends NonCodeMembersContributor {
method.addParameter("values", genericType.createArrayType(), false);
method.addAndGetParameter("c", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
method.setReturnType(TypesUtil.createListType(place, genericType));
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// List<T> (Iterable<T>, Closure)
method = createMethod(name, clazz, place);
@@ -78,14 +67,14 @@ public class JsonDelegateContributor extends NonCodeMembersContributor {
method.addParameter("values", TypesUtil.createIterableType(place, genericType), false);
method.addAndGetParameter("c", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
method.setReturnType(TypesUtil.createListType(place, genericType));
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
// List<T> (T...)
method = createMethod(name, clazz, place);
genericType = facade.getElementFactory().createType(method.addTypeParameter("T"));
method.addAndGetParameter("values", new PsiEllipsisType(genericType), false);
method.setReturnType(TypesUtil.createListType(place, genericType));
processor.execute(method, state);
return processor.process(method);
}
private static GrLightMethodBuilder createMethod(@NotNull String name,
@@ -94,7 +83,7 @@ public class JsonDelegateContributor extends NonCodeMembersContributor {
GrLightMethodBuilder method = new GrLightMethodBuilder(context.getManager(), name);
method.setOriginInfo(JsonBuilderContributor.ORIGIN_INFO);
method.addModifier(PsiModifier.PUBLIC);
method.setContainingClass(clazz instanceof ClsClassImpl ? ((ClsClassImpl)clazz).getSourceMirrorClass() : clazz);
UtilsKt.setContainingClass(method, clazz);
return method;
}
}
@@ -0,0 +1,95 @@
/*
* Copyright 2000-2016 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.builder;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import static com.intellij.psi.CommonClassNames.JAVA_UTIL_MAP;
import static org.jetbrains.plugins.groovy.builder.StreamingJsonBuilderDelegateContributor.addClosureParameter;
public class StreamingJsonBuilderContributor extends BuilderMethodsContributor {
private static final String FQN = "groovy.json.StreamingJsonBuilder";
static final String ORIGIN_INFO = "via StreamingJsonBuilder";
@Nullable
@Override
protected String getParentClassName() {
return FQN;
}
@Override
boolean processDynamicMethods(@NotNull PsiType qualifierType,
@NotNull PsiClass clazz,
@NotNull String name,
@NotNull PsiElement place,
@NotNull Processor<PsiElement> processor) {
GrLightMethodBuilder method;
// ()
method = createMethod(name, place, qualifierType, clazz);
if (!processor.process(method)) return false;
// (Closure)
method = createMethod(name, place, qualifierType, clazz);
addClosureParameter(method);
if (!processor.process(method)) return false;
// (Map)
method = createMethod(name, place, qualifierType, clazz);
method.addParameter("args", JAVA_UTIL_MAP);
if (!processor.process(method)) return false;
// (Map, Closure)
method = createMethod(name, place, qualifierType, clazz);
method.addParameter("args", JAVA_UTIL_MAP);
addClosureParameter(method);
if (!processor.process(method)) return false;
// (Iterable, Closure)
method = createMethod(name, place, qualifierType, clazz);
method.addParameter("values", TypesUtil.createIterableType(place, null), false);
addClosureParameter(method);
if (!processor.process(method)) return false;
// (Object[], Closure)
method = createMethod(name, place, qualifierType, clazz);
method.addParameter("values", TypesUtil.getJavaLangObject(place).createArrayType());
addClosureParameter(method);
return processor.process(method);
}
@NotNull
private static GrLightMethodBuilder createMethod(@NotNull String name,
@NotNull PsiElement place,
@NotNull PsiType returnType,
@NotNull PsiClass clazz) {
GrLightMethodBuilder method = new GrLightMethodBuilder(place.getManager(), name);
method.setModifiers(GrModifierFlags.PUBLIC_MASK);
method.setReturnType(returnType);
UtilsKt.setContainingClass(method, clazz);
method.setOriginInfo(ORIGIN_INFO);
return method;
}
}
@@ -0,0 +1,100 @@
/*
* Copyright 2000-2016 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.builder;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiEllipsisType;
import com.intellij.psi.PsiType;
import com.intellij.util.Processor;
import com.siyeh.ig.psiutils.TypeUtils;
import groovy.lang.Closure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrDelegatesToUtil.DELEGATES_TO_KEY;
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrDelegatesToUtil.DELEGATES_TO_STRATEGY_KEY;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE;
public class StreamingJsonBuilderDelegateContributor extends BuilderMethodsContributor {
private static final String DELEGATE_FQN = "groovy.json.StreamingJsonBuilder.StreamingJsonDelegate";
@Nullable
@Override
protected String getParentClassName() {
return DELEGATE_FQN;
}
@Override
boolean processDynamicMethods(@NotNull PsiType qualifierType,
@NotNull PsiClass clazz,
@NotNull String name,
@NotNull PsiElement place,
@NotNull Processor<PsiElement> processor) {
GrLightMethodBuilder method;
// (Object...)
method = createMethod(name, place, clazz);
method.addParameter("values", new PsiEllipsisType(TypeUtils.getObjectType(place)));
if (!processor.process(method)) return false;
// (Closure)
method = createMethod(name, place, clazz);
addClosureParameter(method);
if (!processor.process(method)) return false;
// (Iterable, Closure)
method = createMethod(name, place, clazz);
method.addParameter("values", TypesUtil.createIterableType(place, null));
addClosureParameter(method);
if (!processor.process(method)) return false;
// (Object[], Closure)
method = createMethod(name, place, clazz);
method.addParameter("values", TypesUtil.getJavaLangObject(place).createArrayType());
addClosureParameter(method);
if (!processor.process(method)) return false;
// (Object, Closure)
method = createMethod(name, place, clazz);
method.addParameter("value", TypesUtil.getJavaLangObject(place));
addClosureParameter(method);
return processor.process(method);
}
@NotNull
private static GrLightMethodBuilder createMethod(@NotNull String name,
@NotNull PsiElement place,
@NotNull PsiClass clazz) {
GrLightMethodBuilder method = new GrLightMethodBuilder(place.getManager(), name);
method.setModifiers(GrModifierFlags.PUBLIC_MASK);
method.setReturnType(TypesUtil.getJavaLangObject(place));
UtilsKt.setContainingClass(method, clazz);
method.setOriginInfo(StreamingJsonBuilderContributor.ORIGIN_INFO);
return method;
}
static void addClosureParameter(GrLightMethodBuilder method) {
GrLightParameter closureParam = method.addAndGetParameter("closure", GROOVY_LANG_CLOSURE);
closureParam.putUserData(DELEGATES_TO_KEY, DELEGATE_FQN);
closureParam.putUserData(DELEGATES_TO_STRATEGY_KEY, Closure.DELEGATE_FIRST);
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2016 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.builder
import com.intellij.psi.PsiClass
import com.intellij.psi.impl.compiled.ClsClassImpl
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder
fun setContainingClass(method: GrLightMethodBuilder, clazz: PsiClass): Unit {
method.containingClass = (if (clazz is ClsClassImpl) clazz.sourceMirrorClass else null) ?: clazz
}
@@ -13,28 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.markup;
package org.jetbrains.plugins.groovy.builder;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import static com.intellij.psi.CommonClassNames.*;
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrDelegatesToUtil.DELEGATES_TO_KEY;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE;
public class XmlMarkupBuilderNonCodeMemberContributor extends NonCodeMembersContributor {
public class XmlMarkupBuilderNonCodeMemberContributor extends BuilderMethodsContributor {
private static final String FQN = "groovy.xml.MarkupBuilder";
private static final String ORIGIN_INFO = "via MarkupBuilder";
@Nullable
@Override
@@ -43,71 +40,65 @@ public class XmlMarkupBuilderNonCodeMemberContributor extends NonCodeMembersCont
}
@Override
public void processDynamicElements(@NotNull PsiType qualifierType,
PsiClass aClass,
@NotNull PsiScopeProcessor processor,
@NotNull PsiElement place,
@NotNull ResolveState state) {
String name = ResolveUtil.getNameHint(processor);
if (name == null) return;
if (!ResolveUtil.shouldProcessMethods(processor.getHint(ElementClassHint.KEY))) return;
boolean processDynamicMethods(@NotNull PsiType qualifierType,
@NotNull PsiClass clazz,
@NotNull String name,
@NotNull PsiElement place,
@NotNull Processor<PsiElement> processor) {
GrLightMethodBuilder res;
// ()
res = new GrLightMethodBuilder(aClass.getManager(), name);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res.setOriginInfo("via MarkupBuilder");
if (!processor.execute(res, state)) return;
res = createMethod(name, clazz, place);
if (!processor.process(res)) return false;
// (Closure)
res = new GrLightMethodBuilder(aClass.getManager(), name);
res = createMethod(name, clazz, place);
res.addAndGetParameter("body", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, FQN);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res.setOriginInfo("via MarkupBuilder");
if (!processor.execute(res, state)) return;
if (!processor.process(res)) return false;
// (Object, Closure)
res = new GrLightMethodBuilder(aClass.getManager(), name);
res = createMethod(name, clazz, place);
res.addParameter("value", JAVA_LANG_OBJECT, false);
res.addAndGetParameter("body", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, FQN);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res.setOriginInfo("via MarkupBuilder");
if (!processor.execute(res, state)) return;
if (!processor.process(res)) return false;
// (Map, Closure)
res = new GrLightMethodBuilder(aClass.getManager(), name);
res = createMethod(name, clazz, place);
res.addParameter("attributes", JAVA_UTIL_MAP, false);
res.addAndGetParameter("body", GROOVY_LANG_CLOSURE, false).putUserData(DELEGATES_TO_KEY, FQN);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res.setOriginInfo("via MarkupBuilder");
if (!processor.execute(res, state)) return;
if (!processor.process(res)) return false;
// (Map)
// (Map, Object)
// (Map, Object, Closure)
res = new GrLightMethodBuilder(aClass.getManager(), name);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res = createMethod(name, clazz, place);
res.addParameter("attributes", JAVA_UTIL_MAP, false);
res.addParameter("value", JAVA_LANG_OBJECT, true);
res.addAndGetParameter("body", GROOVY_LANG_CLOSURE, true).putUserData(DELEGATES_TO_KEY, FQN);
res.setOriginInfo("via MarkupBuilder");
for (GrReflectedMethod method : res.getReflectedMethods()) {
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
}
// (Object)
// (Object, Map)
// (Object, Map, Closure)
res = new GrLightMethodBuilder(aClass.getManager(), name);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res = createMethod(name, clazz, place);
res.addParameter("value", JAVA_LANG_OBJECT, false);
res.addParameter("attributes", JAVA_UTIL_MAP, true);
res.addAndGetParameter("body", GROOVY_LANG_CLOSURE, true).putUserData(DELEGATES_TO_KEY, FQN);
res.setOriginInfo("via MarkupBuilder");
for (GrReflectedMethod method : res.getReflectedMethods()) {
if (!processor.execute(method, state)) return;
if (!processor.process(method)) return false;
}
return true;
}
@NotNull
private static GrLightMethodBuilder createMethod(@NotNull String name, @NotNull PsiClass clazz, @NotNull PsiElement place) {
GrLightMethodBuilder res = new GrLightMethodBuilder(place.getManager(), name);
res.setReturnType(JAVA_LANG_STRING, place.getResolveScope());
res.setOriginInfo(ORIGIN_INFO);
UtilsKt.setContainingClass(res, clazz);
return res;
}
}
@@ -46,7 +46,7 @@ public class Transformations {
result.put(PREVIOUS, new UnaryTransformation(mDEC));
result.put(AS_BOOLEAN, new AsBooleanTransformation());
result.put(CALL, new CallTransformation());
//result.put(CALL, new CallTransformation());
}
private void addBinary() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -56,6 +56,7 @@ import org.jetbrains.plugins.groovy.annotator.GrKeywordAndDeclarationHighlightFa
import org.jetbrains.plugins.groovy.annotator.GrReferenceHighlighterFactory;
import org.jetbrains.plugins.groovy.annotator.GroovyFrameworkConfigNotification;
import org.jetbrains.plugins.groovy.annotator.checkers.*;
import org.jetbrains.plugins.groovy.builder.XmlMarkupBuilderNonCodeMemberContributor;
import org.jetbrains.plugins.groovy.codeInsight.GroovyClsCustomNavigationPolicy;
import org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactory;
import org.jetbrains.plugins.groovy.codeInspection.declaration.GrMethodMayBeStaticInspectionFilter;
@@ -96,7 +97,6 @@ import org.jetbrains.plugins.groovy.lang.resolve.ast.*;
import org.jetbrains.plugins.groovy.lang.resolve.noncode.GrCollectionTypeMembersProvider;
import org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor;
import org.jetbrains.plugins.groovy.lang.stubs.GroovyShortNamesCache;
import org.jetbrains.plugins.groovy.markup.XmlMarkupBuilderNonCodeMemberContributor;
import org.jetbrains.plugins.groovy.spock.SpockMemberContributor;
import org.jetbrains.plugins.groovy.spock.SpockPomDeclarationSearcher;
import org.jetbrains.plugins.groovy.structure.GroovyStructureViewFactory;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
/**
* @author ven
@@ -32,10 +33,16 @@ public interface GrReferenceElement<Q extends PsiElement> extends GroovyPsiEleme
@Nullable
String getReferenceName();
@Nullable
@Override
PsiElement resolve();
default PsiElement resolve() {
return advancedResolve().getElement();
}
GroovyResolveResult advancedResolve();
@NotNull
default GroovyResolveResult advancedResolve() {
return PsiImplUtil.extractUniqueResult(multiResolve(false));
}
@Override
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -24,6 +24,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
/**
* @author ven
@@ -48,10 +49,14 @@ public interface GrCall extends GroovyPsiElement {
GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument);
@Nullable
PsiMethod resolveMethod();
default PsiMethod resolveMethod() {
return PsiImplUtil.extractUniqueElement(multiResolve(false));
}
@NotNull
GroovyResolveResult advancedResolve();
default GroovyResolveResult advancedResolve() {
return PsiImplUtil.extractUniqueResult(multiResolve(false));
}
@NotNull
GroovyResolveResult[] multiResolve(boolean incompleteCode);
@@ -17,6 +17,7 @@
package org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members;
import com.intellij.psi.PsiEnumConstant;
import com.intellij.psi.PsiMethod;
import com.intellij.util.ArrayFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,4 +47,10 @@ public interface GrEnumConstant extends GrField, GrConstructorCall, PsiEnumConst
@Nullable
@Override
GrArgumentList getArgumentList();
@Nullable
@Override
default PsiMethod resolveMethod() {
return GrConstructorCall.super.resolveMethod();
}
}
@@ -29,7 +29,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
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.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrCallImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -115,17 +114,6 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru
return new GroovyResolveResult[]{new GroovyResolveResultImpl(aClass, this, null, PsiSubstitutor.EMPTY, true, true)};
}
@Override
public PsiMethod resolveMethod() {
return PsiImplUtil.extractUniqueElement(multiResolve(false));
}
@NotNull
@Override
public GroovyResolveResult advancedResolve() {
return PsiImplUtil.extractUniqueResult(multiResolve(false));
}
@Override
@Nullable
public PsiClass getDelegatedClass() {
@@ -17,9 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import groovy.lang.Closure;
import org.jetbrains.annotations.NotNull;
@@ -37,10 +35,14 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getArgumentTypes;
/**
* @author Max Medvedev
@@ -55,7 +57,7 @@ public class GrDelegatesToUtil {
GrCall call = getContainingCall(closableBlock);
if (call == null) return null;
GroovyResolveResult result = call.advancedResolve();
GroovyResolveResult result = resolveActualCall(call);
if (GdkMethodUtil.isWithOrIdentity(result.getElement())) {
final GrExpression qualifier = inferCallQualifier((GrMethodCall)call);
@@ -270,6 +272,32 @@ public class GrDelegatesToUtil {
return null;
}
@NotNull
static GroovyResolveResult resolveActualCall(@NotNull GrCall call) {
if (call instanceof GrMethodCall) {
return CachedValuesManager.getCachedValue(call, () -> CachedValueProvider.Result.create(
doResolveActualCall((GrMethodCall)call), PsiModificationTracker.MODIFICATION_COUNT
));
}
else {
return call.advancedResolve();
}
}
@NotNull
private static GroovyResolveResult doResolveActualCall(@NotNull GrMethodCall call) {
GroovyResolveResult result = call.advancedResolve();
if (result.getElement() instanceof PsiMethod && !result.isInvokedOnProperty()) {
return result;
}
GrExpression expression = call.getInvokedExpression();
PsiType type = expression.getType();
if (type == null) return result;
GroovyResolveResult[] calls = ResolveUtil.getMethodCandidates(type, "call", expression, getArgumentTypes(expression, false));
return PsiImplUtil.extractUniqueResult(calls);
}
public static class DelegatesToInfo {
final PsiType myClassToDelegate;
final int myStrategy;
@@ -19,7 +19,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
@@ -85,28 +84,6 @@ public abstract class GrMethodCallImpl extends GrCallExpressionImpl implements G
throw new IncorrectOperationException("invoked expression must not be null");
}
@Override
public PsiMethod resolveMethod() {
final GrExpression methodExpr = getInvokedExpression();
if (methodExpr instanceof GrReferenceExpression) {
final PsiElement resolved = ((GrReferenceExpression) methodExpr).resolve();
return resolved instanceof PsiMethod ? (PsiMethod) resolved : null;
}
return null;
}
@NotNull
@Override
public GroovyResolveResult advancedResolve() {
final GrExpression methodExpr = getInvokedExpression();
if (methodExpr instanceof GrReferenceExpression) {
return ((GrReferenceExpression) methodExpr).advancedResolve();
}
return GroovyResolveResult.EMPTY_RESULT;
}
@Override
public PsiType getType() {
return TypeInferenceHelper.getCurrentContext().getExpressionType(this, METHOD_CALL_TYPES_CALCULATOR);
@@ -46,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnonymousClassType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClassReferenceType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrCallExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GrInnerClassConstructorUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -195,18 +194,6 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx
return findChildByClass(GrTypeArgumentList.class);
}
@Override
@Nullable
public PsiMethod resolveMethod() {
return PsiImplUtil.extractUniqueElement(multiResolve(false));
}
@NotNull
@Override
public GroovyResolveResult advancedResolve() {
return PsiImplUtil.extractUniqueResult(multiResolve(false));
}
@Override
@NotNull
public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) {
@@ -198,12 +198,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return "Reference expression";
}
@Override
@Nullable
public final PsiElement resolve() {
return advancedResolve().getElement();
}
private static final PolyVariantResolver<GrReferenceExpressionImpl> POLY_RESOLVER = new PolyVariantResolver<GrReferenceExpressionImpl>() {
@Override
@NotNull
@@ -601,12 +595,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return dot == null ? null : dot.getNode().getElementType();
}
@Override
public GroovyResolveResult advancedResolve() {
ResolveResult[] results = TypeInferenceHelper.getCurrentContext().multiResolve(this, false, POLY_RESOLVER);
return results.length == 1 ? (GroovyResolveResult)results[0] : GroovyResolveResult.EMPTY_RESULT;
}
@Override
@NotNull
public GroovyResolveResult[] multiResolve(boolean incomplete) { //incomplete means we do not take arguments into consideration
@@ -462,6 +462,13 @@ public class TypesUtil {
return createTypeByFQClassName(fqName, context);
}
@NotNull
public static PsiClassType createType(@NotNull PsiClass clazz, @Nullable PsiElement context, PsiType... parameters) {
return JavaPsiFacade.getInstance(
(context == null ? clazz : context).getProject()
).getElementFactory().createType(clazz, parameters);
}
@NotNull
public static PsiClassType getJavaLangObject(@NotNull PsiElement context) {
return LazyFqnClassType.getLazyType(CommonClassNames.JAVA_LANG_OBJECT, context);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -354,18 +354,6 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
return GrClosableBlock.EMPTY_ARRAY;
}
@Override
public PsiMethod resolveMethod() {
return PsiImplUtil.extractUniqueElement(multiResolve(false));
}
@NotNull
@Override
public GroovyResolveResult advancedResolve() {
GroovyResolveResult[] results = multiResolve(false);
return results.length == 1 ? results[0] : GroovyResolveResult.EMPTY_RESULT;
}
@Override
public PsiReference getReference() {
return myReference;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -37,7 +37,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEn
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.GrFieldImpl;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrFieldStub;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -159,11 +158,6 @@ public class GrEnumConstantImpl extends GrFieldImpl implements GrEnumConstant {
return GrClosableBlock.EMPTY_ARRAY;
}
@Override
public PsiMethod resolveMethod() {
return PsiImplUtil.extractUniqueElement(multiResolve(false));
}
@NotNull
@Override
public JavaResolveResult resolveMethodGenerics() {
@@ -199,12 +193,6 @@ public class GrEnumConstantImpl extends GrFieldImpl implements GrEnumConstant {
return myReference;
}
@NotNull
@Override
public GroovyResolveResult advancedResolve() {
return PsiImplUtil.extractUniqueResult(multiResolve(false));
}
@Override
public PsiMethod resolveConstructor() {
return resolveMethod();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -57,27 +57,11 @@ public class GrLightClassReferenceElement extends LightElement implements GrCode
return myClassName;
}
@Override
public PsiElement resolve() {
return GroovyPsiManager.getInstance(getProject()).findClassWithCache(myClassName, myContext.getResolveScope());
}
@Override
public GroovyResolveResult advancedResolve() {
return new GroovyResolveResultImpl(resolve(), true);
}
@NotNull
@Override
public GroovyResolveResult[] multiResolve(boolean incompleteCode) {
final GroovyResolveResult resolveResult = advancedResolve();
if (resolveResult.getElement() == null) {
return new GroovyResolveResult[]{resolveResult};
}
else {
return GroovyResolveResult.EMPTY_ARRAY;
}
PsiClass clazz = GroovyPsiManager.getInstance(getProject()).findClassWithCache(myClassName, myContext.getResolveScope());
return clazz == null ? GroovyResolveResult.EMPTY_ARRAY : new GroovyResolveResult[]{new GroovyResolveResultImpl(clazz, true)};
}
@NotNull
@@ -260,17 +260,32 @@ public class GrLightMethodBuilder extends LightElement implements GrMethod, Orig
return this;
}
@NotNull
public GrLightMethodBuilder addParameter(@NotNull String name, @NotNull String type) {
return addParameter(name, type, false);
}
@NotNull
public GrLightMethodBuilder addParameter(@NotNull String name, @NotNull String type, boolean isOptional) {
return addParameter(name, JavaPsiFacade.getElementFactory(getProject()).createTypeFromText(type, this), isOptional);
}
@NotNull
public GrLightMethodBuilder addParameter(@NotNull String name, @NotNull PsiType type) {
return addParameter(name, type, false);
}
@NotNull
public GrLightMethodBuilder addParameter(@NotNull String name, @NotNull PsiType type, boolean isOptional) {
GrLightParameter param = new GrLightParameter(name, type, this).setOptional(isOptional);
return addParameter(param);
}
@NotNull
public GrLightParameter addAndGetParameter(@NotNull String name, @NotNull String type) {
return addAndGetParameter(name, type, false);
}
@NotNull
public GrLightParameter addAndGetParameter(@NotNull String name, @NotNull String type, boolean isOptional) {
return addAndGetParameter(name, JavaPsiFacade.getElementFactory(getProject()).createTypeFromText(type, this), isOptional);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -118,13 +118,6 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl<GrCodeRef
CLASS_IN_QUALIFIED_NEW
}
@Override
@Nullable
public PsiElement resolve() {
ResolveResult[] results = TypeInferenceHelper.getCurrentContext().multiResolve(this, false, RESOLVER);
return results.length == 1 ? results[0].getElement() : null;
}
public ReferenceKind getKind(boolean forCompletion) {
if (isClassReferenceForNew()) {
return ReferenceKind.CLASS_OR_PACKAGE;
@@ -519,12 +512,6 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl<GrCodeRef
private static final OurResolver RESOLVER = new OurResolver();
@Override
public GroovyResolveResult advancedResolve() {
ResolveResult[] results = TypeInferenceHelper.getCurrentContext().multiResolve(this, false, RESOLVER);
return results.length == 1 ? (GroovyResolveResult)results[0] : GroovyResolveResult.EMPTY_RESULT;
}
@Override
@NotNull
public GroovyResolveResult[] multiResolve(boolean incompleteCode) {
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2016 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.lang.resolve
import com.intellij.psi.scope.PsiScopeProcessor
import org.jetbrains.plugins.groovy.lang.resolve.processors.DynamicMembersHint
fun shouldProcessDynamicMethods(processor: PsiScopeProcessor): Boolean {
return processor.getHint(DynamicMembersHint.KEY)?.shouldProcessMethods() ?: false
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2016 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.lang.resolve.processors;
import com.intellij.openapi.util.Key;
public interface DynamicMembersHint {
Key<DynamicMembersHint> KEY = Key.create("groovy.dynamic.members.hint");
boolean shouldProcessMethods();
}
@@ -32,6 +32,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
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.api.statements.expressions.path.GrCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyMethodResult;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
@@ -50,7 +51,7 @@ import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.isAccessible
import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.isStaticsOK;
import static org.jetbrains.plugins.groovy.lang.resolve.processors.AccessorResolverProcessor.*;
public abstract class GroovyResolverProcessor implements PsiScopeProcessor, ElementClassHint, NameHint {
public abstract class GroovyResolverProcessor implements PsiScopeProcessor, ElementClassHint, NameHint, DynamicMembersHint {
protected final @NotNull GrReferenceExpression myRef;
private final @NotNull String myName;
@@ -204,7 +205,7 @@ public abstract class GroovyResolverProcessor implements PsiScopeProcessor, Elem
@Nullable
@Override
public <T> T getHint(@NotNull Key<T> hintKey) {
if (hintKey == ElementClassHint.KEY || hintKey == NameHint.KEY) {
if (hintKey == ElementClassHint.KEY || hintKey == NameHint.KEY || hintKey == DynamicMembersHint.KEY) {
return (T)this;
}
return null;
@@ -235,6 +236,11 @@ public abstract class GroovyResolverProcessor implements PsiScopeProcessor, Elem
return myName;
}
@Override
public boolean shouldProcessMethods() {
return myRef.getParent() instanceof GrCallExpression && !myCandidates.containsKey(GroovyResolveKind.METHOD);
}
@NotNull
public abstract List<GroovyResolveResult> getCandidates();
+3 -1
View File
@@ -108,9 +108,11 @@
<membersContributor implementation="org.jetbrains.plugins.groovy.gant.GantMemberContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.markup.XmlMarkupBuilderNonCodeMemberContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.XmlMarkupBuilderNonCodeMemberContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.JsonBuilderContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.JsonDelegateContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.StreamingJsonBuilderContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.StreamingJsonBuilderDelegateContributor"/>
<closureMissingMethodContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.PluginXmlClosureMemberContributor"/>
@@ -49,11 +49,15 @@ builder.people {
boolCall true
varArgs '1111', 22222
empty()
<warning>someProperty</warning>
}
<warning>someProperty</warning>
}
builder.<warning>root</warning>
builder.root<warning>(new Object())</warning>
builder.root<warning>(new Object[0])</warning>
builder.root<warning>([new Object(), new Object()])</warning>
builder.root<warning>([], new Object(), {})</warning>
'''
fixture.enableInspections GroovyAssignabilityCheckInspection, GrUnresolvedAccessInspection
@@ -0,0 +1,162 @@
/*
* Copyright 2000-2016 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.builder
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.compiled.ClsMethodImpl
import com.intellij.testFramework.LightProjectDescriptor
import groovy.transform.CompileStatic
import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
import org.jetbrains.plugins.groovy.LightGroovyTestCase
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression
@CompileStatic
class StreamingJsonBuilderTest extends LightGroovyTestCase {
final String basePath = null
final LightProjectDescriptor projectDescriptor = GroovyLightProjectDescriptor.GROOVY_LATEST
void 'test highlighting'() {
myFixture.configureByText 'a.groovy', '''
def builder = new groovy.json.StreamingJsonBuilder(null)
builder.people {
person {
string "fdsasdf"
mapCall(
city: 'A',
country: 'B',
zip: 12345,
)
boolCall true
varArgs '1111', 22222
empty()
cc {
foobar()
hellYeah(1,2,3)
}
<warning>someProperty</warning>
}
<warning>someProperty</warning>
}
builder.<warning>root</warning>
builder.root<warning>(new Object())</warning>
builder.root<warning>(new Object[0])</warning>
builder.root<warning>([new Object(), new Object()])</warning>
builder.root<warning>([], new Object(), {})</warning>
'''
fixture.enableInspections GroovyAssignabilityCheckInspection, GrUnresolvedAccessInspection
fixture.checkHighlighting true, false, true
}
void 'test builder calls resolve & return type'() {
[
"builder.root()",
"builder.root {}",
"builder.root(a: 1, b: 2)",
"builder.root(a: 1, b: 2) {}",
"builder.root([1, 2, 3, 4]) {}",
"builder.root([] as Integer[], {})",
].each { text ->
def file = fixture.configureByText('a.groovy', "def builder = new groovy.json.StreamingJsonBuilder(null);$text") as GroovyFile
def call = file.topStatements.last() as GrCallExpression
def method = call.resolveMethod()
assert method
assert call.type.canonicalText == 'groovy.json.StreamingJsonBuilder'
}
}
void 'test builder inner calls resolve & return type'() {
[
"noArg()",
"singleArg(1)",
"singleArg(new Object())",
"singleArg {}",
"singleArg([:])",
"doubleArg([:]) {}",
"doubleArg(1, 2)",
"doubleArg([], {})",
"doubleArg(new Object[0]) {}",
"doubleArg(new Object[0], {})",
"varArg(1, 2, 3)",
"varArg(1, 2d, '')",
"varArg(new Object(), [], {}, a: 1, 2d, [:], '')",
].each { callText ->
[
"builder.root {<caret>$callText}",
"builder.root(a: 1, b: 2) {<caret>$callText}",
"builder.root([1, 2, 3, 4]) {<caret>$callText}",
"builder.root([] as Integer[], {<caret>$callText})",
].each { text ->
doTest(text)
}
}
}
void 'test builder delegate inner calls resolve & return type'() {
[
"noArg()",
"singleArg(1)",
"singleArg(new Object())",
"singleArg {}",
"singleArg([:])",
"doubleArg([:]) {}",
"doubleArg(1, 2)",
"doubleArg([], {})",
"doubleArg(new Object[0]) {}",
"doubleArg(new Object[0], {})",
"varArg(1, 2, 3)",
"varArg(1, 2d, '')",
"varArg(new Object(), [], {}, a: 1, 2d, [:], '')",
].each { innerCallText ->
[
"singleArg {<caret>$innerCallText}",
"doubleArg([:]) {<caret>$innerCallText}",
"doubleArg([], {<caret>$innerCallText})",
"doubleArg(new Object[0], {<caret>$innerCallText})",
"varArg(new Object(), [], {<caret>$innerCallText}, a: 1, 2d, [:], '')",
].each { callText ->
["builder.root {$callText}",
"builder.root(a: 1, b: 2) {$callText}",
"builder.root([1, 2, 3, 4]) {$callText}",
"builder.root([] as Integer[], {$callText})",
].each { text ->
doTest(text)
}
}
}
}
private void doTest(text) {
fixture.configureByText 'a.groovy', "def builder = new groovy.json.StreamingJsonBuilder(); $text"
def reference = fixture.getReferenceAtCaretPosition() as GrReferenceExpression
assert reference.resolve() instanceof PsiMethod
assert reference.type.canonicalText == 'java.lang.Object'
}
void 'test do not override existing methods'() {
def file = myFixture.configureByText('a.groovy', '''
new groovy.json.StreamingJsonBuilder().cal<caret>l {}
''') as GroovyFile
def call = file.topStatements.last() as GrCallExpression
def method = call.resolveMethod()
assert method
assert method instanceof ClsMethodImpl
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.markup
package org.jetbrains.plugins.groovy.builder
import com.intellij.psi.impl.compiled.ClsMethodImpl
import org.jetbrains.plugins.groovy.LightGroovyTestCase
@@ -37,7 +37,7 @@ public class GrChangeToOperatorTest extends LightGroovyTestCase {
assertValid(/a.bitwiseNegate()/, /~a/)
assertValid(/a.negative()/, /-a/)
assertValid(/a.positive()/, /+a/)
assertValid(/a.call()/, /a()/)
// assertValid(/a.call()/, /a()/)
assertValid(/a.next()/, /++a/)
assertValid(/a.previous()/, /--a/)
}
@@ -347,6 +347,7 @@ test()
''', 'LinkedHashMap'
}
void testShouldChooseMethodFromOwnerInJava() {
myFixture.configureByText("Abc.java", '''\
import groovy.lang.Closure;
@@ -737,4 +738,54 @@ doX {
final containingClass = resolved.containingClass.name
assertEquals(resolvedClass, containingClass)
}
void 'test delegate within implicit call()'() {
assertScript '''\
class A {
def call(@DelegatesTo(Boo) Closure c) {}
}
class Boo {
def foo() {}
}
def a = new A()
a {
f<caret>oo()
}
''', 'Boo'
}
void 'test delegate within index property'() {
assertScript '''\
class A {
def getAt(@DelegatesTo(Boo) Closure c) {}
}
class Boo {
def foo() {}
}
def a = new A()
a[{
fo<caret>o()
}]
''', 'Boo'
}
void 'test delegate within constructor argument'() {
assertScript '''\
class A {
A(@DelegatesTo(Boo) Closure c) {}
}
class Boo {
def foo() {}
}
new A({
fo<caret>o()
})
''', 'Boo'
}
}
@@ -17,6 +17,7 @@ package org.jetbrains.idea.svn.actions;
import com.intellij.diff.DiffManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -52,7 +53,6 @@ import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
@@ -148,8 +148,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
myException = exc;
}
// since sometimes called from modal dialog (commit changes dialog)
SwingUtilities.invokeLater(new Runnable() {
TransactionGuard.submitTransaction(myProject, new Runnable() {
public void run() {
if (myException != null) {
Messages.showErrorDialog(myException.getMessage(), myErrorTitle);
@@ -11,7 +11,11 @@ import com.intellij.diff.tools.ErrorDiffTool;
import com.intellij.diff.util.DiffUtil;
import com.intellij.ide.DataManager;
import com.intellij.ide.impl.DataManagerImpl;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -295,7 +299,7 @@ public class SvnDiffViewer implements DiffViewer {
private class ToggleHidePropertiesAction extends ToggleAction implements DumbAware {
public ToggleHidePropertiesAction() {
EmptyAction.setupAction(this, "Subversion.TogglePropertiesDiff", null);
ActionUtil.copyFrom(this, "Subversion.TogglePropertiesDiff");
}
@Override
@@ -82,7 +82,7 @@ public class XmlChooseColorIntentionAction extends PsiElementBaseIntentionAction
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
final String newText = "#" + ColorUtil.toHex(color);
final PsiManager manager = literal.getManager();
final XmlAttribute newAttribute = XmlElementFactory.getInstance(manager.getProject()).createXmlAttribute("name", newText);
final XmlAttribute newAttribute = XmlElementFactory.getInstance(manager.getProject()).createAttribute("name", newText, element);
final Runnable replaceRunnable = new Runnable() {
@Override
public void run() {
@@ -68,7 +68,7 @@ public class AddAttributeValueIntentionFix extends LocalQuickFixAndIntentionActi
new WriteCommandAction(project) {
@Override
protected void run(@NotNull final Result result) {
final XmlAttribute attributeWithValue = XmlElementFactory.getInstance(getProject()).createXmlAttribute(attribute.getName(), "");
final XmlAttribute attributeWithValue = XmlElementFactory.getInstance(getProject()).createAttribute(attribute.getName(), "", startElement);
final PsiElement newAttribute = attribute.replace(attributeWithValue);
if (editor != null && newAttribute != null && newAttribute instanceof XmlAttribute && newAttribute.isValid()) {
@@ -33,7 +33,7 @@ public class XmlAttributeLiteralEscaper extends LiteralTextEscaper<XmlAttributeV
super(host);
PsiElement parent = host.getParent();
myXmlAttribute = parent instanceof XmlAttribute ? (XmlAttribute)parent :
XmlElementFactory.getInstance(host.getProject()).createXmlAttribute("a", host.getValue());
XmlElementFactory.getInstance(host.getProject()).createAttribute("a", host.getValue(), parent);
}
@Override
@@ -87,7 +87,7 @@ public class XmlAttributeImpl extends XmlElementImpl implements XmlAttribute, Hi
public void setValue(String valueText) throws IncorrectOperationException {
final ASTNode value = XmlChildRole.ATTRIBUTE_VALUE_FINDER.findChild(this);
final PomModel model = PomManager.getModel(getProject());
final XmlAttribute attribute = XmlElementFactory.getInstance(getProject()).createXmlAttribute("a", valueText);
final XmlAttribute attribute = XmlElementFactory.getInstance(getProject()).createAttribute("a", valueText, this);
final ASTNode newValue = XmlChildRole.ATTRIBUTE_VALUE_FINDER.findChild((ASTNode)attribute);
final XmlAspect aspect = model.getModelAspect(XmlAspect.class);
model.runTransaction(new PomTransactionBase(this, aspect) {
@@ -137,7 +137,7 @@ public class XmlAttributeValueImpl extends XmlElementImpl implements XmlAttribut
final String quoteChar = getTextLength() > 0 ? getText().substring(0, 1) : "";
String contents = StringUtil.containsAnyChar(quoteChar, "'\"") ?
StringUtil.trimEnd(StringUtil.trimStart(text, quoteChar), quoteChar) : text;
XmlAttribute newAttribute = XmlElementFactory.getInstance(getProject()).createXmlAttribute("q", contents);
XmlAttribute newAttribute = XmlElementFactory.getInstance(getProject()).createAttribute("q", contents, this);
XmlAttributeValue newValue = newAttribute.getValueElement();
CheckUtil.checkWritable(this);