diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index a708a6014d6d..b84d8ef19a71 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -2,18 +2,7 @@ - \ No newline at end of file diff --git a/.idea/libraries/winp.xml b/.idea/libraries/winp.xml new file mode 100644 index 000000000000..d0cfa26a9417 --- /dev/null +++ b/.idea/libraries/winp.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/build/lib/gant/jps-sources.zip b/build/lib/gant/jps-sources.zip index b3ba72d2b6f4..8fe522551467 100644 Binary files a/build/lib/gant/jps-sources.zip and b/build/lib/gant/jps-sources.zip differ diff --git a/build/lib/gant/lib/jps.jar b/build/lib/gant/lib/jps.jar index 57bf7b6b164e..ba0edbb05375 100644 Binary files a/build/lib/gant/lib/jps.jar and b/build/lib/gant/lib/jps.jar differ diff --git a/build/scripts/common_tests.gant b/build/scripts/common_tests.gant index d29059d66986..dd7794da93d4 100644 --- a/build/scripts/common_tests.gant +++ b/build/scripts/common_tests.gant @@ -38,6 +38,8 @@ target('default': 'The default target') { }; } + commonJvmArgs().each { jvmarg(value: it) } + if (isDefined("jvm_args")) { jvm_args.each { jvmarg(value: it) } } diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java index aea6261e8f2f..507e5a78ca58 100644 --- a/java/compiler/javac2/src/com/intellij/ant/Javac2.java +++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java @@ -32,14 +32,11 @@ import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.StringTokenizer; +import java.util.*; public class Javac2 extends Javac { private ArrayList myFormFiles; - private Path myNestedFormDirs; + private List myNestedFormPathList; public Javac2() { } @@ -170,34 +167,32 @@ public class Javac2 extends Javac { /** * Sets the nested form directories that will be used during the * compilation. - * @param nestedformdirs a path + * @param nestedformdirs a list of {@link PrefixedPath} */ - public void setNestedformdirs(Path nestedformdirs) { - if (myNestedFormDirs == null) { - myNestedFormDirs = nestedformdirs; - } else { - myNestedFormDirs.append(nestedformdirs); - } + public void setNestedformdirs(List nestedformdirs) { + myNestedFormPathList = nestedformdirs; } /** * Gets the nested form directories that will be used during the * compilation. - * @return the extension directories as a path + * @return the extension directories as a list of {@link PrefixedPath} */ - public Path getNestedformdirs() { - return myNestedFormDirs; + public List getNestedformdirs() { + return myNestedFormPathList; } /** * Adds a path to nested form directories. * @return a path to be configured */ - public Path createNestedformdirs() { - if (myNestedFormDirs == null) { - myNestedFormDirs = new Path(getProject()); + public PrefixedPath createNestedformdirs() { + PrefixedPath p = new PrefixedPath(getProject()); + if (myNestedFormPathList == null) { + myNestedFormPathList = new ArrayList(); } - return myNestedFormDirs.createPath(); + myNestedFormPathList.add(p); + return p; } /** @@ -287,8 +282,9 @@ public class Javac2 extends Javac { finally { stream.close(); } - final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, loader, new AntNestedFormLoader(loader, myNestedFormDirs), false, - new AntClassWriter(getAsmClassWriterFlags(version), loader)); + AntNestedFormLoader formLoader = new AntNestedFormLoader(loader, myNestedFormPathList); + AntClassWriter classWriter = new AntClassWriter(getAsmClassWriterFlags(version), loader); + final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, loader, formLoader, false, classWriter); codeGenerator.patchFile(classFile); final FormErrorInfo[] warnings = codeGenerator.getWarnings(); @@ -493,52 +489,44 @@ public class Javac2 extends Javac { private class AntNestedFormLoader implements NestedFormLoader { private final ClassLoader myLoader; - private final Path myNestedFormDirs; + private final List myNestedFormPathList; private final HashMap myFormCache = new HashMap(); - public AntNestedFormLoader(final ClassLoader loader, Path nestedFormDirs) { + public AntNestedFormLoader(final ClassLoader loader, List nestedFormPathList) { myLoader = loader; - myNestedFormDirs = nestedFormDirs; + myNestedFormPathList = nestedFormPathList; } - public LwRootContainer loadForm(String formFileName) throws Exception { - if (myFormCache.containsKey(formFileName)) { - return (LwRootContainer)myFormCache.get(formFileName); + public LwRootContainer loadForm(String formFilePath) throws Exception { + if (myFormCache.containsKey(formFilePath)) { + return (LwRootContainer)myFormCache.get(formFilePath); } - String formFileFullName = formFileName.toLowerCase(); - log("Searching for form " + formFileFullName, Project.MSG_VERBOSE); + + String lowerFormFilePath = formFilePath.toLowerCase(); + log("Searching for form " + lowerFormFilePath, Project.MSG_VERBOSE); for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) { File file = (File)iterator.next(); String name = file.getAbsolutePath().replace(File.separatorChar, '/').toLowerCase(); log("Comparing with " + name, Project.MSG_VERBOSE); - if (name.endsWith(formFileFullName)) { - return loadForm(formFileName, new FileInputStream(file)); + if (name.endsWith(lowerFormFilePath)) { + return loadForm(formFilePath, new FileInputStream(file)); } } - if (myNestedFormDirs != null) { - String[] list = myNestedFormDirs.list(); - for (int i = 0, listLength = list.length; i < listLength; i++) { - String formPath = list[i]; - if (!formPath.endsWith("/")) { - formPath += "/"; + + if (myNestedFormPathList != null) { + for (int i = 0; i < myNestedFormPathList.size(); i++) { + PrefixedPath path = (PrefixedPath)myNestedFormPathList.get(i); + File formFile = path.findFile(formFilePath); + if (formFile != null) { + return loadForm(formFilePath, new FileInputStream(formFile)); + } } - if (formFileFullName.startsWith("/")) { - formPath += formFileName.substring(1); - } - else { - formPath += formFileName; - } - File formFile = new File(formPath.replace('/', File.separatorChar)); - if (formFile.isFile()) { - return loadForm(formFileName, new FileInputStream(formFile)); - } - } } - InputStream resourceStream = myLoader.getResourceAsStream(formFileName); + InputStream resourceStream = myLoader.getResourceAsStream(formFilePath); if (resourceStream != null) { - return loadForm(formFileName, resourceStream); + return loadForm(formFilePath, resourceStream); } - throw new Exception("Cannot find nested form file " + formFileName); + throw new Exception("Cannot find nested form file " + formFilePath); } private LwRootContainer loadForm(String formFileName, InputStream resourceStream) throws Exception { diff --git a/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java b/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java new file mode 100644 index 000000000000..c7af4eb63613 --- /dev/null +++ b/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ant; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Path; + +import java.io.File; + +/** + * Allows to specify relative output prefix for Path. + * Used to support searching for nested form files under source roots with package prefixes. + * + * @author nik + */ +public class PrefixedPath extends Path { + private String myPrefix; + + public PrefixedPath(Project project) { + super(project); + } + + public PrefixedPath(Project p, String path) { + super(p, path); + } + + public String getPrefix() { + return myPrefix; + } + + public void setPrefix(String prefix) { + myPrefix = prefix; + } + + public File findFile(String relativePath) { + relativePath = trimStartSlash(relativePath); + String prefix = myPrefix; + if (prefix != null) { + prefix = trimStartSlash(ensureEndsWithSlash(prefix)); + if (!relativePath.toLowerCase().startsWith(prefix.toLowerCase())) { + return null; + } + relativePath = relativePath.substring(prefix.length()); + } + + String[] dirsList = list(); + for (int j = 0, listLength = dirsList.length; j < listLength; j++) { + String fullPath = ensureEndsWithSlash(dirsList[j]) + relativePath; + File file = new File(fullPath.replace('/', File.separatorChar)); + if (file.isFile()) { + return file; + } + } + return null; + } + + private static String trimStartSlash(String path) { + if (path.startsWith("/")) return path.substring(1); + return path; + } + + private static String ensureEndsWithSlash(String path) { + if (!path.endsWith("/")) return path + "/"; + return path; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java index e06812b6587a..ae3e603ccf70 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java @@ -48,11 +48,19 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { protected void invokeImpl(PsiClass targetClass) { assert ApplicationManager.getApplication().isWriteAccessAllowed(); - PsiNewExpression newExpression = getNewExpression(); + final PsiNewExpression newExpression = getNewExpression(); - PsiJavaCodeReferenceElement referenceElement = getReferenceElement(newExpression); - final PsiClass psiClass = CreateFromUsageUtils.createClass(referenceElement, CreateClassKind.CLASS, null); - setupClassFromNewExpression(psiClass, newExpression); + final PsiJavaCodeReferenceElement referenceElement = getReferenceElement(newExpression); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + final PsiClass psiClass = CreateFromUsageUtils.createClass(referenceElement, CreateClassKind.CLASS, null); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + setupClassFromNewExpression(psiClass, newExpression); + } + }); + } + }); } protected static void setupClassFromNewExpression(final PsiClass psiClass, final PsiNewExpression newExpression) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index fe27b82adea0..4bcc98095c95 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -41,6 +41,7 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -264,6 +265,7 @@ public class CreateFromUsageUtils { public static PsiClass createClass(final PsiJavaCodeReferenceElement referenceElement, final CreateClassKind classKind, final String superClassName) { + assert !ApplicationManager.getApplication().isWriteAccessAllowed(); final String name = referenceElement.getReferenceName(); final PsiElement qualifierElement; @@ -274,23 +276,7 @@ public class CreateFromUsageUtils { return ApplicationManager.getApplication().runWriteAction( new Computable() { public PsiClass compute() { - try { - PsiClass psiClass = (PsiClass) qualifierElement; - if (!CodeInsightUtilBase.preparePsiElementForWrite(psiClass)) return null; - - PsiManager manager = psiClass.getManager(); - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - PsiClass result = classKind == INTERFACE ? elementFactory.createInterface(name) : - classKind == CLASS ? elementFactory.createClass(name) : - elementFactory.createEnum(name); - CreateFromUsageBaseFix.setupGenericParameters(result, referenceElement); - result = (PsiClass)manager.getCodeStyleManager().reformat(result); - return (PsiClass) psiClass.add(result); - } - catch (IncorrectOperationException e) { - LOG.error(e); - return null; - } + return createClassInQualifier((PsiClass)qualifierElement, classKind, name, referenceElement); } }); } @@ -302,20 +288,7 @@ public class CreateFromUsageUtils { final PsiManager manager = referenceElement.getManager(); final PsiFile sourceFile = referenceElement.getContainingFile(); final Module module = ModuleUtil.findModuleForPsiElement(sourceFile); - PsiPackage aPackage = null; - if (qualifierElement instanceof PsiPackage) { - aPackage = (PsiPackage)qualifierElement; - } - else { - final PsiDirectory directory = sourceFile.getContainingDirectory(); - if (directory != null) { - aPackage = JavaDirectoryService.getInstance().getPackage(directory); - } - - if (aPackage == null) { - aPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(""); - } - } + PsiPackage aPackage = findTargetPackage(qualifierElement, manager, sourceFile); if (aPackage == null) return null; final PsiDirectory targetDirectory; if (!ApplicationManager.getApplication().isUnitTestMode()) { @@ -335,6 +308,48 @@ public class CreateFromUsageUtils { return createClass(classKind, targetDirectory, name, manager, referenceElement, sourceFile, superClassName); } + @Nullable + public static PsiPackage findTargetPackage(PsiElement qualifierElement, PsiManager manager, PsiFile sourceFile) { + PsiPackage aPackage = null; + if (qualifierElement instanceof PsiPackage) { + aPackage = (PsiPackage)qualifierElement; + } + else { + final PsiDirectory directory = sourceFile.getContainingDirectory(); + if (directory != null) { + aPackage = JavaDirectoryService.getInstance().getPackage(directory); + } + + if (aPackage == null) { + aPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(""); + } + } + if (aPackage == null) return null; + return aPackage; + } + + public static PsiClass createClassInQualifier(PsiClass psiClass, + CreateClassKind classKind, + String name, + PsiJavaCodeReferenceElement referenceElement) { + try { + if (!CodeInsightUtilBase.preparePsiElementForWrite(psiClass)) return null; + + PsiManager manager = psiClass.getManager(); + PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + PsiClass result = classKind == INTERFACE ? elementFactory.createInterface(name) : + classKind == CLASS ? elementFactory.createClass(name) : + elementFactory.createEnum(name); + CreateFromUsageBaseFix.setupGenericParameters(result, referenceElement); + result = (PsiClass)manager.getCodeStyleManager().reformat(result); + return (PsiClass) psiClass.add(result); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return null; + } + } + public static PsiClass createClass(final CreateClassKind classKind, final PsiDirectory directory, final String name, diff --git a/java/java-impl/src/com/intellij/pom/java/impl/PomJavaAspectImpl.java b/java/java-impl/src/com/intellij/pom/java/impl/PomJavaAspectImpl.java index e3d0276469e1..a35bb8ec0771 100644 --- a/java/java-impl/src/com/intellij/pom/java/impl/PomJavaAspectImpl.java +++ b/java/java-impl/src/com/intellij/pom/java/impl/PomJavaAspectImpl.java @@ -23,7 +23,6 @@ import com.intellij.pom.PomModelAspect; import com.intellij.pom.event.PomModelEvent; import com.intellij.pom.java.LanguageLevel; import com.intellij.pom.java.PomJavaAspect; -import com.intellij.pom.java.events.JavaTreeChanged; import com.intellij.pom.java.events.PomJavaAspectChangeSet; import com.intellij.pom.tree.TreeAspect; import com.intellij.pom.tree.events.TreeChangeEvent; @@ -69,7 +68,6 @@ public class PomJavaAspectImpl extends PomJavaAspect implements ProjectComponent final PsiFile containingFile = changeSet.getRootElement().getPsi().getContainingFile(); if(!(containingFile.getLanguage() instanceof JavaLanguage)) return; final PomJavaAspectChangeSet set = new PomJavaAspectChangeSet(myPomModel); - set.addChange(new JavaTreeChanged(containingFile)); event.registerChangeSet(this, set); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java index ed62d32ba2cd..81c76b2737c8 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java @@ -78,8 +78,8 @@ public class PsiSuperMethodImplUtil { @NotNull private static List findSuperMethodSignatures(PsiMethod method, - PsiClass parentClass, - boolean allowStaticMethod) { + PsiClass parentClass, + boolean allowStaticMethod) { return new ArrayList(SuperMethodsSearch.search(method, parentClass, true, allowStaticMethod).findAll()); } @@ -306,4 +306,58 @@ public class PsiSuperMethodImplUtil { private static Map getSignaturesMap(final PsiClass aClass) { return SIGNATURES_KEY.getValue(aClass); } + + + // uses hierarchy signature tree if available, traverses class structure by itself otherwise + public static boolean isSuperMethodSmart(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) { + //boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod); + + if (method == superMethod) return false; + PsiClass aClass = method.getContainingClass(); + PsiClass superClass = superMethod.getContainingClass(); + + if (aClass == null || superClass == null || superClass == aClass) return false; + + if (!canHaveSuperMethod(method, true, false)) return false; + + PsiMethod[] superMethods = null; + Map cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass); + if (cachedMap != null) { + HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY)); + if (signature != null) { + superMethods = MethodSignatureUtil.convertMethodSignaturesToMethods(signature.getSuperSignatures()); + } + } + if (superMethods == null) { + PsiClassType[] directSupers = aClass.getSuperTypes(); + List found = null; + boolean canceled = false; + for (PsiClassType directSuper : directSupers) { + PsiClassType.ClassResolveResult resolveResult = directSuper.resolveGenerics(); + if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) { + // generics + canceled = true; + break; + } + PsiClass directSuperClass = resolveResult.getElement(); + if (directSuperClass == null) continue; + PsiMethod[] candidates = directSuperClass.findMethodsBySignature(method, false); + if (candidates.length != 0) { + if (found == null) found = new ArrayList(); + for (PsiMethod candidate : candidates) { + if (PsiUtil.canBeOverriden(candidate)) found.add(candidate); + } + } + } + superMethods = canceled ? null : found == null ? PsiMethod.EMPTY_ARRAY : found.toArray(new PsiMethod[found.size()]); + } + if (superMethods == null) { + superMethods = MethodSignatureUtil.convertMethodSignaturesToMethods(method.getHierarchicalMethodSignature().getSuperSignatures()); + } + + for (PsiMethod superCandidate : superMethods) { + if (superMethod.equals(superCandidate) || isSuperMethodSmart(superCandidate, superMethod)) return true; + } + return false; + } } diff --git a/java/java-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java b/java/java-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java index 11ce35a12791..992c7920cdfe 100644 --- a/java/java-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java +++ b/java/java-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java @@ -39,11 +39,11 @@ public class MethodSuperSearcher implements QueryExecutor consumer) { + final PsiMethod method, + final PsiClass parentClass, + final boolean allowStaticMethod, + final boolean checkBases, + final Processor consumer) { PsiMethod signatureMethod = signature.getMethod(); PsiClass hisClass = signatureMethod.getContainingClass(); if (parentClass == null || InheritanceUtil.isInheritorOrSelf(parentClass, hisClass, true)) { diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java index ae32fccd1998..0d59b5ed8367 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java @@ -49,7 +49,7 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { } @NotNull - public SmartTypePointer createSmartTypePointer(PsiType type) { + public SmartTypePointer createSmartTypePointer(@NotNull PsiType type) { return type.accept(new SmartTypeCreatingVisitor()); } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index d85d4a99a724..b49ea654f6dd 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -332,6 +332,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements public boolean isReferenceTo(PsiElement element) { IElementType i = getLastChildNode().getElementType(); + boolean resolvingToMethod = element instanceof PsiMethod; if (i == JavaTokenType.IDENTIFIER) { if (!(element instanceof PsiPackage)) { if (!(element instanceof PsiNamedElement)) return false; @@ -341,10 +342,15 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements } } else if (i == JavaTokenType.SUPER_KEYWORD || i == JavaTokenType.THIS_KEYWORD) { - if (!(element instanceof PsiMethod)) return false; + if (!resolvingToMethod) return false; if (!((PsiMethod)element).isConstructor()) return false; } + PsiElement parent = getParent(); + boolean parentIsMethodCall = parent instanceof PsiMethodCallExpression; + // optimization: methodCallExpression should resolve to a method + if (parentIsMethodCall != resolvingToMethod) return false; + return element.getManager().areElementsEquivalent(element, resolve()); } diff --git a/java/java-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index f324999ba9a7..db990d48f565 100644 --- a/java/java-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiSuperMethodImplUtil; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.scope.PsiConflictResolver; @@ -150,7 +151,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ if (!method.hasModifierProperty(PsiModifier.STATIC)) { for (int k=i-1; k>=0; k--) { PsiMethod existingMethod = (PsiMethod)conflicts.get(k).getElement(); - if (PsiSuperMethodUtil.isSuperMethod(existingMethod, method)) { + if (PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) { conflicts.remove(i); i--; continue nextConflict; @@ -189,12 +190,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ // filter out methods with incorrect inferred bounds (for unrelated methods only) boolean existingTypeParamAgree = areTypeParametersAgree(existing); boolean infoTypeParamAgree = areTypeParametersAgree(info); - if (existingTypeParamAgree && !infoTypeParamAgree && !PsiSuperMethodUtil.isSuperMethod(method, existingMethod)) { + if (existingTypeParamAgree && !infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(method, existingMethod)) { conflicts.remove(i); i--; continue; } - else if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodUtil.isSuperMethod(existingMethod, method)) { + else if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) { signatures.put(signature, info); int index = conflicts.indexOf(existing); conflicts.remove(index); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index 22314744e177..af3944e140d3 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -35,7 +35,6 @@ import com.intellij.ide.util.PackageUtil; import com.intellij.ide.util.PsiClassListCellRenderer; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -230,7 +229,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase JavaCodeStyleManager.getInstance(field.getProject()).shortenClassReferences(field); } - private static PsiElement getPhysicalElement(final PsiExpression selectedExpr) { + public static PsiElement getPhysicalElement(final PsiExpression selectedExpr) { PsiElement element = selectedExpr.getUserData(ElementToWorkOn.PARENT); if (element == null) element = selectedExpr; return element; @@ -677,32 +676,8 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase createField(myFieldName, myType, initializer, initializerPlace == InitializationPlace.IN_FIELD_DECLARATION && initializer != null, myParentClass); - PsiElement finalAnchorElement = null; - if (destClass == myParentClass) { - for (finalAnchorElement = myAnchorElement; - finalAnchorElement != null && finalAnchorElement.getParent() != destClass; - finalAnchorElement = finalAnchorElement.getParent()) { - - } - } - PsiMember anchorMember = finalAnchorElement instanceof PsiMember ? (PsiMember)finalAnchorElement : null; setModifiers(myField, mySettings, mySettings.isDeclareStatic()); - if ((anchorMember instanceof PsiField) && - anchorMember.hasModifierProperty(PsiModifier.STATIC) == myField.hasModifierProperty(PsiModifier.STATIC)) { - myField = (PsiField)destClass.addBefore(myField, anchorMember); - } - else if (anchorMember instanceof PsiClassInitializer) { - myField = (PsiField)destClass.addBefore(myField, anchorMember); - destClass.addBefore(CodeEditUtil.createLineFeed(myField.getManager()), anchorMember); - } - else { - final PsiField forwardReference = checkForwardRefs(initializer); - if (forwardReference != null) { - myField = (PsiField)destClass.addAfter(myField, forwardReference); - } else { - myField = (PsiField)destClass.add(myField); - } - } + myField = appendField(initializer, destClass, myParentClass, myAnchorElement, myField); if (!mySettings.isIntroduceEnumConstant()) { VisibilityUtil.fixVisibility(myOccurrences, myField, mySettings.getFieldVisibility()); } @@ -800,7 +775,42 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase } } - private PsiField checkForwardRefs(PsiExpression initializer) { + static PsiField appendField(final PsiExpression initializer, + final PsiClass destClass, + final PsiClass parentClass, + final PsiElement anchorElement, + final PsiField psiField) { + PsiElement finalAnchorElement = null; + if (destClass == parentClass) { + for (finalAnchorElement = anchorElement; + finalAnchorElement != null && finalAnchorElement.getParent() != destClass; + finalAnchorElement = finalAnchorElement.getParent()) { + + } + } + PsiMember anchorMember = finalAnchorElement instanceof PsiMember ? (PsiMember)finalAnchorElement : null; + + if ((anchorMember instanceof PsiField) && + anchorMember.hasModifierProperty(PsiModifier.STATIC) == psiField.hasModifierProperty(PsiModifier.STATIC)) { + return (PsiField)destClass.addBefore(psiField, anchorMember); + } + else if (anchorMember instanceof PsiClassInitializer) { + + PsiField field = (PsiField)destClass.addBefore(psiField, anchorMember); + destClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), anchorMember); + return field; + } + else { + final PsiField forwardReference = checkForwardRefs(initializer, parentClass); + if (forwardReference != null) { + return (PsiField)destClass.addAfter(psiField, forwardReference); + } else { + return (PsiField)destClass.add(psiField); + } + } + } + + private static PsiField checkForwardRefs(PsiExpression initializer, final PsiClass parentClass) { final PsiField[] refConstantFields = new PsiField[1]; initializer.accept(new JavaRecursiveElementWalkingVisitor() { @Override @@ -809,7 +819,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase final PsiElement resolve = expression.resolve(); if (resolve instanceof PsiField && ((PsiField)resolve).hasModifierProperty(PsiModifier.FINAL) && - PsiTreeUtil.isAncestor(myParentClass, resolve, false) && ((PsiField)resolve).hasInitializer()) { + PsiTreeUtil.isAncestor(parentClass, resolve, false) && ((PsiField)resolve).hasInitializer()) { if (refConstantFields[0] == null || refConstantFields[0].getTextOffset() < resolve.getTextOffset()) { refConstantFields[0] = (PsiField)resolve; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index 5a57f1df3377..987c40445702 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -24,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.util.Computable; @@ -62,9 +63,9 @@ public class InplaceIntroduceConstantPopup { private final PsiLocalVariable myLocalVariable; private final PsiExpression[] myOccurrences; private final TypeSelectorManagerImpl myTypeSelectorManager; - private final PsiElement myAnchorElement; + private PsiElement myAnchorElement; private int myAnchorIdx = -1; - private final PsiElement myAnchorElementIfAll; + private PsiElement myAnchorElementIfAll; private int myAnchorIdxIfAll = -1; private final OccurenceManager myOccurenceManager; @@ -116,7 +117,7 @@ public class InplaceIntroduceConstantPopup { } myOccurenceManager = occurenceManager; - myExprMarker = expr != null ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null; + myExprMarker = expr != null && expr.isPhysical() ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null; myExprText = expr != null ? expr.getText() : null; myLocalName = localVariable != null ? localVariable.getName() : null; @@ -200,6 +201,7 @@ public class InplaceIntroduceConstantPopup { final PsiField field = createFieldToStartTemplateOn(names, defaultType); if (field != null) { myEditor.getCaretModel().moveToOffset(field.getTextOffset()); + myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); final LinkedHashSet nameSuggestions = new LinkedHashSet(); nameSuggestions.add(field.getName()); nameSuggestions.addAll(Arrays.asList(names)); @@ -215,10 +217,10 @@ public class InplaceIntroduceConstantPopup { return ApplicationManager.getApplication().runWriteAction(new Computable() { @Override public PsiField compute() { - PsiField field = elementFactory.createField(myConstantName != null ? myConstantName : names[0], psiType); - field = (PsiField)myParentClass.add(field); + PsiField field = elementFactory.createFieldFromText(psiType.getCanonicalText() + " " + (myConstantName != null ? myConstantName : names[0]) + " = " + myExprText + ";", myParentClass); PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true); PsiUtil.setModifierProperty(field, PsiModifier.STATIC, true); + field = BaseExpressionToFieldHandler.ConvertToFieldRunnable.appendField(myExpr, myParentClass, myParentClass, myAnchorElementIfAll, field); return field; } }); @@ -255,7 +257,7 @@ public class InplaceIntroduceConstantPopup { super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), myEditor, field, false, myTypeSelectorManager.getTypesForAll().length > 1, - myExpr != null ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers()); + myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers()); myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType()); @@ -269,7 +271,7 @@ public class InplaceIntroduceConstantPopup { @Override protected PsiExpression getExpr() { - return myExpr; + return myExpr != null && myExpr.isValid() && myExpr.isPhysical() ? myExpr : null; } @Override @@ -319,20 +321,23 @@ public class InplaceIntroduceConstantPopup { myFieldTypePointer.getType(), isDeleteVariable(), myParentClass, isAnnotateNonNls(), false); - if (myLocalVariable != null) { - final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = - new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, true, myOccurrences); - fieldRunnable.run(); - } - else { - final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable = - new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(), - myOccurrences, myOccurenceManager, - myAnchorIdxIfAll != -1? myOccurrences[myAnchorIdxIfAll].getParent() : myAnchorElementIfAll, - myAnchorIdx != -1 ? myOccurrences[myAnchorIdx].getParent() : myAnchorElement, myEditor, - myParentClass); - convertToFieldRunnable.run(); - } + final Runnable runnable = new Runnable() { + public void run() { + if (myLocalVariable != null) { + final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = + new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, true, myOccurrences); + fieldRunnable.run(); + } + else { + final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable = + new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(), + myOccurrences, myOccurenceManager, + myAnchorElementIfAll, myAnchorElement, myEditor, myParentClass); + convertToFieldRunnable.run(); + } + } + }; + ApplicationManager.getApplication().runWriteAction(runnable); } super.moveOffsetAfter(success); if (myMoveToAnotherClassCb.isSelected()) { @@ -389,9 +394,12 @@ public class InplaceIntroduceConstantPopup { public void run() { final PsiFile containingFile = myParentClass.getContainingFile(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); - myExpr = restoreExpression(containingFile, psiField, elementFactory, getExprMarker(), myExprText); - if (myExpr != null) { - myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange()); + final RangeMarker exprMarker = getExprMarker(); + if (exprMarker != null) { + myExpr = restoreExpression(containingFile, psiField, elementFactory, exprMarker, myExprText); + if (myExpr != null && myExpr.isPhysical()) { + myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange()); + } } final List occurrenceMarkers = getOccurrenceMarkers(); for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) { @@ -405,6 +413,14 @@ public class InplaceIntroduceConstantPopup { myOccurrences[i] = psiExpression; } } + + if (myAnchorIdxIfAll != -1) { + myAnchorElementIfAll = myOccurrences[myAnchorIdxIfAll].getParent(); + } + + if (myAnchorIdx != -1) { + myAnchorElement = myOccurrences[myAnchorIdx].getParent(); + } myOccurrenceMarkers = null; if (psiField.isValid()) { psiField.delete(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index 9c36c46c83e4..c5bb407d8646 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.psi.*; @@ -95,7 +96,7 @@ public class InplaceIntroduceFieldPopup { myInitializerExpression = initializerExpression; myExprText = myInitializerExpression != null ? myInitializerExpression.getText() : null; myLocalName = localVariable != null ? localVariable.getName() : null; - myExprMarker = myInitializerExpression != null ? editor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null; + myExprMarker = myInitializerExpression != null && myInitializerExpression.isPhysical() ? editor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null; myTypeSelectorManager = typeSelectorManager; myAnchorElement = anchorElement; myAnchorElementIfAll = anchorElementIfAll; @@ -176,6 +177,7 @@ public class InplaceIntroduceFieldPopup { final PsiField field = createFieldToStartTemplateOn(suggestedNameInfo.names, defaultType); if (field != null) { myEditor.getCaretModel().moveToOffset(field.getTextOffset()); + myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); final LinkedHashSet nameSuggestions = new LinkedHashSet(); nameSuggestions.add(field.getName()); nameSuggestions.addAll(Arrays.asList(suggestedNameInfo.names)); @@ -233,7 +235,7 @@ public class InplaceIntroduceFieldPopup { super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), myEditor, psiVariable, false, myTypeSelectorManager.getTypesForAll().length > 1, - myInitializerExpression != null ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers()); + myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers()); myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType()); myFieldRangeStart = myEditor.getDocument().createRangeMarker(psiVariable.getTextRange()); @@ -246,7 +248,7 @@ public class InplaceIntroduceFieldPopup { @Override protected PsiExpression getExpr() { - return myInitializerExpression; + return myInitializerExpression != null && myInitializerExpression.isValid() && myInitializerExpression.isPhysical() ? myInitializerExpression : null; } @Override @@ -318,20 +320,25 @@ public class InplaceIntroduceFieldPopup { myFieldTypePointer.getType(), myIntroduceFieldPanel.isDeleteVariable(), myParentClass, false, false); - if (myLocalVariable != null) { - final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = - new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, myStatic, myOccurrences); - fieldRunnable.run(); - } - else { - final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable = - new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myInitializerExpression, settings, settings.getForcedType(), - myOccurrences, myOccurenceManager, - myAnchorIdxIfAll != -1? myOccurrences[myAnchorIdxIfAll].getParent() : myAnchorElementIfAll, - myAnchorIdx != -1 ? myOccurrences[myAnchorIdx].getParent() : myAnchorElement, myEditor, - myParentClass); - convertToFieldRunnable.run(); - } + final Runnable runnable = new Runnable() { + public void run() { + if (myLocalVariable != null) { + final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = + new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, myStatic, myOccurrences); + fieldRunnable.run(); + } + else { + final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable = + new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myInitializerExpression, settings, settings.getForcedType(), + myOccurrences, myOccurenceManager, + myAnchorIdxIfAll != -1? myOccurrences[myAnchorIdxIfAll].getParent() : myAnchorElementIfAll, + myAnchorIdx != -1 ? myOccurrences[myAnchorIdx].getParent() : myAnchorElement, myEditor, + myParentClass); + convertToFieldRunnable.run(); + } + } + }; + ApplicationManager.getApplication().runWriteAction(runnable); } super.moveOffsetAfter(success); } @@ -349,9 +356,11 @@ public class InplaceIntroduceFieldPopup { public void run() { final PsiFile containingFile = myParentClass.getContainingFile(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); - myInitializerExpression = restoreExpression(containingFile, psiField, elementFactory, getExprMarker(), myExprText); - if (myInitializerExpression != null) { - myExprMarker = myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()); + if (getExprMarker() != null) { + myInitializerExpression = restoreExpression(containingFile, psiField, elementFactory, getExprMarker(), myExprText); + if (myInitializerExpression != null) { + myExprMarker = myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()); + } } final List occurrenceMarkers = getOccurrenceMarkers(); for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index 7e7606ad7612..a63f7a2a676f 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.psi.*; @@ -135,6 +136,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { if (parameter != null) { myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter); myEditor.getCaretModel().moveToOffset(parameter.getTextOffset()); + myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); final LinkedHashSet nameSuggestions = new LinkedHashSet(); nameSuggestions.add(parameter.getName()); nameSuggestions.addAll(Arrays.asList(names)); @@ -247,20 +249,25 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { getReplaceFieldsWithGetters(), myMustBeFinal || myFinal, isGenerateDelegate(), myParameterTypePointer.getType(), parametersToRemove); - ApplicationManager.getApplication().invokeLater(new Runnable() { + final Runnable runnable = new Runnable() { public void run() { - final boolean [] conflictsFound = new boolean[] {true}; - processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { - @Override + ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { - conflictsFound[0] = processor.hasConflicts(); + final boolean [] conflictsFound = new boolean[] {true}; + processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { + @Override + public void run() { + conflictsFound[0] = processor.hasConflicts(); + } + }); + processor.run(); + normalizeParameterIdxAccordingToRemovedParams(parametersToRemove); + ParameterInplaceIntroducer.super.moveOffsetAfter(!conflictsFound[0]); } }); - processor.run(); - normalizeParameterIdxAccordingToRemovedParams(parametersToRemove); - ParameterInplaceIntroducer.super.moveOffsetAfter(!conflictsFound[0]); } - }); + }; + CommandProcessor.getInstance().executeCommand(myProject, runnable, IntroduceParameterHandler.REFACTORING_NAME, null); } else { super.moveOffsetAfter(success); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index e75a44e48d8b..001e566b46c3 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -90,7 +90,11 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme final PsiElement[] statementsInRange = findStatementsAtOffset(editor, file, offset); //try line selection - if (statementsInRange.length == 1 && (PsiUtil.hasErrorElementChild(statementsInRange[0]) || !PsiUtil.isStatement(statementsInRange[0]) || isPreferStatements())) { + if (statementsInRange.length == 1 && (PsiUtil.hasErrorElementChild(statementsInRange[0]) || + !PsiUtil.isStatement(statementsInRange[0]) || + statementsInRange[0].getTextRange().getStartOffset() >= offset || + statementsInRange[0].getTextRange().getEndOffset() <= offset || + isPreferStatements())) { selectionModel.selectLineAtCaret(); if (findExpressionInRange(project, file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()) == null) { selectionModel.removeSelection(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java index 2e05d7203321..890fae8445d1 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableInplaceIntroducer.java @@ -28,10 +28,7 @@ import com.intellij.ide.IdeTooltipManager; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.application.*; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.editor.*; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; @@ -55,6 +52,7 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.ui.TitlePanel; import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.ui.PositionTracker; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -161,8 +159,9 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { @Override public boolean performInplaceRename(boolean processTextOccurrences, LinkedHashSet nameSuggestions) { + final boolean result = super.performInplaceRename(processTextOccurrences, nameSuggestions); showBalloon(); - return super.performInplaceRename(processTextOccurrences, nameSuggestions); + return result; } public RangeMarker getExprMarker() { @@ -180,10 +179,10 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { } saveSettings(psiVariable); adjustLine(psiVariable, document); - int startOffset = myExprMarker != null ? myExprMarker.getStartOffset() : psiVariable.getTextOffset(); + int startOffset = myExprMarker != null && myExprMarker.isValid() ? myExprMarker.getStartOffset() : psiVariable.getTextOffset(); final PsiFile file = psiVariable.getContainingFile(); final PsiReference referenceAt = file.findReferenceAt(startOffset); - if (referenceAt != null && referenceAt.resolve() instanceof PsiLocalVariable) { + if (referenceAt != null && referenceAt.resolve() instanceof PsiVariable) { startOffset = referenceAt.getElement().getTextRange().getEndOffset(); } else { @@ -193,6 +192,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { } } myEditor.getCaretModel().moveToOffset(startOffset); + myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); if (psiVariable.getInitializer() != null) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { @@ -353,7 +353,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { if (ApplicationManager.getApplication().isHeadlessEnvironment()) return; final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(component); balloonBuilder.setFadeoutTime(0) - .setFillColor(IdeTooltipManager.GRAPHITE_COLOR) + .setFillColor(IdeTooltipManager.GRAPHITE_COLOR.brighter().brighter()) .setAnimationCycle(0) .setHideOnClickOutside(false) .setHideOnKeyOutside(false) @@ -363,8 +363,11 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer { final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor); final Point screenPoint = target.getScreenPoint(); myBalloon = balloonBuilder.createBalloon(); - myBalloon - .show(new RelativePoint(new Point(screenPoint.x, screenPoint.y - myEditor.getLineHeight())), Balloon.Position.above); + int y = screenPoint.y; + if (target.getPoint().getY() > myEditor.getLineHeight() + myBalloon.getPreferredSize().getHeight()) { + y -= myEditor.getLineHeight(); + } + myBalloon.show(new RelativePoint(new Point(screenPoint.x, y)), Balloon.Position.above); } public class FinalListener implements ActionListener { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index 9cd7922962fb..982615d1afb6 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -33,7 +33,10 @@ import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.FileReferenceContextUtil; import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler; +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil; import com.intellij.refactoring.rename.RenameUtil; import com.intellij.refactoring.util.NonCodeUsageInfo; import com.intellij.refactoring.util.RefactoringUIUtil; @@ -182,6 +185,7 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor Messages.showErrorDialog(myProject, e.getMessage(), CommonBundle.getErrorTitle()); return; } + final List movedFiles = new ArrayList(); final Map oldToNewElementsMapping = new HashMap(); for (PsiFile psiFile : myFilesToMove.keySet()) { ChangeContextUtil.encodeContextInfo(psiFile, true); @@ -195,7 +199,14 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor } } else { if (!moveDestination.equals(psiFile.getContainingDirectory())) { - psiFile.getManager().moveFile(psiFile, moveDestination); + MoveFileHandler.forElement(psiFile).prepareMovedFile(psiFile, moveDestination, oldToNewElementsMapping); + + PsiFile moving = moveDestination.findFile(psiFile.getName()); + if (moving == null) { + MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, moveDestination); + } + moving = moveDestination.findFile(psiFile.getName()); + movedFiles.add(moving); listener.elementMoved(psiFile); } } @@ -212,6 +223,12 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor } } } + // fix references in moved files to outer files + for (PsiFile movedFile : movedFiles) { + MoveFileHandler.forElement(movedFile).updateMovedFile(movedFile); + FileReferenceContextUtil.decodeFileReferences(movedFile); + } + for (PsiDirectory directory : myDirectories) { directory.delete(); } diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java index 3274ef48af16..12223a532047 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java @@ -40,6 +40,7 @@ import com.intellij.usageView.UsageInfo; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.util.*; @@ -765,28 +766,30 @@ public class TypeMigrationLabeler { return refs; } + @TestOnly public String getMigrationReport() { - final StringBuffer buffer = new StringBuffer(); + final StringBuilder buffer = new StringBuilder(); + + buffer.append("Types:\n").append(getTypeEvaluator().getReport()).append("\n"); - buffer.append("Types:\n" + getTypeEvaluator().getReport() + "\n"); buffer.append("Conversions:\n"); final String[] conversions = new String[myConversions.size()]; int k = 0; for (final PsiElement expr : myConversions.keySet()) { - final Object conv = myConversions.get(expr); + final Object conversion = myConversions.get(expr); - if (conv instanceof Pair && ((Pair)conv).first == null) { - conversions[k++] = (expr.getText() + " -> " + ((Pair)conv).second + "\n"); + if (conversion instanceof Pair && ((Pair)conversion).first == null) { + conversions[k++] = (expr.getText() + " -> " + ((Pair)conversion).second + "\n"); } else { - conversions[k++] = (expr.getText() + " -> " + conv + "\n"); + conversions[k++] = (expr.getText() + " -> " + conversion + "\n"); } } - Arrays.sort(conversions, new Comparator() { - public int compare(Object x, Object y) { - return ((String)x).compareTo((String)y); + Arrays.sort(conversions, new Comparator() { + public int compare(String x, String y) { + return x.compareTo(y); } }); @@ -796,23 +799,22 @@ public class TypeMigrationLabeler { buffer.append("\nNew expression type changes:\n"); - final String[] newchanges = new String[myNewExpressionTypeChange.size()]; + final String[] newChanges = new String[myNewExpressionTypeChange.size()]; k = 0; for (final Map.Entry entry : myNewExpressionTypeChange.entrySet()) { - - - newchanges[k++] = entry.getKey().getElement().getText() + " -> " + entry.getValue().getCanonicalText() + "\n"; + final PsiElement element = entry.getKey().getElement(); + newChanges[k++] = (element != null ? element.getText() : entry.getKey()) + " -> " + entry.getValue().getCanonicalText() + "\n"; } - Arrays.sort(newchanges, new Comparator() { - public int compare(Object x, Object y) { - return ((String)x).compareTo((String)y); + Arrays.sort(newChanges, new Comparator() { + public int compare(String x, String y) { + return x.compareTo(y); } }); - for (String newchange : newchanges) { - buffer.append(newchange); + for (String change : newChanges) { + buffer.append(change); } buffer.append("Fails:\n"); @@ -830,13 +832,12 @@ public class TypeMigrationLabeler { for (final Pair p : failsList) { final PsiElement element = p.getFirst().retrieve(); if (element != null) { - buffer.append(element.getText() + "->" + p.getSecond().getCanonicalText() + "\n"); + buffer.append(element.getText()).append("->").append(p.getSecond().getCanonicalText()).append("\n"); } } return buffer.toString(); } - public static class MigrateException extends RuntimeException { - } + public static class MigrateException extends RuntimeException { } } diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationRules.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationRules.java index da50f51dbd71..9ba8ddbf3fbd 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationRules.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationRules.java @@ -63,8 +63,8 @@ public class TypeMigrationRules { @NonNls @Nullable - public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, PsiMember member, final PsiExpression context, final boolean isCovariantPosition, - final TypeMigrationLabeler labeler) { + public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context, + final boolean isCovariantPosition, final TypeMigrationLabeler labeler) { final TypeConversionDescriptorBase conversion = findConversion(from, to, member, context, labeler); if (conversion != null) return conversion; @@ -74,12 +74,13 @@ public class TypeMigrationRules { } if (TypeConversionUtil.isAssignable(to, from)) return new TypeConversionDescriptorBase(); } - if (!isCovariantPosition && TypeConversionUtil.isAssignable(from, to)) return new TypeConversionDescriptorBase(); - return null; + + return !isCovariantPosition && TypeConversionUtil.isAssignable(from, to) ? new TypeConversionDescriptorBase() : null; } @Nullable - public TypeConversionDescriptorBase findConversion(PsiType from, PsiType to, PsiMember member, PsiExpression context, TypeMigrationLabeler labeler) { + public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, + final PsiExpression context, final TypeMigrationLabeler labeler) { for (TypeConversionRule descriptor : myConversionRules) { final TypeConversionDescriptorBase conversion = descriptor.findConversion(from, to, member, context, labeler); if (conversion != null) return conversion; @@ -96,7 +97,8 @@ public class TypeMigrationRules { } @Nullable - public Pair bindTypeParameters(final PsiType from, final PsiType to, final PsiMethod method, final PsiExpression context, final TypeMigrationLabeler labeler) { + public Pair bindTypeParameters(final PsiType from, final PsiType to, final PsiMethod method, + final PsiExpression context, final TypeMigrationLabeler labeler) { for (TypeConversionRule conversionRule : myConversionRules) { final Pair typePair = conversionRule.bindTypeParameters(from, to, method, context, labeler); if (typePair != null) return typePair; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after6.java index c791df6fc625..2ee20246b298 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after6.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after6.java @@ -3,7 +3,7 @@ public class Test { public static void main() { Collection[] cc = new MyCollection[10]; } -} +} -public class MyCollection { +public class MyCollection { } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after8.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after8.java index e1e4712ec0c1..e4761ed3c0ca 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after8.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/after8.java @@ -6,7 +6,7 @@ public class Test { public static void main() { JTable table = new JTable(new MyTableModel()); } -} +} -public class MyTableModel implements TableModel { +public class MyTableModel implements TableModel { } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/afterGenerics.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/afterGenerics.java index aea3f7e011f6..3cae4d83de95 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/afterGenerics.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createClassFromNew/afterGenerics.java @@ -3,7 +3,7 @@ class Test { void foo () { new Generic (); } -} +} -public class Generic { +public class Generic { } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/pom/java/events/JavaTreeChanged.java b/java/openapi/src/com/intellij/pom/java/events/JavaTreeChanged.java deleted file mode 100644 index b948b33129b9..000000000000 --- a/java/openapi/src/com/intellij/pom/java/events/JavaTreeChanged.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.pom.java.events; - -import com.intellij.psi.PsiFile; - -public class JavaTreeChanged implements PomJavaChange { - private final PsiFile myFile; - - public JavaTreeChanged(final PsiFile file) { - myFile = file; - } - - public PsiFile getFile() { - return myFile; - } - -} diff --git a/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java b/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java index ebbd94c2d4e2..3ae8f6ee6d8f 100644 --- a/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java +++ b/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java @@ -22,30 +22,18 @@ import com.intellij.pom.event.PomChangeSet; import com.intellij.pom.java.PomJavaAspect; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; - public class PomJavaAspectChangeSet implements PomChangeSet{ private final PomModel myModel; - private final List myChanges = new ArrayList(); - public PomJavaAspectChangeSet(PomModel model) { myModel = model; } - public void addChange(PomJavaChange change) { - myChanges.add(change); - } - @NotNull public PomModelAspect getAspect() { return myModel.getModelAspect(PomJavaAspect.class); } public void merge(@NotNull PomChangeSet blocked) { - if(!(blocked instanceof PomJavaAspectChangeSet)) return; - final PomJavaAspectChangeSet blockedJavaChange = (PomJavaAspectChangeSet)blocked; - myChanges.addAll(blockedJavaChange.myChanges); } } diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java b/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java index 7c46254a519d..2624506a0b57 100644 --- a/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java +++ b/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java @@ -29,5 +29,5 @@ public abstract class SmartTypePointerManager { } @NotNull - public abstract SmartTypePointer createSmartTypePointer(PsiType type); + public abstract SmartTypePointer createSmartTypePointer(@NotNull PsiType type); } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/openapi/src/com/intellij/psi/util/MethodSignatureUtil.java index 5a70a6862181..a8f9bfb88ed4 100644 --- a/java/openapi/src/com/intellij/psi/util/MethodSignatureUtil.java +++ b/java/openapi/src/com/intellij/psi/util/MethodSignatureUtil.java @@ -323,7 +323,7 @@ public class MethodSignatureUtil { } @NotNull - public static PsiMethod[] convertMethodSignaturesToMethods(List sameNameMethodList) { + public static PsiMethod[] convertMethodSignaturesToMethods(List sameNameMethodList) { final PsiMethod[] methods = new PsiMethod[sameNameMethodList.size()]; for (int i = 0; i < sameNameMethodList.size(); i++) { methods[i] = sameNameMethodList.get(i).getMethod(); diff --git a/java/openapi/src/com/intellij/psi/util/PsiSuperMethodUtil.java b/java/openapi/src/com/intellij/psi/util/PsiSuperMethodUtil.java index bba2e8788a2e..0de28052cc6e 100644 --- a/java/openapi/src/com/intellij/psi/util/PsiSuperMethodUtil.java +++ b/java/openapi/src/com/intellij/psi/util/PsiSuperMethodUtil.java @@ -18,6 +18,7 @@ package com.intellij.psi.util; import com.intellij.psi.*; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.Set; @@ -68,7 +69,7 @@ public class PsiSuperMethodUtil { return null; } - public static boolean isSuperMethod(PsiMethod method, PsiMethod superMethod) { + public static boolean isSuperMethod(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) { HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); List superSignatures = signature.getSuperSignatures(); for (int i = 0, superSignaturesSize = superSignatures.size(); i < superSignaturesSize; i++) { diff --git a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java index 60316bc0b1ef..e12ebb456dce 100644 --- a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java @@ -672,10 +672,7 @@ public class TypeConversionUtil { } if (left instanceof PsiDisjunctionType) { - for (PsiType type : ((PsiDisjunctionType)left).getDisjunctions()) { - if (isAssignable(type, right, allowUncheckedConversion)) return true; - } - return false; + return isAssignable(((PsiDisjunctionType)left).getLeastUpperBound(), right, allowUncheckedConversion); } if (right instanceof PsiDisjunctionType) { return isAssignable(left, ((PsiDisjunctionType)right).getLeastUpperBound(), allowUncheckedConversion); @@ -900,8 +897,8 @@ public class TypeConversionUtil { */ @NotNull public static PsiSubstitutor getSuperClassSubstitutor(@NotNull PsiClass superClass, - PsiClass derivedClass, - PsiSubstitutor derivedSubstitutor) { + @NotNull PsiClass derivedClass, + @NotNull PsiSubstitutor derivedSubstitutor) { // [dsl] assertion commented out since we no longer cache isInheritor //LOG.assertTrue(derivedClass.isInheritor(superClass, true), "Not inheritor: " + derivedClass + " super: " + superClass); @@ -931,8 +928,8 @@ public class TypeConversionUtil { } if (substitutor == null) { LOG.error( - "Not inheritor: " + derivedClass + "(" + derivedClass.getClass().getName() + "; " + PsiUtil.getVirtualFile(derivedClass) + ");" + - "\n super: " + superClass + "(" + superClass.getClass().getName() + "; " + PsiUtil.getVirtualFile(superClass) + ")"); + "Not inheritor: " + derivedClass + "(" + derivedClass.getClass().getName() + "; " + PsiUtilBase.getVirtualFile(derivedClass) + ");" + + "\n super: " + superClass + "(" + superClass.getClass().getName() + "; " + PsiUtilBase.getVirtualFile(superClass) + ")"); } return substitutor; } diff --git a/platform/lang-api/src/com/intellij/ide/TypePresentationService.java b/platform/lang-api/src/com/intellij/ide/TypePresentationService.java index 4d25772a88f9..9d5410a797d0 100644 --- a/platform/lang-api/src/com/intellij/ide/TypePresentationService.java +++ b/platform/lang-api/src/com/intellij/ide/TypePresentationService.java @@ -1,115 +1,37 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.ide; -import com.intellij.ide.presentation.Presentation; -import com.intellij.ide.presentation.PresentationTemplate; -import com.intellij.ide.presentation.PresentationTemplateImpl; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.util.NullableLazyValue; -import com.intellij.util.containers.ConcurrentFactoryMap; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.FactoryMap; +import com.intellij.openapi.components.ServiceManager; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; /** * @author peter */ -public class TypePresentationService { - - @Nullable - public Icon getTypeIcon(Class type) { - Set templates = mySuperClasses.get(type); - for (PresentationTemplate template : templates) { - Icon icon = template.getIcon(null, 0); - if (icon != null) return icon; - } - return null; - } - - @Nullable - public String getTypePresentableName(Class type) { - Set templates = mySuperClasses.get(type); - for (PresentationTemplate template : templates) { - String typeName = template.getTypeName(); - if (typeName != null) return typeName; - } - return null; - } +public abstract class TypePresentationService { public static TypePresentationService getService() { - return ourInstance; - } - - public TypePresentationService() { - for(TypeIconEP ep: Extensions.getExtensions(TypeIconEP.EP_NAME)) { - myIcons.put(ep.className, ep.getIcon()); - } - for(TypeNameEP ep: Extensions.getExtensions(TypeNameEP.EP_NAME)) { - myNames.put(ep.className, ep.getTypeName()); - } + return ServiceManager.getService(TypePresentationService.class); } @Nullable - private PresentationTemplate createPresentationTemplate(Class type) { - Presentation presentation = type.getAnnotation(Presentation.class); - if (presentation != null) { - return new PresentationTemplateImpl(presentation, type); - } - final NullableLazyValue icon = myIcons.get(type.getName()); - final NullableLazyValue typeName = myNames.get(type.getName()); - if (icon != null || typeName != null) { - return new PresentationTemplate() { - @Override - public Icon getIcon(Object o, int flags) { - return icon == null ? null : icon.getValue(); - } - - @Override - public String getName(Object o) { - return null; - } - - @Override - public String getTypeName() { - return typeName == null ? null : typeName.getValue(); - } - }; - } - return null; - } - - private static final TypePresentationService ourInstance = new TypePresentationService(); - - private final Map> myIcons = new HashMap>(); - private final Map> myNames = new HashMap>(); - @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) - private final FactoryMap> mySuperClasses = new ConcurrentFactoryMap>() { - @Override - protected Set create(Class key) { - LinkedHashSet templates = new LinkedHashSet(); - walkSupers(key, new LinkedHashSet(), templates); - return templates; - } - - private void walkSupers(Class aClass, Set classes, Set templates) { - if (!classes.add(aClass)) { - return; - } - ContainerUtil.addIfNotNull(createPresentationTemplate(aClass), templates); - final Class superClass = aClass.getSuperclass(); - if (superClass != null) { - walkSupers(superClass, classes, templates); - } - - for (Class intf : aClass.getInterfaces()) { - walkSupers(intf, classes, templates); - } - } - }; + public abstract Icon getTypeIcon(Class type); + @Nullable + public abstract String getTypePresentableName(Class type); } diff --git a/platform/lang-api/src/com/intellij/ide/presentation/PresentationTemplate.java b/platform/lang-api/src/com/intellij/ide/presentation/PresentationTemplate.java deleted file mode 100644 index e322db7416e8..000000000000 --- a/platform/lang-api/src/com/intellij/ide/presentation/PresentationTemplate.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.ide.presentation; - -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -/** - * @author Dmitry Avdeev - */ -public interface PresentationTemplate { - - @Nullable - Icon getIcon(Object o, int flags); - - @Nullable - String getName(Object o); - - @Nullable - String getTypeName(); -} diff --git a/platform/lang-api/src/com/intellij/ide/presentation/PresentationTemplateImpl.java b/platform/lang-api/src/com/intellij/ide/presentation/PresentationTemplateImpl.java deleted file mode 100644 index 8b656cd0d5dc..000000000000 --- a/platform/lang-api/src/com/intellij/ide/presentation/PresentationTemplateImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2000-2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.ide.presentation; - -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.NullableLazyValue; -import com.intellij.openapi.util.text.StringUtil; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -/** - * @author Dmitry Avdeev - */ -public class PresentationTemplateImpl implements PresentationTemplate { - - @Override - @Nullable - public Icon getIcon(Object o, int flags) { - PresentationIconProvider iconProvider = myIconProvider.getValue(); - return iconProvider == null ? myIcon.getValue() : iconProvider.getIcon(o, flags); - } - - @Override - @Nullable - public String getTypeName() { - return StringUtil.isEmpty(myPresentation.typeName()) ? null : myPresentation.typeName(); - } - - @Override - @Nullable - public String getName(Object o) { - PresentationNameProvider namer = myNameProvider.getValue(); - return namer == null ? null : namer.getName(o); - } - - public PresentationTemplateImpl(Presentation presentation, Class aClass) { - this.myPresentation = presentation; - myClass = aClass; - } - - private final Presentation myPresentation; - private final Class myClass; - - private final NullableLazyValue myIcon = new NullableLazyValue() { - @Override - protected Icon compute() { - if (StringUtil.isEmpty(myPresentation.icon())) return null; - return IconLoader.getIcon(myPresentation.icon(), myClass); - } - }; - - private final NullableLazyValue myNameProvider = new NullableLazyValue() { - @Override - protected PresentationNameProvider compute() { - Class aClass = myPresentation.nameProviderClass(); - - try { - return aClass == PresentationNameProvider.class ? null : aClass.newInstance(); - } - catch (Exception e) { - return null; - } - } - }; - - private final NullableLazyValue myIconProvider = new NullableLazyValue() { - @Override - protected PresentationIconProvider compute() { - Class aClass = myPresentation.iconProviderClass(); - - try { - return aClass == PresentationIconProvider.class ? null : aClass.newInstance(); - } - catch (Exception e) { - return null; - } - } - }; - -} diff --git a/platform/lang-api/src/com/intellij/lang/LanguageDocumentation.java b/platform/lang-api/src/com/intellij/lang/LanguageDocumentation.java index 130a63b34452..d67283065d98 100644 --- a/platform/lang-api/src/com/intellij/lang/LanguageDocumentation.java +++ b/platform/lang-api/src/com/intellij/lang/LanguageDocumentation.java @@ -21,7 +21,7 @@ package com.intellij.lang; import com.intellij.lang.documentation.CompositeDocumentationProvider; import com.intellij.lang.documentation.DocumentationProvider; -import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -32,11 +32,11 @@ public class LanguageDocumentation extends LanguageExtension providers = allForLanguage(l); if (providers.size() < 2) { return super.forLanguage(l); } return CompositeDocumentationProvider.wrapProviders(providers); } -} \ No newline at end of file +} diff --git a/platform/lang-api/src/com/intellij/lang/folding/LanguageFolding.java b/platform/lang-api/src/com/intellij/lang/folding/LanguageFolding.java index b3c1d77c6b7d..4a2a4238c4c0 100644 --- a/platform/lang-api/src/com/intellij/lang/folding/LanguageFolding.java +++ b/platform/lang-api/src/com/intellij/lang/folding/LanguageFolding.java @@ -21,8 +21,8 @@ import com.intellij.lang.Language; import com.intellij.lang.LanguageExtension; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.DumbService; -import com.intellij.openapi.project.DumbAware; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -38,7 +38,7 @@ public class LanguageFolding extends LanguageExtension { } @Override - public FoldingBuilder forLanguage(Language l) { + public FoldingBuilder forLanguage(@NotNull Language l) { FoldingBuilder cached = l.getUserData(getLanguageCache()); if (cached != null) return cached; @@ -77,4 +77,4 @@ public class LanguageFolding extends LanguageExtension { return builder.buildFoldRegions(astNode, document); } -} \ No newline at end of file +} diff --git a/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReference.java b/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReference.java index acf00ddf29b0..d6d94d9d2e7b 100644 --- a/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReference.java +++ b/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReference.java @@ -23,6 +23,8 @@ import org.jetbrains.annotations.NotNull; * e.g. in java references in static context are resolved to nonstatic methods in case * there is no valid candidate. isValidResult() in this case should return false * for later analysis by highlighting pass. + * + * @see PsiPolyVariantReferenceBase */ public interface PsiPolyVariantReference extends PsiReference { /** diff --git a/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReferenceBase.java b/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReferenceBase.java index aa2d99396790..ac6d87c27ca2 100644 --- a/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReferenceBase.java +++ b/platform/lang-api/src/com/intellij/psi/PsiPolyVariantReferenceBase.java @@ -28,6 +28,10 @@ public abstract class PsiPolyVariantReferenceBase extends super(psiElement); } + public PsiPolyVariantReferenceBase(T element, TextRange range) { + super(element, range); + } + public PsiPolyVariantReferenceBase(final T psiElement, final boolean soft) { super(psiElement, soft); } diff --git a/platform/lang-api/src/com/intellij/psi/PsiReference.java b/platform/lang-api/src/com/intellij/psi/PsiReference.java index bf98b1ff6919..b73db89ac638 100644 --- a/platform/lang-api/src/com/intellij/psi/PsiReference.java +++ b/platform/lang-api/src/com/intellij/psi/PsiReference.java @@ -27,9 +27,10 @@ import org.jetbrains.annotations.Nullable; * Generally returned from {@link PsiElement#getReferences()} and {@link com.intellij.psi.PsiReferenceService#getReferences}, * but may be contributed to some elements by third party plugins via {@link com.intellij.psi.PsiReferenceContributor} * + * @see PsiPolyVariantReference * @see PsiElement#getReference() * @see PsiElement#getReferences() - * @see com.intellij.psi.PsiReferenceService#getReferences + * @see com.intellij.psi.PsiReferenceService#getReferences(PsiElement, com.intellij.psi.PsiReferenceService.Hints) * @see com.intellij.psi.PsiReferenceBase * @see com.intellij.psi.PsiReferenceContributor */ diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiCacheKey.java b/platform/lang-api/src/com/intellij/psi/util/PsiCacheKey.java index d6ccc12f249a..8c6c16991e0e 100644 --- a/platform/lang-api/src/com/intellij/psi/util/PsiCacheKey.java +++ b/platform/lang-api/src/com/intellij/psi/util/PsiCacheKey.java @@ -21,9 +21,11 @@ package com.intellij.psi.util; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.psi.PsiElement; import com.intellij.util.Function; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; public class PsiCacheKey extends Key> { private final Function myFunction; @@ -34,10 +36,34 @@ public class PsiCacheKey extends Key> { } public final T getValue(H h) { + while (true) { + Pair data = h.getUserData(this); + + final long count = h.getManager().getModificationTracker().getJavaStructureModificationCount(); + if (data == null) { + data = new Pair(count, myFunction.fun(h)); + data = ((UserDataHolderEx)h).putUserDataIfAbsent(this, data); + } + else if (data.getFirst() != count) { + Pair newData = new Pair(count, myFunction.fun(h)); + if (((UserDataHolderEx)h).replace(this, data, newData)) { + data = newData; + } + else { + continue; + } + } + + return data.getSecond(); + } + } + + @Nullable + public final T getCachedValueOrNull(H h) { Pair data = h.getUserData(this); final long count = h.getManager().getModificationTracker().getJavaStructureModificationCount(); if (data == null || data.getFirst() != count) { - h.putUserData(this, data = new Pair(count, myFunction.fun(h))); + return null; } return data.getSecond(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java index 370c39f68bc3..0c32cfa102bd 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/TypedHandler.java @@ -32,6 +32,7 @@ import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.actionSystem.TypedActionHandler; import com.intellij.openapi.extensions.Extensions; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -98,26 +99,43 @@ public class TypedHandler implements TypedActionHandler { } static CharFilter.Result getLookupAction(final char charTyped, final LookupImpl lookup) { + final CharFilter.Result filtersDecision = getFiltersDecision(charTyped, lookup); + final LookupElement currentItem = lookup.getCurrentItem(); if (currentItem != null && charTyped != ' ') { - String postfix = lookup.getAdditionalPrefix() + charTyped; - final PrefixMatcher matcher = currentItem.getPrefixMatcher(); - if (matcher.cloneWithPrefix(matcher.getPrefix() + postfix).prefixMatches(currentItem)) { - return CharFilter.Result.ADD_TO_PREFIX; - } - for (final LookupElement element : lookup.getItems()) { - if (element.isPrefixMatched() && element.getPrefixMatcher().cloneWithPrefix(element.getPrefixMatcher().getPrefix() + postfix).prefixMatches(element)) { + if (charTyped != '*' || filtersDecision != CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP) { + String postfix = lookup.getAdditionalPrefix() + charTyped; + final PrefixMatcher matcher = currentItem.getPrefixMatcher(); + if (matcher.cloneWithPrefix(matcher.getPrefix() + postfix).prefixMatches(currentItem)) { return CharFilter.Result.ADD_TO_PREFIX; } + for (final LookupElement element : lookup.getItems()) { + if (element.isPrefixMatched() && + element.getPrefixMatcher().cloneWithPrefix(element.getPrefixMatcher().getPrefix() + postfix).prefixMatches(element)) { + return CharFilter.Result.ADD_TO_PREFIX; + } + } } } - final CharFilter[] filters = Extensions.getExtensions(CharFilter.EP_NAME); - for (final CharFilter extension : filters) { + + if (filtersDecision != null) return filtersDecision; + throw new AssertionError("Typed char not handler by char filter: c=" + charTyped + + "; prefix=" + currentItem + + "; filters=" + Arrays.toString(getFilters())); + } + + @Nullable + private static CharFilter.Result getFiltersDecision(char charTyped, LookupImpl lookup) { + for (final CharFilter extension : getFilters()) { final CharFilter.Result result = extension.acceptChar(charTyped, lookup.getMinPrefixLength() + lookup.getAdditionalPrefix().length(), lookup); if (result != null) { return result; } } - throw new AssertionError("Typed char not handler by char filter: c=" + charTyped + "; prefix=" + currentItem + "; filters=" + Arrays.toString(filters)); + return null; + } + + private static CharFilter[] getFilters() { + return Extensions.getExtensions(CharFilter.EP_NAME); } } diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index 4a58c854a986..61b6ee393d99 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -60,6 +60,7 @@ import com.intellij.psi.impl.PsiManagerEx; import com.intellij.testFramework.LightVirtualFile; import com.intellij.ui.SideBorder; import com.intellij.util.FileContentUtil; +import com.intellij.util.ui.AbstractLayoutManager; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; @@ -87,7 +88,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { private final Document myEditorDocument; protected PsiFile myFile; - private final JPanel myPanel = new JPanel(new BorderLayout()); + private final JPanel myPanel = new JPanel(new MyLayout()); private String myTitle; private String myPrompt = "> "; @@ -124,20 +125,17 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { }; myConsoleEditor.setColorsScheme(scheme); myHistoryViewer.setColorsScheme(scheme); - myPanel.add(myHistoryViewer.getComponent(), BorderLayout.NORTH); - myPanel.add(myConsoleEditor.getComponent(), BorderLayout.CENTER); + myPanel.add(myHistoryViewer.getComponent()); + myPanel.add(myConsoleEditor.getComponent()); setupComponents(); myPanel.putClientProperty(DataManager.CLIENT_PROPERTY_DATA_PROVIDER, new TypeSafeDataProviderAdapter(this)); myUpdateQueue = new MergingUpdateQueue("ConsoleUpdateQueue", 300, true, null); Disposer.register(this, myUpdateQueue); - myPanel.addComponentListener(new ComponentAdapter() { + myHistoryViewer.getComponent().addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { - try { - myHistoryViewer.getScrollingModel().disableAnimation(); - updateSizes(true); - } - finally { - myHistoryViewer.getScrollingModel().enableAnimation(); + if (myForceScrollToEnd.getAndSet(false)) { + final JScrollBar scrollBar = myHistoryViewer.getScrollPane().getVerticalScrollBar(); + scrollBar.setValue(scrollBar.getMaximum()); } } @@ -145,6 +143,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { componentResized(e); } }); + setPromptInner(myPrompt); } public void setFullEditorMode(boolean fullEditorMode) { @@ -156,8 +155,8 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { fileManager.closeFile(virtualFile); myFullEditor = null; myPanel.removeAll(); - myPanel.add(myHistoryViewer.getComponent(), BorderLayout.NORTH); - myPanel.add(myConsoleEditor.getComponent(), BorderLayout.CENTER); + myPanel.add(myHistoryViewer.getComponent()); + myPanel.add(myConsoleEditor.getComponent()); myHistoryViewer.setHorizontalScrollbarVisible(false); } @@ -191,7 +190,6 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { private void setupComponents() { setupEditorDefault(myConsoleEditor); setupEditorDefault(myHistoryViewer); - setPrompt(myPrompt); myConsoleEditor.addEditorMouseListener(EditorActionUtil.createEditorPopupHandler(IdeActions.GROUP_CUT_COPY_PASTE)); if (SEPARATOR_THICKNESS > 0) { myHistoryViewer.getComponent().setBorder(new SideBorder(Color.LIGHT_GRAY, SideBorder.BOTTOM)); @@ -294,7 +292,19 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { public void setPrompt(String prompt) { myPrompt = prompt; - ((EditorImpl)myConsoleEditor).setPrefixTextAndAttributes(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes()); + setPromptInner(myPrompt); + } + + private void setPromptInner(final String prompt) { + ((EditorImpl)myConsoleEditor).setPrefixTextAndAttributes(prompt, ConsoleViewContentType.USER_INPUT.getAttributes()); + if (myPanel.isVisible()) { + queueUiUpdate(false); + } + } + + public void setEditable(boolean editable) { + myConsoleEditor.setRendererMode(!editable); + setPromptInner(editable? myPrompt : ""); } public PsiFile getFile() { @@ -345,26 +355,40 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { HighlighterLayer.SYNTAX, attributes, HighlighterTargetArea.EXACT_RANGE); + if (scrollToEnd) { + scrollHistoryToEnd(); + } queueUiUpdate(scrollToEnd); } public String addCurrentToHistory(final TextRange textRange, final boolean erase, final boolean preserveMarkup) { final Ref ref = Ref.create(""); final boolean scrollToEnd = shouldScrollHistoryToEnd(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { + final Runnable action = new Runnable() { public void run() { ref.set(addTextRangeToHistory(textRange, myConsoleEditor, preserveMarkup)); if (erase) { myConsoleEditor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset()); } } - }); + }; + if (erase) { + ApplicationManager.getApplication().runWriteAction(action); + } + else { + ApplicationManager.getApplication().runReadAction(action); + } + if (scrollToEnd) { + scrollHistoryToEnd(); + } queueUiUpdate(scrollToEnd); return ref.get(); } public boolean shouldScrollHistoryToEnd() { - return myHistoryViewer.getCaretModel().getOffset() == myHistoryViewer.getDocument().getTextLength(); + final Rectangle visibleArea = myHistoryViewer.getScrollingModel().getVisibleArea(); + final Dimension contentSize = myHistoryViewer.getContentSize(); + return contentSize.getHeight() - visibleArea.getMaxY() < 2*myHistoryViewer.getLineHeight(); } private void scrollHistoryToEnd() { @@ -437,7 +461,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { myUpdateQueue.queue(new Update("UpdateUi") { public void run() { if (Disposer.isDisposed(LanguageConsoleImpl.this)) return; - updateSizes(myForceScrollToEnd.getAndSet(false)); + updateSizes(); if (myUiUpdateRunnable != null) { ApplicationManager.getApplication().runReadAction(myUiUpdateRunnable); } @@ -445,36 +469,10 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { }); } - private void updateSizes(boolean forceScrollToEnd) { + private void updateSizes() { if (myFullEditor != null) return; - final Dimension panelSize = myPanel.getSize(); - final Dimension historyContentSize = myHistoryViewer.getContentSize(); - final Dimension contentSize = myConsoleEditor.getContentSize(); - final Dimension newEditorSize = new Dimension(); - final int minHistorySize = historyContentSize.height > 0 ? 2 * myHistoryViewer.getLineHeight() + SEPARATOR_THICKNESS : 0; - final int width = Math.max(contentSize.width, historyContentSize.width); - newEditorSize.height = Math.min(Math.max(panelSize.height - minHistorySize, 2 * myConsoleEditor.getLineHeight()), - contentSize.height + myConsoleEditor.getScrollPane().getHorizontalScrollBar().getHeight()); - newEditorSize.width = width + myConsoleEditor.getScrollPane().getHorizontalScrollBar().getHeight(); - myConsoleEditor.getSettings() - .setAdditionalColumnsCount(2 + (width - contentSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, myConsoleEditor)); - myHistoryViewer.getSettings() - .setAdditionalColumnsCount(2 + (width - historyContentSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, myHistoryViewer)); - - final Dimension editorSize = myConsoleEditor.getComponent().getSize(); - if (!editorSize.equals(newEditorSize)) { - myConsoleEditor.getComponent().setPreferredSize(newEditorSize); - } - final boolean scrollToEnd = forceScrollToEnd || shouldScrollHistoryToEnd(); - final Dimension newHistorySize = new Dimension( - width, Math.max(0, Math.min(minHistorySize == 0 ? 0 : historyContentSize.height + SEPARATOR_THICKNESS, - panelSize.height - newEditorSize.height))); - final Dimension historySize = myHistoryViewer.getComponent().getSize(); - if (!historySize.equals(newHistorySize)) { - myHistoryViewer.getComponent().setPreferredSize(newHistorySize); - } - myPanel.validate(); - if (scrollToEnd) scrollHistoryToEnd(); + myPanel.revalidate(); + myPanel.repaint(); } public void dispose() { @@ -562,7 +560,6 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { ((PsiManagerEx)prevFile.getManager()).getFileManager().setViewProvider(file, null); } - final FileType type = language.getAssociatedFileType(); @NonNls final String name = getTitle(); final LightVirtualFile newVFile = new LightVirtualFile(name, language, myEditorDocument.getText()); FileDocumentManagerImpl.registerDocument(myEditorDocument, newVFile); @@ -641,4 +638,61 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { }, ModalityState.stateForComponent(console.getComponent())); } } + + private class MyLayout extends AbstractLayoutManager { + @Override + public Dimension preferredLayoutSize(final Container parent) { + return new Dimension(0, 0); + } + + @Override + public void layoutContainer(final Container parent) { + final int componentCount = parent.getComponentCount(); + if (componentCount == 0) return; + final EditorEx history = myHistoryViewer; + final EditorEx editor = componentCount == 2? myConsoleEditor : null; + + if (editor == null) { + parent.getComponent(0).setBounds(parent.getBounds()); + return; + } + + final Dimension panelSize = parent.getSize(); + if (panelSize.getHeight() <= 0) return; + final Dimension historySize = history.getContentSize(); + final Dimension editorSize = editor.getContentSize(); + final Dimension newEditorSize = new Dimension(); + + // deal with width + final int width = Math.max(editorSize.width, historySize.width); + newEditorSize.width = width + editor.getScrollPane().getHorizontalScrollBar().getHeight(); + editor.getSettings().setAdditionalColumnsCount(2 + (width - editorSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, editor)); + history.getSettings().setAdditionalColumnsCount(2 + (width - historySize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, history)); + + // deal with height + if (historySize.width == 0) historySize.height = 0; + final int minHistorySize = historySize.height > 0 ? 2 * history.getLineHeight() + SEPARATOR_THICKNESS : 0; + final int minEditorSize = editor.isViewer() ? 0 : editor.getLineHeight(); + final int editorPreferred = editor.isViewer() ? 0 : Math.max(minEditorSize, editorSize.height); + final int historyPreferred = Math.max(minHistorySize, historySize.height); + if (panelSize.height < minEditorSize) { + newEditorSize.height = panelSize.height; + } + else if (panelSize.height < editorPreferred) { + newEditorSize.height = panelSize.height - minHistorySize; + } + else if (panelSize.height < editorPreferred + historyPreferred) { + newEditorSize.height = editorPreferred; + } + else { + newEditorSize.height = editorPreferred == 0 ? 0 : panelSize.height - historyPreferred; + } + final Dimension newHistorySize = new Dimension(width, panelSize.height - newEditorSize.height); + + // apply + editor.getComponent().setBounds(0, newHistorySize.height, panelSize.width, newEditorSize.height); + myForceScrollToEnd.compareAndSet(false, shouldScrollHistoryToEnd()); + history.getComponent().setBounds(0, 0, panelSize.width, newHistorySize.height); + } + } } diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java index e683e9cf4673..13a991ea9ab2 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java @@ -202,8 +202,7 @@ public abstract class AbstractConsoleRunnerWithHistory { protected void finishConsole() { myRunAction.getTemplatePresentation().setEnabled(false); - myConsoleView.getConsole().setPrompt(""); - myConsoleView.getConsole().getConsoleEditor().setRendererMode(true); + myConsoleView.getConsole().setEditable(false); ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { myConsoleView.getConsole().getConsoleEditor().getComponent().updateUI(); diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index 8946f4cb1d7c..3c0f52c9ea64 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -468,6 +468,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec add(myReplacementPane, BorderLayout.SOUTH); myReplaceButton = new JButton("Replace"); + myReplaceButton.setFocusable(false); myReplaceButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { @@ -477,6 +478,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec myReplaceButton.setMnemonic('p'); myReplaceAllButton = new JButton("Replace all"); + myReplaceAllButton.setFocusable(false); myReplaceAllButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { @@ -486,7 +488,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec myReplaceAllButton.setMnemonic('a'); myExcludeButton = new JButton(""); - + myExcludeButton.setFocusable(false); myExcludeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java index cba1b5543527..353068a6adf7 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java @@ -335,7 +335,7 @@ public class SearchResults { if (searchResult.getPrimaryRange().intersects(oldCursorRange)) { mayBeOldCursor = searchResult; } - if (searchResult.getPrimaryRange().equals(oldCursorRange)) { + if (searchResult.getPrimaryRange().getStartOffset() == oldCursorRange.getStartOffset()) { break; } } diff --git a/platform/lang-impl/src/com/intellij/ide/TypePresentationServiceImpl.java b/platform/lang-impl/src/com/intellij/ide/TypePresentationServiceImpl.java new file mode 100644 index 000000000000..653fd222d2bb --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/TypePresentationServiceImpl.java @@ -0,0 +1,206 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide; + +import com.intellij.ide.presentation.*; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.NullableLazyValue; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.ConcurrentFactoryMap; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FactoryMap; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * @author peter + */ +public class TypePresentationServiceImpl extends TypePresentationService { + + @Override@Nullable + public Icon getTypeIcon(Class type) { + Set templates = mySuperClasses.get(type); + for (PresentationTemplate template : templates) { + Icon icon = template.getIcon(null, 0); + if (icon != null) return icon; + } + return null; + } + + @Override@Nullable + public String getTypePresentableName(Class type) { + Set templates = mySuperClasses.get(type); + for (PresentationTemplate template : templates) { + String typeName = template.getTypeName(); + if (typeName != null) return typeName; + } + return null; + } + + public TypePresentationServiceImpl() { + for(TypeIconEP ep: Extensions.getExtensions(TypeIconEP.EP_NAME)) { + myIcons.put(ep.className, ep.getIcon()); + } + for(TypeNameEP ep: Extensions.getExtensions(TypeNameEP.EP_NAME)) { + myNames.put(ep.className, ep.getTypeName()); + } + } + + @Nullable + private PresentationTemplate createPresentationTemplate(Class type) { + Presentation presentation = type.getAnnotation(Presentation.class); + if (presentation != null) { + return new PresentationTemplateImpl(presentation, type); + } + final NullableLazyValue icon = myIcons.get(type.getName()); + final NullableLazyValue typeName = myNames.get(type.getName()); + if (icon != null || typeName != null) { + return new PresentationTemplate() { + @Override + public Icon getIcon(Object o, int flags) { + return icon == null ? null : icon.getValue(); + } + + @Override + public String getName(Object o) { + return null; + } + + @Override + public String getTypeName() { + return typeName == null ? null : typeName.getValue(); + } + }; + } + return null; + } + + private final Map> myIcons = new HashMap>(); + private final Map> myNames = new HashMap>(); + @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) + private final FactoryMap> mySuperClasses = new ConcurrentFactoryMap>() { + @Override + protected Set create(Class key) { + LinkedHashSet templates = new LinkedHashSet(); + walkSupers(key, new LinkedHashSet(), templates); + return templates; + } + + private void walkSupers(Class aClass, Set classes, Set templates) { + if (!classes.add(aClass)) { + return; + } + ContainerUtil.addIfNotNull(createPresentationTemplate(aClass), templates); + final Class superClass = aClass.getSuperclass(); + if (superClass != null) { + walkSupers(superClass, classes, templates); + } + + for (Class intf : aClass.getInterfaces()) { + walkSupers(intf, classes, templates); + } + } + }; + + /** + * @author Dmitry Avdeev + */ + public static class PresentationTemplateImpl implements PresentationTemplate { + + @Override + @Nullable + public Icon getIcon(Object o, int flags) { + PresentationIconProvider iconProvider = myIconProvider.getValue(); + return iconProvider == null ? myIcon.getValue() : iconProvider.getIcon(o, flags); + } + + @Override + @Nullable + public String getTypeName() { + return StringUtil.isEmpty(myPresentation.typeName()) ? null : myPresentation.typeName(); + } + + @Override + @Nullable + public String getName(Object o) { + PresentationNameProvider namer = myNameProvider.getValue(); + return namer == null ? null : namer.getName(o); + } + + public PresentationTemplateImpl(Presentation presentation, Class aClass) { + this.myPresentation = presentation; + myClass = aClass; + } + + private final Presentation myPresentation; + private final Class myClass; + + private final NullableLazyValue myIcon = new NullableLazyValue() { + @Override + protected Icon compute() { + if (StringUtil.isEmpty(myPresentation.icon())) return null; + return IconLoader.getIcon(myPresentation.icon(), myClass); + } + }; + + private final NullableLazyValue myNameProvider = new NullableLazyValue() { + @Override + protected PresentationNameProvider compute() { + Class aClass = myPresentation.nameProviderClass(); + + try { + return aClass == PresentationNameProvider.class ? null : aClass.newInstance(); + } + catch (Exception e) { + return null; + } + } + }; + + private final NullableLazyValue myIconProvider = new NullableLazyValue() { + @Override + protected PresentationIconProvider compute() { + Class aClass = myPresentation.iconProviderClass(); + + try { + return aClass == PresentationIconProvider.class ? null : aClass.newInstance(); + } + catch (Exception e) { + return null; + } + } + }; + + } + + interface PresentationTemplate { + + @Nullable + Icon getIcon(Object o, int flags); + + @Nullable + String getName(Object o); + + @Nullable + String getTypeName(); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java index 4daba937a186..33c059978838 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java @@ -25,6 +25,7 @@ import com.intellij.ide.plugins.cl.PluginClassLoader; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.components.ExportableComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -763,7 +764,9 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo parentDir = topDir; } else { - if (topDir instanceof NewVirtualFile) { + final ApplicationEx app = (ApplicationEx)ApplicationManager.getApplication(); + if (topDir instanceof NewVirtualFile && (!app.holdsReadLock() || app.isDispatchThread())) { + // need dispatch-thread-check because sync refresh in non-awt thread may cause deadlock parentDir = ((NewVirtualFile)topDir).refreshAndFindChild(myDefaultTemplatesDir); } else { diff --git a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java index f74e28777500..a458b57396e3 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java @@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.DumbService; @@ -145,7 +146,7 @@ public class DeleteHandler { } if (safeDeleteApplicable && dumb) { - warningMessage += "\n\nWarning:\n Safe delete is not available while IntelliJ IDEA updates indices,\n no usages will be checked."; + warningMessage += "\n\nWarning:\n Safe delete is not available while " + ApplicationNamesInfo.getInstance().getFullProductName() + " updates indices,\n no usages will be checked."; } int result = Messages.showDialog(project, warningMessage, IdeBundle.message("title.delete"), diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java index 729efea586e3..dbf72d5b6432 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java @@ -60,7 +60,8 @@ public class LowLevelSearchUtil { final PsiElement scope, final StringSearcher searcher, final int offset, - final boolean ignoreInjectedPsi, ProgressIndicator progress) { + final boolean ignoreInjectedPsi, + ProgressIndicator progress) { final int scopeStartOffset = scope.getTextRange().getStartOffset(); final int patternLength = searcher.getPatternLength(); PsiElement leafElement = null; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index aa180d5fae4a..1c2aaf448b61 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.search; import com.intellij.codeInsight.CommentUtil; import com.intellij.concurrency.JobUtil; -import com.intellij.ide.todo.TodoConfiguration; import com.intellij.ide.todo.TodoIndexPatternProvider; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; @@ -44,6 +43,7 @@ import com.intellij.psi.search.searches.IndexPatternSearch; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; +import com.intellij.util.SmartList; import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.MultiMap; import com.intellij.util.indexing.FileBasedIndex; @@ -489,8 +489,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { refProcessor = new Processor() { @Override public boolean process(PsiReference psiReference) { - if (!myProcessor.process(psiReference)) return false; - return another.refProcessor.process(psiReference); + return myProcessor.process(psiReference) && another.refProcessor.process(psiReference); } }; } @@ -571,7 +570,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { progress.setText(PsiBundle.message("psi.scanning.files.progress")); } - final MultiMap candidateFiles = collectFiles(singles); + final MultiMap candidateFiles = collectFiles(singles, progress); if (candidateFiles.isEmpty()) { return true; @@ -593,7 +592,8 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final VirtualFile vfile = psiRoot.getContainingFile().getVirtualFile(); for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) { StringSearcher searcher = searchers.get(singleRequest); - if (!LowLevelSearchUtil.processElementsContainingWordInElement(adaptProcessor(singleRequest.request, singleRequest.refProcessor), psiRoot, searcher, false, progress)) { + TextOccurenceProcessor adapted = adaptProcessor(singleRequest.request, singleRequest.refProcessor); + if (!LowLevelSearchUtil.processElementsContainingWordInElement(adapted, psiRoot, searcher, false, progress)) { return false; } } @@ -616,9 +616,10 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { }; } - private MultiMap collectFiles(MultiMap, RequestWithProcessor> singles) { + private MultiMap collectFiles(MultiMap, RequestWithProcessor> singles, + ProgressIndicator progress) { final ProjectFileIndex index = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex(); - final MultiMap result = new MultiMap(); + final MultiMap result = createMultiMap(); for (Set key : singles.keySet()) { if (key.isEmpty()) { continue; @@ -631,7 +632,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { boolean first = true; for (IdIndexEntry entry : key) { - final MultiMap local = findFilesWithIndexEntry(entry, index, data, commonScope); + final MultiMap local = findFilesWithIndexEntry(entry, index, data, commonScope, progress); if (first) { intersection = local; first = false; @@ -648,6 +649,15 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return result; } + private static MultiMap createMultiMap() { + return new MultiMap(){ + @Override + protected Collection createCollection() { + return new SmartList(); // usually there is just one request + } + }; + } + private static GlobalSearchScope uniteScopes(Collection requests) { GlobalSearchScope commonScope = null; for (RequestWithProcessor r : requests) { @@ -659,29 +669,30 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { } private static MultiMap findFilesWithIndexEntry(final IdIndexEntry entry, - final ProjectFileIndex index, - final Collection data, - final GlobalSearchScope commonScope) { - final MultiMap local = new MultiMap(); + final ProjectFileIndex index, + final Collection data, + final GlobalSearchScope commonScope, + final ProgressIndicator progress) { + final MultiMap local = createMultiMap(); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - ProgressManager.checkCanceled(); + if (progress != null) progress.checkCanceled(); FileBasedIndex.getInstance().processValues(IdIndex.NAME, entry, null, new FileBasedIndex.ValueProcessor() { - public boolean process(VirtualFile file, Integer value) { - ProgressManager.checkCanceled(); - if (!IndexCacheManagerImpl.shouldBeFound(file, index)) { + public boolean process(VirtualFile file, Integer value) { + if (progress != null) progress.checkCanceled(); + if (!IndexCacheManagerImpl.shouldBeFound(file, index)) { + return true; + } + int mask = value.intValue(); + for (RequestWithProcessor single : data) { + final PsiSearchRequest request = single.request; + if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) { + local.putValue(file, single); + } + } return true; } - int mask = value.intValue(); - for (RequestWithProcessor single : data) { - final PsiSearchRequest request = single.request; - if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) { - local.putValue(file, single); - } - } - return true; - } - }, commonScope); + }, commonScope); } }); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java index 0237d6756ade..f3f17275ffb5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java @@ -406,8 +406,7 @@ public class CodeEditUtil { public static void setOldIndentation(final TreeElement treeElement, final int oldIndentation) { if(treeElement == null) return; - if(oldIndentation >= 0) treeElement.putCopyableUserData(INDENT_INFO, oldIndentation); - else treeElement.putCopyableUserData(INDENT_INFO, null); + treeElement.putCopyableUserData(INDENT_INFO, oldIndentation >= 0 ? oldIndentation : null); } public static boolean isMarkedToReformatBefore(final TreeElement element) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java index 52323e3a37f6..5946b573b5b1 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java @@ -83,7 +83,7 @@ public abstract class LeafElement extends TreeElement { return leafTextMatches(text, buffer, start); } - public static int leafTextMatches(CharSequence text, CharSequence buffer, int start) { + public static int leafTextMatches(@NotNull CharSequence text, @NotNull CharSequence buffer, int start) { final int length = text.length(); if(buffer.length() - start < length) return -1; for(int i = 0; i < length; i++){ diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java index 7fa8c3b2e7fb..47a892abfbe6 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java @@ -100,7 +100,11 @@ public abstract class ParameterTableModelBase

extends L int column) { Component component = original.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (!table.isCellEditable(row, table.convertColumnIndexToModel(column))) { - component.setBackground(table.getBackground().darker()); + Color bg = table.getBackground().darker(); + component.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(), 230)); + if (component instanceof EditorTextField) { + ((EditorTextField)component).setCenterByHeight(false); + } } return component; } diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java index e0ff09e3c3e1..fa06d4aae1db 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellEditorBase.java @@ -23,6 +23,8 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.ui.EditorTextField; import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; import javax.swing.table.TableCellEditor; import java.awt.*; @@ -50,11 +52,13 @@ public class CodeFragmentTableCellEditorBase extends AbstractCellEditor implemen } protected EditorTextField createEditorField(Document document) { - return new EditorTextField(document, myProject, myFileType) { + EditorTextField field = new EditorTextField(document, myProject, myFileType) { protected boolean shouldHaveBorder() { return false; } }; + field.setBorder(new EmptyBorder(1, 1, 1, 1)); + return field; } public PsiCodeFragment getCellEditorValue() { diff --git a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java index df8e9f67b44b..f76582636804 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/ui/CodeFragmentTableCellRenderer.java @@ -24,6 +24,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.ui.EditorTextField; import javax.swing.*; +import javax.swing.border.EmptyBorder; import javax.swing.table.TableCellRenderer; import java.awt.*; @@ -62,7 +63,7 @@ public class CodeFragmentTableCellRenderer implements TableCellRenderer { } }; } - editorTextField.setBorder(hasFocus ? BorderFactory.createLineBorder(table.getForeground()): null); + editorTextField.setBorder(hasFocus ? BorderFactory.createLineBorder(table.getForeground()): new EmptyBorder(1, 1, 1, 1)); return editorTextField; } } diff --git a/platform/platform-api/src/com/intellij/lang/LanguageExtension.java b/platform/platform-api/src/com/intellij/lang/LanguageExtension.java index fdec618383c6..9b36627f81aa 100644 --- a/platform/platform-api/src/com/intellij/lang/LanguageExtension.java +++ b/platform/platform-api/src/com/intellij/lang/LanguageExtension.java @@ -43,27 +43,21 @@ public class LanguageExtension extends KeyedExtensionCollector { return key.getID(); } - public T forLanguage(Language l) { + public T forLanguage(@NotNull Language l) { T cached = l.getUserData(IN_LANGUAGE_CACHE); if (cached != null) return cached; List extensions = forKey(l); T result; if (extensions.isEmpty()) { - Language base = l.getBaseLanguage(); - if (base != null) { - result = forLanguage(base); - } - else { - result = myDefaultImplementation; - } + result = base == null ? myDefaultImplementation : forLanguage(base); } else { result = extensions.get(0); } - - l.putUserData(IN_LANGUAGE_CACHE, result); + if (result == null) return result; + l.putUserDataIfAbsent(IN_LANGUAGE_CACHE, result); return result; } diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java index 5d5e8dd98731..74daf6527798 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java @@ -95,6 +95,11 @@ public class JBScrollPane extends JScrollPane { public boolean canBePreprocessed(MouseEvent e) { return JBScrollPane.canBePreprocessed(e, this); } + + @Override + public Dimension getPreferredSize() { + return super.getPreferredSize(); //To change body of overridden methods use File | Settings | File Templates. + } } diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index b4c83c0cd66b..f4a93cc54492 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -45,6 +45,10 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component private MyCellEditorRemover myEditorRemover; private boolean myEnableAntialiasing; + private int myRowHeight = -1; + private boolean myRowHeightIsExplicitlySet; + private boolean myRowHeightIsComputing; + public JBTable() { this(new DefaultTableModel()); } @@ -86,6 +90,9 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component final TableModelListener modelListener = new TableModelListener() { @Override public void tableChanged(final TableModelEvent e) { + if (!myRowHeightIsExplicitlySet) { + myRowHeight = -1; + } if ((e.getType() == TableModelEvent.DELETE && isEmpty()) || (e.getType() == TableModelEvent.INSERT && !isEmpty())) { repaintViewport(); @@ -113,6 +120,36 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component boolean marker = Patches.SUN_BUG_ID_4503845; // Don't remove. It's a marker for find usages } + @Override + public int getRowHeight() { + if (myRowHeightIsComputing) return super.getRowHeight(); + + if (myRowHeight < 0) { + try { + myRowHeightIsComputing = true; + TableModel model = getModel(); + for (int row = 0; row < model.getRowCount(); row++) { + for (int column = 0; column < model.getColumnCount(); column++) { + Dimension size = + getCellRenderer(row, column).getTableCellRendererComponent(this, model.getValueAt(row, column), true, true, row, column) + .getPreferredSize(); + myRowHeight = Math.max(size.height, myRowHeight); + } + } + } + finally { + myRowHeightIsComputing = false; + } + } + return myRowHeight; + } + + @Override + public void setRowHeight(int rowHeight) { + myRowHeight = rowHeight; + myRowHeightIsExplicitlySet = true; + } + private void repaintViewport() { if (!isDisplayable() || !isVisible()) return; diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java index f36e3b33eba9..1df1f86a9e8d 100644 --- a/platform/platform-api/src/com/intellij/ui/table/TableView.java +++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java @@ -15,6 +15,10 @@ */ package com.intellij.ui.table; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.TableUtil; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; @@ -26,9 +30,8 @@ import javax.swing.*; import javax.swing.event.TableModelEvent; import javax.swing.table.*; import java.awt.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.awt.event.KeyEvent; +import java.util.*; import java.util.List; public class TableView extends BaseTableView implements ItemsProvider, SelectionProvider { @@ -55,6 +58,57 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel return (ListTableModel)super.getModel(); } + + @Override + public boolean editCellAt(final int row, final int column, final EventObject e) { + boolean started = super.editCellAt(row, column, e); + if (started && e instanceof KeyEvent) { + final Runnable r = new Runnable() { + @Override + public void run() { + if (getEditingColumn() != row && getEditingColumn() != column) return; + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner == null || !SwingUtilities.isDescendingFrom(focusOwner, TableView.this)) return; + + KeyEvent keyEvent = (KeyEvent)e; + if (Character.isDefined(keyEvent.getKeyChar())) { + try { + selectAll(focusOwner); + + Robot r = new Robot(); + r.keyPress(keyEvent.getKeyCode()); + r.keyRelease(keyEvent.getKeyCode()); + } + catch (AWTException e1) { + return; + } + } else { + selectAll(focusOwner); + } + } + }; + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + r.run(); + } + }); + } + return started; + } + + private void selectAll(Component focusOwner) { + if (focusOwner instanceof TextComponent) { + ((TextComponent)focusOwner).selectAll(); + } else { + Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(focusOwner)); + if (editor != null) { + editor.getSelectionModel().setSelection(0, editor.getDocument().getTextLength()); + } + } + } + public TableCellRenderer getCellRenderer(int row, int column) { final ColumnInfo columnInfo = getListTableModel().getColumnInfos()[convertColumnIndexToModel(column)]; final Item item = getListTableModel().getItems().get(convertRowIndexToModel(row)); diff --git a/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java b/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java index 65e97cca94fc..1cfc6661df48 100644 --- a/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java +++ b/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java @@ -19,6 +19,8 @@ import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerAdapter; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Application; @@ -29,12 +31,20 @@ import org.jetbrains.annotations.NotNull; import javax.swing.FocusManager; import javax.swing.*; +import javax.swing.event.CaretListener; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentListener; import javax.swing.plaf.basic.BasicPopupMenuUI; +import javax.swing.text.AbstractDocument; +import javax.swing.text.Document; import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.dnd.DragGestureRecognizer; +import java.awt.event.AWTEventListener; +import java.awt.event.HierarchyEvent; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.EventListener; /** * This class listens event from ProjectManager and cleanup some @@ -181,6 +191,60 @@ public final class SwingCleanuper implements ApplicationComponent{ } } ); + + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + @Override + public void eventDispatched(AWTEvent event) { + if (!SystemInfo.isMac || !Registry.is("jvmbugfix.mac.caccessibleLeak")) return; + + HierarchyEvent he = (HierarchyEvent)event; + if ((he.getChangeFlags() & (HierarchyEvent.SHOWING_CHANGED)) > 0) { + if (he.getComponent() != null && !he.getComponent().isShowing()) { + Component c = he.getComponent(); + if (c instanceof JTextComponent) { + JTextComponent textComponent = (JTextComponent)c; + + CaretListener[] carets = textComponent.getListeners(CaretListener.class); + for (CaretListener each : carets) { + if (isCAccessibleListener(each)) { + textComponent.removeCaretListener(each); + } + } + + Document document = textComponent.getDocument(); + if (document instanceof AbstractDocument) { + DocumentListener[] documentListeners = ((AbstractDocument)document).getDocumentListeners(); + for (DocumentListener each : documentListeners) { + if (isCAccessibleListener(each)) { + document.removeDocumentListener(each); + } + } + } + } else if (c instanceof JProgressBar) { + JProgressBar bar = (JProgressBar)c; + ChangeListener[] changeListeners = bar.getChangeListeners(); + for (ChangeListener each : changeListeners) { + if (isCAccessibleListener(each)) { + bar.removeChangeListener(each); + } + } + } else if (c instanceof JSlider) { + JSlider slider = (JSlider)c; + ChangeListener[] changeListeners = slider.getChangeListeners(); + for (ChangeListener each : changeListeners) { + if (isCAccessibleListener(each)) { + slider.removeChangeListener(each); + } + } + } + } + } + } + }, HierarchyEvent.HIERARCHY_EVENT_MASK); + } + + private boolean isCAccessibleListener(EventListener listener) { + return listener != null && listener.toString().contains("AXTextChangeNotifier"); } private static void resetField(Object object, Class type, @NonNls String name) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java index 75f62da8b6eb..4ea4bf781df4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/ApplyNonConflicts.java @@ -28,6 +28,7 @@ import com.intellij.util.containers.FilteringIterator; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; public class ApplyNonConflicts extends AnAction implements DumbAware { public ApplyNonConflicts() { @@ -36,7 +37,7 @@ public class ApplyNonConflicts extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { DataContext dataContext = e.getDataContext(); - ArrayList notConflicts = ContainerUtil.collect(getNotConflicts(dataContext)); + List notConflicts = ContainerUtil.collect(getNotConflicts(dataContext)); for (Change change : notConflicts) { Change.apply(change, MergeList.BRANCH_SIDE); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 699c7ff1eb09..b71ce84d2def 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -228,7 +228,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private boolean myGutterNeedsUpdate = false; private Alarm myAppleRepaintAlarm; - private Alarm myMouseSelectionStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private final Alarm myMouseSelectionStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private Runnable myMouseSelectionStateResetRunnable; private boolean myEmbeddedIntoDialogWrapper; @@ -1721,6 +1721,19 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) { drawWave(g, end.x, end.x + charWidth - 1, y); } + else if (attributes.getEffectType() == EffectType.BOLD_DOTTED_LINE) { + final int dottedAt = SystemInfo.isMac ? y - 1 : y; + UIUtil.drawBoldDottedLine((Graphics2D)g, end.x, end.x + charWidth - 1, dottedAt, + getBackgroundColor(attributes), attributes.getEffectColor(), false); + } + else if (attributes.getEffectType() == EffectType.STRIKEOUT) { + int y1 = y - getCharHeight() / 2 - 1; + UIUtil.drawLine(g, end.x, y1, end.x + charWidth - 1, y1); + } + else if (attributes.getEffectType() == EffectType.BOLD_LINE_UNDERSCORE) { + UIUtil.drawLine(g, end.x, y - 1, end.x + charWidth - 1, y - 1); + UIUtil.drawLine(g, end.x, y, end.x + charWidth - 1, y); + } else if (attributes.getEffectType() != EffectType.BOXED) { UIUtil.drawLine(g, end.x, y, end.x + charWidth - 1, y); } @@ -4682,8 +4695,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } private boolean processMousePressed(MouseEvent e) { - boolean isNavigation = false; - myInitialMouseEvent = e; if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && System.currentTimeMillis() - myMouseSelectionChangeTimestamp > Registry.intValue( @@ -4698,6 +4709,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (y < 0) y = 0; final EditorMouseEventArea eventArea = getMouseEventArea(e); + boolean isNavigation = false; if (eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA) { final FoldRegion range = myGutterComponent.findFoldingAnchorAt(x, y); if (range != null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java index c5f7460f6616..c025221f4fe4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java @@ -25,7 +25,10 @@ import gnu.trove.TLongHashSet; import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -36,40 +39,44 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; public abstract class IntervalTreeImpl extends RedBlackTree implements IntervalTree { protected int keySize; // number of all keys protected final ReadWriteLock l = new ReentrantReadWriteLock(); + private IntervalNode minNode; // left most node in the tree protected abstract EqualStartIntervalComparator getComparator(); private final ReferenceQueue myReferenceQueue = new ReferenceQueue(); private int deadReferenceCount; - public abstract class IntervalNode extends RedBlackTree.Node implements MutableInterval { - protected int maxEnd; // max of all intervalEnd()s among all children. - protected int delta; // delta of startOffset. getStartOffset() = myStartOffset + Sum of deltas up to root - protected abstract int computeDeltaUpToRoot(); - @Override - public IntervalNode getLeft() { - return (IntervalNode)super.getLeft(); - } - @Override - public IntervalNode getRight() { - return (IntervalNode)super.getRight(); - } - @Override - public IntervalNode getParent() { - return (IntervalNode)super.getParent(); - } - } - - protected class MyNode extends IntervalNode { + protected class IntervalNode extends Node implements MutableInterval/*, Iterable, Iterator*/ { private volatile int myStart; private volatile int myEnd; private volatile boolean isValid = true; - protected final List> intervals; - public MyNode(@NotNull T key, int start, int end) { + protected final SmartList> intervals; + protected int maxEnd; // max of all intervalEnd()s among all children. + protected int delta; // delta of startOffset. getStartOffset() = myStartOffset + Sum of deltas up to root + IntervalNode next; // node following this in the in-order tree traversal. used for optimised tree iteration + + public IntervalNode(@NotNull T key, int start, int end) { // maxEnd == 0 so to not disrupt existing maxes intervals = new SmartList>(createGetable(key)); myStart = start; myEnd = end; } + + + @Override + public IntervalNode getLeft() { + return (IntervalNode)left; + } + + @Override + public IntervalNode getRight() { + return (IntervalNode)right; + } + + @Override + public IntervalNode getParent() { + return (IntervalNode)parent; + } + @Override public boolean processAliveKeys(@NotNull Processor processor) { for (Getable interval : intervals) { @@ -79,21 +86,6 @@ public abstract class IntervalTreeImpl extends RedBla return true; } - @NotNull - @Override - public List getAliveKeys() { - List result = null; - for (Getable ref : intervals) { - T interval = ref.get(); - if (interval == null) continue; - if (result == null) { - result = new ArrayList(intervals.size()); - } - result.add(interval); - } - return result == null ? Collections.emptyList() : result; - } - public boolean hasAliveKey(boolean purgeDead) { for (int i = intervals.size() - 1; i >= 0; i--) { Getable interval = intervals.get(i); @@ -126,8 +118,7 @@ public abstract class IntervalTreeImpl extends RedBla return false; } } - List aliveKeys = getAliveKeys(); - assert false: "not found interval: "+key +"; "+ aliveKeys; + assert false: "interval not found: "+key +"; "+ intervals; return false; } @@ -147,7 +138,6 @@ public abstract class IntervalTreeImpl extends RedBla return new WeakReferencedGetable(interval, myReferenceQueue); } - @Override protected int computeDeltaUpToRoot() { if (normalized) return 0; int delta = 0; @@ -205,8 +195,8 @@ public abstract class IntervalTreeImpl extends RedBla } @NotNull - protected abstract MyNode createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer); - protected abstract MyNode lookupNode(@NotNull T key); + protected abstract IntervalNode createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer); + protected abstract IntervalNode lookupNode(@NotNull T key); private int compareNodes(@NotNull IntervalNode i1, int delta1, @NotNull IntervalNode i2, int delta2, @NotNull List invalid) { if (!i2.hasAliveKey(false)) { @@ -339,7 +329,7 @@ public abstract class IntervalTreeImpl extends RedBla return processOverlapping(root.getRight(), offset, processor, modCountBefore, delta); } - protected MyNode findOrInsert(@NotNull IntervalNode node) { + protected IntervalNode findOrInsert(@NotNull IntervalNode node) { node.color = Color.RED; node.setParent(null); node.setValid(true); @@ -353,14 +343,14 @@ public abstract class IntervalTreeImpl extends RedBla root = node; } else { - IntervalNode current = (IntervalNode)root; + IntervalNode current = getRoot(); int delta = 0; loop: while (true) { delta += current.delta; int compResult = compareNodes(node, 0, current, delta, gced); if (compResult == 0) { - return (MyNode)current; + return current; } if (compResult < 0) { if (current.getLeft() == null) { @@ -380,14 +370,56 @@ public abstract class IntervalTreeImpl extends RedBla node.delta = -delta; node.setParent(current); } + linkNode(node); correctMaxUp(node); onInsertNode(); - keySize += ((MyNode)node).intervals.size(); + keySize += node.intervals.size(); insertCase1(node); verifyProperties(); deleteNodes(gced); - return (MyNode)node; + return node; + } + + private void linkNode(@NotNull IntervalNode node) { + IntervalNode previous = previous(node); + if (previous == null) { + node.next = minNode; + minNode = node; + } + else { + node.next = previous.next; + previous.next = node; + } + } + + private void unlinkNode(@NotNull IntervalNode node) { + IntervalNode previous = previous(node); + if (previous == null) { + minNode = node.next; + } + else { + previous.next = node.next; + } + node.next = null; + } + + // finds previous in the in-order traversal + private IntervalNode previous(@NotNull IntervalNode node) { + IntervalNode left = node.getLeft(); + if (left != null) { + while (left.getRight() != null) { + left = left.getRight(); + } + return left; + } + IntervalNode parent = node.getParent(); + while (parent != null) { + if (parent.getRight() == node) break; + node = parent; + parent = parent.getParent(); + } + return parent; } private void deleteNodes(List collectedAway) { @@ -405,14 +437,14 @@ public abstract class IntervalTreeImpl extends RedBla } } - public MyNode addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) { + public IntervalNode addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) { try { l.writeLock().lock(); checkMax(true); processReferenceQueue(); modCount++; IntervalNode newNode = createNewNode(interval, start, end, greedyToLeft, greedyToRight, layer); - MyNode insertedNode = findOrInsert(newNode); + IntervalNode insertedNode = findOrInsert(newNode); if (insertedNode != newNode) { // merged insertedNode.addInterval(interval); @@ -442,19 +474,22 @@ public abstract class IntervalTreeImpl extends RedBla } // returns real (minStart, maxStart, maxEnd) - protected Trinity checkMax(IntervalNode root, - int deltaUpToRootExclusive, - boolean assertInvalid, - Ref allValid, - AtomicInteger keyCounter, - AtomicInteger nodeCounter, - TLongHashSet ids) { + private Trinity checkMax(IntervalNode root, + int deltaUpToRootExclusive, + boolean assertInvalid, + Ref allValid, + AtomicInteger keyCounter, + AtomicInteger nodeCounter, + TLongHashSet ids) { if (root == null) return Trinity.create(Integer.MAX_VALUE,Integer.MIN_VALUE,Integer.MIN_VALUE); - for (T t : root.getAliveKeys()) { + for (int i = root.intervals.size() - 1; i >= 0; i--) { + T t = root.intervals.get(i).get(); + if (t == null) continue; checkBelongsToTheTree(t, assertInvalid); assert ids.add(((RangeMarkerImpl)t).getId()) : t; } - keyCounter.addAndGet(((MyNode)root).intervals.size()); + + keyCounter.addAndGet(root.intervals.size()); nodeCounter.incrementAndGet(); int delta = deltaUpToRootExclusive + (root.isValid() ? root.delta : 0); Trinity l = checkMax(root.getLeft(), delta, assertInvalid, allValid, keyCounter, nodeCounter, ids); @@ -503,22 +538,26 @@ public abstract class IntervalTreeImpl extends RedBla protected void checkBelongsToTheTree(T interval, boolean assertInvalid) { if (!VERIFY) return; - MyNode root = lookupNode(interval); + IntervalNode root = lookupNode(interval); if (root == null) return; assert !root.intervals.isEmpty(); assert root.getTree() == this; - List keys = root.getAliveKeys(); - assert keys.contains(interval) : keys + "; " + interval; - for (T key : keys) { - MyNode node = lookupNode(key); + boolean contains = false; + for (int i = root.intervals.size() - 1; i >= 0; i--) { + T key = root.intervals.get(i).get(); + if (key == null) continue; + contains |= key == interval; + IntervalNode node = lookupNode(key); assert assertInvalid && node == root || !assertInvalid && (node == null || node == root) : node; assert assertInvalid && node.getTree() == this || !assertInvalid && (node == null || node.getTree() == this) : node; } + assert contains : root.intervals + "; " + interval; + IntervalNode e = root; while (e.getParent() != null) e = e.getParent(); - assert e == this.root; // assert the node belongs to our tree + assert e == getRoot(); // assert the node belongs to our tree } @Override @@ -530,7 +569,7 @@ public abstract class IntervalTreeImpl extends RedBla checkMax(true); processReferenceQueue(); - MyNode node = lookupNode(interval); + IntervalNode node = lookupNode(interval); if (node == null) return false; node.removeInterval(interval); @@ -543,7 +582,7 @@ public abstract class IntervalTreeImpl extends RedBla } // run under write lock - public void removeNode(@NotNull IntervalNode node) { + void removeNode(@NotNull IntervalNode node) { deleteNode(node); IntervalNode parent = node.getParent(); correctMaxUp(parent); @@ -551,8 +590,10 @@ public abstract class IntervalTreeImpl extends RedBla @Override protected void deleteNode(Node n) { - MyNode node = (MyNode)n; + IntervalNode node = (IntervalNode)n; pushDeltaFromRoot(node); + unlinkNode(node); + super.deleteNode(n); keySize -= node.intervals.size(); @@ -564,9 +605,9 @@ public abstract class IntervalTreeImpl extends RedBla return keySize; } - // returns true if some delta was or became not null + // returns true if all deltas involved are still 0 protected boolean pushDelta(IntervalNode root) { - if (root == null || !root.isValid()) return false; + if (root == null || !root.isValid()) return true; int delta = root.delta; if (delta != 0) { root.setIntervalStart(root.intervalStart() + delta); @@ -575,23 +616,23 @@ public abstract class IntervalTreeImpl extends RedBla root.delta = 0; //noinspection NonShortCircuitBooleanExpression return - incDelta(root.getLeft(), delta) | + incDelta(root.getLeft(), delta) & incDelta(root.getRight(), delta); } - return false; + return true; } - // returns true if some delta was or became not null + // returns true if all deltas involved are still 0 private boolean incDelta(IntervalNode root, int delta) { - if (root == null) return false; + if (root == null) return true; if (root.isValid()) { int newDelta = root.delta += delta; - return newDelta != 0; + return newDelta == 0; } else { //noinspection NonShortCircuitBooleanExpression return - incDelta(root.getLeft(), delta) | + incDelta(root.getLeft(), delta) & incDelta(root.getRight(), delta); } } @@ -743,10 +784,7 @@ public abstract class IntervalTreeImpl extends RedBla } public Iterator iterator() { - IntervalNode firstNode = getRoot(); - while (firstNode != null && firstNode.getLeft() != null) { - firstNode = firstNode.getLeft(); - } + IntervalNode firstNode = minNode; if (firstNode == null) { return ContainerUtil.emptyIterator(); } @@ -795,58 +833,37 @@ public abstract class IntervalTreeImpl extends RedBla final int modCountBefore = modCount; return new Iterator() { private IntervalNode node = firstNode; - private Iterator iteratorInCurrentList = firstNode.getAliveKeys().iterator(); - - { - // find first non-null key - while (!iteratorInCurrentList.hasNext()) { - moveNext(); - if (node == null) break; - } - } + private int indexInCurrentList = 0; + T current; public boolean hasNext() { - Iterator it = iteratorInCurrentList; - return it != null && it.hasNext(); + if (current != null) return true; + while (node != null) { + while (indexInCurrentList != node.intervals.size()) { + current = node.intervals.get(indexInCurrentList).get(); + if (current != null) return true; + indexInCurrentList++; + } + indexInCurrentList = 0; + node = getNextNode(node); + } + return false; } public T next() { assert modCount == modCountBefore : "Must not modify range markers during iterate"; - if (node == null || iteratorInCurrentList == null || !iteratorInCurrentList.hasNext()) throw new NoSuchElementException(); - T current = iteratorInCurrentList.next(); - moveNext(); - return current; + if (!hasNext()) throw new NoSuchElementException(); + + T t = current; + current = null; + + indexInCurrentList++; + return t; } - private void moveNext() { - if (iteratorInCurrentList != null && iteratorInCurrentList.hasNext()) return; - while (true) { - node = getNextNode(); - if (node == null) { - iteratorInCurrentList = null; - break; - } - iteratorInCurrentList = node.getAliveKeys().iterator(); - if (iteratorInCurrentList.hasNext()) break; - } - } - private IntervalNode getNextNode() { - IntervalNode n = node.getRight(); - if (n != null) { - while (n.getLeft()!= null) { - n = n.getLeft(); - } - return n; - } - IntervalNode parent = node.getParent(); - IntervalNode current = node; - while (parent != null) { - if (parent.getLeft() == current) return parent; - current = parent; - parent = parent.getParent(); - } - return null; + private IntervalNode getNextNode(IntervalNode node) { + return node.next; } public void remove() { @@ -881,13 +898,13 @@ public abstract class IntervalTreeImpl extends RedBla try { l.writeLock().lock(); - MyNode node = lookupNode(interval); + IntervalNode node = lookupNode(interval); if (node == null) return; int before = size(); boolean nodeRemoved = node.removeInterval(interval); assert nodeRemoved || !node.intervals.isEmpty(); - MyNode insertedNode = addInterval(interval, start, end, greedyToLeft, greedyToRight, layer); + IntervalNode insertedNode = addInterval(interval, start, end, greedyToLeft, greedyToRight, layer); assert node != insertedNode; int after = size(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java index c3efa8a61aed..8337e9b0ea35 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java @@ -141,7 +141,7 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx } } - IntervalTreeImpl.IntervalNode addRangeHighlighter(RangeHighlighterEx marker, + IntervalTreeImpl.IntervalNode addRangeHighlighter(RangeHighlighterEx marker, int start, int end, boolean greedyToLeft, diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java index f8fa6ff69c4d..b9ceb3307bdf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeHighlighterTree.java @@ -74,7 +74,7 @@ public class RangeHighlighterTree extends RangeMarkerTree { myLayer = layer; } - // range highlighters are strongly referenced + //range highlighters are strongly referenced @Override protected Getable createGetable(@NotNull RangeHighlighterEx interval) { return (Getable)interval; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java index 65e4ba599d06..d2eb1cbc9ed1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java @@ -82,7 +82,7 @@ public class RangeMarkerTree extends IntervalTreeImpl extends IntervalTreeImpl extends IntervalTreeImpl extends IntervalTreeImpl affected = new ArrayList(); - normalized &= !collectAffectedMarkers(getRoot(), e, affected); + normalized &= collectAffectedMarkers(getRoot(), e, affected); checkMax(false); if (!affected.isEmpty()) { @@ -180,9 +177,15 @@ public class RangeMarkerTree extends IntervalTreeImpl aliveKeys = node.getAliveKeys(); - if (aliveKeys.isEmpty()) continue; // collected - RangeMarkerImpl marker = (RangeMarkerImpl)aliveKeys.get(0); + List> keys = node.intervals; + if (keys.isEmpty()) continue; // collected away + + RangeMarkerImpl marker = null; + for (Getable key : keys) { + marker = (RangeMarkerImpl)key.get(); + if (marker != null) break; + } + if (marker == null) continue; marker.setValid(true); //marker.myNode = null; marker.documentChanged(e); @@ -191,7 +194,9 @@ public class RangeMarkerTree extends IntervalTreeImpl key : keys) { + T interval = key.get(); + if (interval == null) continue; insertedNode.addInterval(interval); } } @@ -206,15 +211,14 @@ public class RangeMarkerTree extends IntervalTreeImpl affected) { - if (root == null) return false; - boolean denorm = pushDelta(root); + // returns true if all deltas involved are still 0 + private boolean collectAffectedMarkers(IntervalNode root, @NotNull DocumentEvent e, @NotNull List affected) { + if (root == null) return true; + boolean norm = pushDelta(root); int maxEnd = root.maxEnd; assert root.isValid(); @@ -227,19 +231,19 @@ public class RangeMarkerTree extends IntervalTreeImpl maxEnd) { - + // no need to bother } else if (affectedEndOffset < root.intervalStart()) { int lengthDelta = e.getNewLength() - e.getOldLength(); int newD = root.delta += lengthDelta; - denorm |= newD != 0; + norm &= newD == 0; IntervalNode left = root.getLeft(); if (left != null) { int newL = left.delta -= lengthDelta; - denorm |= newL != 0; + norm &= newL == 0; } - denorm |= pushDelta(root); - denorm |= collectAffectedMarkers(left, e, affected); + norm &= pushDelta(root); + norm &= collectAffectedMarkers(left, e, affected); correctMax(root, 0); } else { @@ -249,11 +253,11 @@ public class RangeMarkerTree extends IntervalTreeImpl sweepProcessor) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java index 88919cc518b9..a0ced136790a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java @@ -18,8 +18,6 @@ package com.intellij.openapi.editor.impl; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; -import java.util.List; - /** * User: cdr @@ -296,9 +294,9 @@ public abstract class RedBlackTree { } public abstract static class Node { - private Node left; - private Node right; - private Node parent = null; + protected Node left; + protected Node right; + protected Node parent = null; protected Color color = Color.RED; public Node() { @@ -347,8 +345,7 @@ public abstract class RedBlackTree { } public abstract boolean processAliveKeys(@NotNull Processor processor); - @NotNull - public abstract List getAliveKeys(); + public abstract boolean hasAliveKey(boolean purgeDead); } diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java index a55f9f7f19bc..6e217d4d1beb 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java @@ -73,6 +73,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, private boolean myInheritSwingFont = true; private Color myEnforcedBgColor = null; private boolean myOneLineMode; // use getter to access this field! It is allowed to override getter and change initial behaviour + private boolean myCenterByHeight = true; public EditorTextField() { this(""); @@ -100,7 +101,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, setDocument(document); myProject = project; myFileType = fileType; - setLayout(new BorderLayout()); + setLayout(null); enableEvents(AWTEvent.KEY_EVENT_MASK); // todo[dsl,max] setFocusable(true); @@ -207,7 +208,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, Editor editor = myEditor; myEditor = createEditor(); releaseEditor(editor); - add(myEditor.getComponent(), BorderLayout.CENTER); + add(myEditor.getComponent()); validate(); if (isFocused) { @@ -307,7 +308,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, boolean isFocused = isFocusOwner(); myEditor = createEditor(); - add(myEditor.getComponent(), BorderLayout.CENTER); + final JComponent component = myEditor.getComponent(); + add(component); super.addNotify(); @@ -393,6 +395,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, editor.setBackgroundColor(getBackgroundColor(!myIsViewer, colorsScheme)); } + + public void setOneLineMode(boolean oneLineMode) { myOneLineMode = oneLineMode; } @@ -527,7 +531,10 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, Editor editor = myEditor; releaseEditor(editor); myEditor = createEditor(); - add(myEditor.getComponent(), BorderLayout.CENTER); + add(myEditor.getComponent() + + + ); revalidate(); } } @@ -539,7 +546,25 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, : UIUtil.getInactiveTextFieldBackgroundColor(); } + @Override + public void doLayout() { + if (getComponentCount() != 1) return; + + Component c = getComponent(0); + Insets insets = getInsets() != null ? getInsets() : new Insets(0, 0, 0, 0); + int prefHeight = c.getPreferredSize().height; + if (myOneLineMode && getSize().height > prefHeight && myCenterByHeight) { + int y = insets.top + getSize().height / 2 - prefHeight / 2; + c.setBounds(insets.left, y - 1, getSize().width - insets.left - insets.right, prefHeight); + } else { + c.setBounds(insets.left, insets.top, getSize().width - insets.left - insets.right, getSize().height - insets.top - insets.bottom); + } + } + public Dimension getPreferredSize() { + if (super.isPreferredSizeSet()) { + return super.getPreferredSize(); + } if (myEditor != null) { final Dimension preferredSize = new Dimension(myEditor.getComponent().getPreferredSize()); final Insets insets = getInsets(); @@ -624,6 +649,10 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener, setDocument(document); } + public void setCenterByHeight(boolean centerByHeight) { + myCenterByHeight = centerByHeight; + } + private static class DelegatingToRootTraversalPolicy extends FocusTraversalPolicy { @Override public Component getComponentAfter(final Container aContainer, final Component aComponent) { diff --git a/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java b/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java index 5e205b9bf462..0b89e21798a6 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java +++ b/platform/platform-impl/src/com/intellij/util/ui/ChangesTrackingTableView.java @@ -39,15 +39,6 @@ public abstract class ChangesTrackingTableView extends TableView { protected abstract void onEditingStopped(); - @Override - public TableCellEditor getCellEditor(int row, int column) { - final TableCellEditor editor = super.getCellEditor(row, column); - if (column == 0 && editor instanceof DefaultCellEditor) { - //((DefaultCellEditor)editor).setClickCountToStart(1); - } - return editor; - } - @Override public boolean editCellAt(final int row, final int column, EventObject e) { if (super.editCellAt(row, column, e)) { @@ -58,16 +49,25 @@ public abstract class ChangesTrackingTableView extends TableView { } }; addChangeListener(getEditorComponent(), new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - onCellValueChanged(row, column, getValue(getEditorComponent())); - } - }, myEditorListenerDisposable); + @Override + public void stateChanged(ChangeEvent e) { + onCellValueChanged(row, column, getValue(getEditorComponent())); + } + }, myEditorListenerDisposable); return true; } return false; } + @Override + public TableCellEditor getCellEditor(int row, int column) { + final TableCellEditor editor = super.getCellEditor(row, column); + if (column == 0 && editor instanceof DefaultCellEditor) { + //((DefaultCellEditor)editor).setClickCountToStart(1); + } + return editor; + } + @Override public void removeEditor() { if (myEditorListenerDisposable != null) { diff --git a/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java b/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java index 3ac0465a6e91..16a52883fcab 100644 --- a/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java +++ b/platform/platform-impl/testSrc/com/intellij/util/IJSwingUtilitiesTest.java @@ -20,7 +20,7 @@ import junit.framework.TestCase; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; +import java.util.List; public class IJSwingUtilitiesTest extends TestCase { private final JPanel myPanel = new JPanel(); @@ -52,7 +52,7 @@ public class IJSwingUtilitiesTest extends TestCase { CHECK.compareAll(new JComponent[]{label1, subPanel, label2, label3, label4}, getChildren()); } - private ArrayList getChildren() { + private List getChildren() { return ContainerUtil.collect(IJSwingUtilities.getChildren(myPanel)); } diff --git a/platform/platform-resources-en/src/messages/XmlErrorMessages.properties b/platform/platform-resources-en/src/messages/XmlErrorMessages.properties index c88534f96060..7a375eae8ebe 100644 --- a/platform/platform-resources-en/src/messages/XmlErrorMessages.properties +++ b/platform/platform-resources-en/src/messages/XmlErrorMessages.properties @@ -11,7 +11,7 @@ element.is.not.allowed.here=Element {0} is not allowed here element.must.be.declared=Element {0} must be declared element.doesnt.have.required.attribute=Element {0} doesn''t have required attribute {1} wrong.root.element=Wrong root element -unbound.namespace=Namespace {0} is not bound +unbound.namespace=Namespace ''{0}'' is not bound unbound.namespace.no.param=Namespace is not bound attribute.is.not.allowed.here=Attribute {0} is not allowed here empty.attribute.is.not.allowed=Empty attribute {0} is not allowed diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 474e36f5ba89..64f450c97174 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -123,3 +123,5 @@ navbar.newpopup=true inspectionGadgets.telemetry.enabled=false minuscule.humps.matching=false minuscule.humps.matching.description=Camel Case without holding Shift in Ctrl+N/Ctrl+Shift+N etc + +jvmbugfix.mac.caccessibleLeak=true diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index b009446fd8ba..5fb1d1d608aa 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -28,6 +28,9 @@ + + availableIntentions = fixture.getAvailableIntentions(); + final IntentionAction intentionAction = findIntentionByText(availableIntentions, action); + Assert.assertTrue("Action not found: " + action + " among " + availableIntentions, intentionAction != null); new WriteCommandAction(fixture.getProject()) { @Override protected void run(Result result) throws Throwable { diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java new file mode 100644 index 000000000000..a8f9a8366b8d --- /dev/null +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java @@ -0,0 +1,110 @@ +package com.intellij.execution.testframework.autotest; + +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentManagerImpl; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.content.Content; +import com.intellij.util.Alarm; +import com.intellij.util.containers.WeakList; + +import java.util.Collection; + +/** + * @author yole + */ +public class AutoTestManager { + private final Project myProject; + private final Alarm myAutoTestAlarm; + + private static final int AUTOTEST_DELAY = 2000; + private final Runnable myRunTestsRunnable; + private boolean myListenerAttached; + private final MyDocumentAdapter myListener; + + public static AutoTestManager getInstance(Project project) { + return ServiceManager.getService(project, AutoTestManager.class); + } + + private final Collection myEnabledDescriptors = new WeakList(); + + public AutoTestManager(Project project) { + myProject = project; + myAutoTestAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, project); + myRunTestsRunnable = new Runnable() { + public void run() { + runAutoTests(); + } + }; + myListener = new MyDocumentAdapter(); + } + + public void setAutoTestEnabled(RunContentDescriptor descriptor, boolean enabled) { + Content content = descriptor.getAttachedContent(); + if (enabled) { + if (!myEnabledDescriptors.contains(content)) { + myEnabledDescriptors.add(content); + } + if (!myListenerAttached) { + myListenerAttached = true; + EditorFactory.getInstance().getEventMulticaster().addDocumentListener(myListener, myProject); + } + } + else { + myEnabledDescriptors.remove(content); + if (myEnabledDescriptors.isEmpty() && myListenerAttached) { + myListenerAttached = false; + EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(myListener); + } + } + } + + public boolean isAutoTestEnabled(RunContentDescriptor descriptor) { + return myEnabledDescriptors.contains(descriptor.getAttachedContent()); + } + + public void runAutoTests() { + for (Content content : myEnabledDescriptors) { + runAutoTest(content); + } + } + + private static void runAutoTest(Content content) { + RunContentDescriptor descriptor = RunContentManagerImpl.getRunContentDescriptorByContent(content); + if (descriptor == null) { + return; + } + Runnable restarter = descriptor.getRestarter(); + if (restarter == null) { + return; + } + final ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler != null && !processHandler.isProcessTerminated()) { + return; + } + restarter.run(); + } + + private class MyDocumentAdapter extends DocumentAdapter { + public void documentChanged(DocumentEvent event) { + final Document document = event.getDocument(); + final VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); + if (vFile != null) { + final FileEditor[] editors = FileEditorManager.getInstance(myProject).getEditors(vFile); + if (editors.length > 0) { + myAutoTestAlarm.cancelAllRequests(); + myAutoTestAlarm.addRequest(myRunTestsRunnable, AUTOTEST_DELAY); + } + } + } + } +} \ No newline at end of file diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/ToggleAutoTestAction.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/ToggleAutoTestAction.java new file mode 100644 index 000000000000..e900bda821a8 --- /dev/null +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/ToggleAutoTestAction.java @@ -0,0 +1,37 @@ +package com.intellij.execution.testframework.autotest; + +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; + +/** + * @author yole + */ +public class ToggleAutoTestAction extends ToggleAction { + public ToggleAutoTestAction() { + super("Toggle auto-test", "Toggle automatic rerun of tests on code changes", + IconLoader.getIcon("/actions/swapPanels.png")); + } + + @Override + public boolean isSelected(AnActionEvent e) { + Project project = e.getData(PlatformDataKeys.PROJECT); + RunContentDescriptor descriptor = e.getData(RunContentManager.RUN_CONTENT_DESCRIPTOR); + return project == null || descriptor == null + ? false + : AutoTestManager.getInstance(project).isAutoTestEnabled(descriptor); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + Project project = e.getData(PlatformDataKeys.PROJECT); + RunContentDescriptor descriptor = e.getData(RunContentManager.RUN_CONTENT_DESCRIPTOR); + if (project != null && descriptor != null) { + AutoTestManager.getInstance(project).setAutoTestEnabled(descriptor, state); + } + } +} diff --git a/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java b/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java index 943f13cefc79..9c83b38427b6 100644 --- a/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java +++ b/platform/util/src/com/intellij/ide/ui/ListCellRendererWrapper.java @@ -32,6 +32,7 @@ public abstract class ListCellRendererWrapper implements ListCellRenderer { private Icon myIcon; private String myText; private String myToolTipText; + private Color myForeground; /** * A combo box for which this cell renderer is created should be passed here. @@ -62,6 +63,7 @@ public abstract class ListCellRendererWrapper implements ListCellRenderer { final JLabel label = (JLabel)component; label.setIcon(myIcon); if (myText != null) label.setText(myText); + if (myForeground != null) label.setForeground(myForeground); label.setToolTipText(myToolTipText); } return component; @@ -97,4 +99,7 @@ public abstract class ListCellRendererWrapper implements ListCellRenderer { myToolTipText = toolTipText; } + public void setForeground(final Color foreground) { + myForeground = foreground; + } } diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java index 033038071288..af407dd2b031 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java +++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java @@ -82,7 +82,6 @@ public class NameUtil { } index++; } - if (upperCaseCount == 0 && lowerCaseCount == 0 && digitCount == 0) continue; String word = name.substring(wordStart, index); array.add(word); } @@ -290,7 +289,7 @@ public class NameUtil { String prevWord = words[i - 1]; if (upperCaseStyle) { word = word.toUpperCase(); - if (prevWord.charAt(prevWord.length() - 1) != '_') { + if (prevWord.charAt(prevWord.length() - 1) != '_' && word.charAt(0) != '_') { word = "_" + word; } } diff --git a/platform/util/src/com/intellij/util/CommonProcessors.java b/platform/util/src/com/intellij/util/CommonProcessors.java index 7fd83237f459..f8f26a6a2dd0 100644 --- a/platform/util/src/com/intellij/util/CommonProcessors.java +++ b/platform/util/src/com/intellij/util/CommonProcessors.java @@ -40,7 +40,13 @@ public class CommonProcessors { } public boolean process(T t) { - myCollection.add(t); + if (accept(t)) { + myCollection.add(t); + } + return true; + } + + protected boolean accept(T t) { return true; } diff --git a/platform/util/src/com/intellij/util/SmartList.java b/platform/util/src/com/intellij/util/SmartList.java index 0bace9c96651..a97da1721993 100644 --- a/platform/util/src/com/intellij/util/SmartList.java +++ b/platform/util/src/com/intellij/util/SmartList.java @@ -140,7 +140,38 @@ public class SmartList extends AbstractList { } public Iterator iterator() { - return mySize == 0 ? EmptyIterator.getInstance() : super.iterator(); + if (mySize == 0) { + return EmptyIterator.getInstance(); + } + if (mySize == 1) { + return new SingletonIterator(); + } + return super.iterator(); + } + + private class SingletonIterator implements Iterator { + private boolean myVisited; + private final int myInitialModCount; + + public SingletonIterator() { + myInitialModCount = modCount; + } + + public boolean hasNext() { + return !myVisited; + } + + public E next() { + if (myVisited) throw new NoSuchElementException(); + myVisited = true; + if (modCount != myInitialModCount) throw new ConcurrentModificationException("ModCount: "+modCount+"; expected: "+myInitialModCount); + return (E)myElem; + } + + public void remove() { + if (modCount != myInitialModCount) throw new ConcurrentModificationException("ModCount: "+modCount+"; expected: "+myInitialModCount); + clear(); + } } public boolean isEmpty() { @@ -161,5 +192,9 @@ public class SmartList extends AbstractList { ContainerUtil.sort((List)myElem, comparator); } } + + public int getModificationCount() { + return modCount; + } } diff --git a/platform/util/src/com/intellij/util/concurrency/Semaphore.java b/platform/util/src/com/intellij/util/concurrency/Semaphore.java index 76d6620d67f5..b3992716d4be 100644 --- a/platform/util/src/com/intellij/util/concurrency/Semaphore.java +++ b/platform/util/src/com/intellij/util/concurrency/Semaphore.java @@ -72,18 +72,18 @@ public class Semaphore { sync.acquireSharedInterruptibly(1); } - public boolean waitFor(final long timeout) { + public boolean waitFor(final long msTimeout) { try { - return waitForUnsafe(timeout); + return waitForUnsafe(msTimeout); } catch (InterruptedException e) { throw new ProcessCanceledException(e); } } - public boolean waitForUnsafe(long timeout) throws InterruptedException { + public boolean waitForUnsafe(long msTimeout) throws InterruptedException { if (sync.tryAcquireShared(1) >= 0) return true; - return sync.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(timeout)); + return sync.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(msTimeout)); } } diff --git a/platform/util/src/com/intellij/util/containers/CollectUtil.java b/platform/util/src/com/intellij/util/containers/CollectUtil.java index 87387804bfa3..b72ce8006c6d 100644 --- a/platform/util/src/com/intellij/util/containers/CollectUtil.java +++ b/platform/util/src/com/intellij/util/containers/CollectUtil.java @@ -17,22 +17,22 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Condition; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Set; /** * @deprecated use {@link ContainerUtil} */ @Deprecated public abstract class CollectUtil { - public abstract HashSet toSet(Iterator iterator); + public abstract Set toSet(Iterator iterator); - public HashSet toSet(Iterator iterator, Convertor convertor) { + public Set toSet(Iterator iterator, Convertor convertor) { return toSet(ConvertingIterator.create(iterator, convertor)); } - public HashSet toSet(Dom[] objects, Convertor convertor) { + public Set toSet(Dom[] objects, Convertor convertor) { return toSet(ContainerUtil.iterate(objects), convertor); } @@ -40,14 +40,14 @@ public abstract class CollectUtil { return toList(iterator).toArray(); } - public abstract ArrayList toList(Iterator iterator); + public abstract List toList(Iterator iterator); - public ArrayList toList(Iterator iterator, Convertor convertor) { + public List toList(Iterator iterator, Convertor convertor) { ConvertingIterator iterator1 = ConvertingIterator.create(iterator, convertor); return toList(iterator1); } - public ArrayList toList(Dom[] objects, Convertor convertor) { + public List toList(Dom[] objects, Convertor convertor) { return toList(ContainerUtil.iterate(objects), convertor); } @@ -60,12 +60,12 @@ public abstract class CollectUtil { } public static final CollectUtil COLLECT = new CollectUtil() { - public HashSet toSet(Iterator iterator) { + public Set toSet(Iterator iterator) { return ContainerUtil.collectSet(iterator); } - public ArrayList toList(Iterator iterator) { - return (ArrayList)ContainerUtil.collect(iterator); + public List toList(Iterator iterator) { + return (List)ContainerUtil.collect(iterator); } }; @@ -78,12 +78,12 @@ public abstract class CollectUtil { myCondition = condition; } - public ArrayList toList(Iterator iterator) { + public List toList(Iterator iterator) { Iterator iterator1 = FilteringIterator.create(iterator, myCondition); return COLLECT.toList((Iterator)(Iterator)iterator1); } - public HashSet toSet(Iterator iterator) { + public Set toSet(Iterator iterator) { return COLLECT.toSet(FilteringIterator.create(iterator, (Condition)myCondition)); } } diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index f9e13020654d..531680d45241 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -25,7 +25,6 @@ import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.Serializable; import java.lang.reflect.Array; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; @@ -134,15 +133,18 @@ public class ContainerUtil { } } - public static ArrayList collect(@NotNull Iterator iterator) { - ArrayList list = new ArrayList(); + @NotNull + public static List collect(@NotNull Iterator iterator) { + if (!iterator.hasNext()) return Collections.emptyList(); + List list = new ArrayList(); addAll(list, iterator); return list; } @NotNull - public static HashSet collectSet(@NotNull Iterator iterator) { - HashSet hashSet = new HashSet(); + public static Set collectSet(@NotNull Iterator iterator) { + if (!iterator.hasNext()) return Collections.emptySet(); + Set hashSet = new HashSet(); addAll(hashSet, iterator); return hashSet; } @@ -477,7 +479,7 @@ public class ContainerUtil { } @NotNull - public static ArrayList collect(@NotNull Iterator iterator, @NotNull FilteringIterator.InstanceOf instanceOf) { + public static List collect(@NotNull Iterator iterator, @NotNull FilteringIterator.InstanceOf instanceOf) { return collect(FilteringIterator.create((Iterator)iterator, instanceOf)); } @@ -1087,7 +1089,10 @@ public class ContainerUtil { y1.add(newY.toNativeArray()); } - private static class EmptyList extends AbstractList implements RandomAccess, Serializable { + /** + * has optimized toArray() as opposed to the {@link java.util.Collections#emptyList()} + */ + private static class EmptyList extends AbstractList implements RandomAccess { private static final EmptyList INSTANCE = new EmptyList(); public int size() { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java index 22a0f918c844..258e9c9f572b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryFinallyCanBeTryWithResourcesInspection.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.HardcodedMethodConstants; @@ -337,6 +338,19 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { final int index = findInitialization(tryBlockStatements, variable, hasInitializer); if (index >= 0 ^ hasInitializer) { + final VariableUsedOutsideContextVisitor visitor = + new VariableUsedOutsideContextVisitor(variable, + tryStatement); + final PsiElement context = + PsiTreeUtil.getParentOfType(variable, + PsiCodeBlock.class); + if (context == null) { + continue; + } + context.accept(visitor); + if (visitor.variableIsUsed()) { + continue; + } found = true; break; } @@ -483,7 +497,7 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { final PsiClassType classType = (PsiClassType) type; final PsiClass aClass = classType.resolve(); return aClass != null && InheritanceUtil.isInheritor(aClass, - "java.io.Closeable"); + "java.lang.AutoCloseable"); } static int findInitialization( @@ -521,4 +535,47 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection { } return result; } + + static class VariableUsedOutsideContextVisitor + extends JavaRecursiveElementVisitor { + + private boolean used = false; + @NotNull private final PsiVariable variable; + private final PsiElement skipContext; + + public VariableUsedOutsideContextVisitor(@NotNull PsiVariable variable, + PsiElement skipContext){ + this.variable = variable; + this.skipContext = skipContext; + } + + @Override public void visitElement(@NotNull PsiElement element){ + if (element.equals(skipContext)) { + return; + } + if (used) { + return; + } + super.visitElement(element); + } + + @Override public void visitReferenceExpression( + @NotNull PsiReferenceExpression referenceExpression){ + if(used){ + return; + } + super.visitReferenceExpression(referenceExpression); + final PsiElement target = referenceExpression.resolve(); + if(target == null){ + return; + } + if(target.equals(variable)){ + used = true; + } + } + + public boolean variableIsUsed(){ + return used; + } + } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java index ef57ae167d12..3d8ac873bc1b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/migration/TryWithIdenticalCatchesInspection.java @@ -81,7 +81,9 @@ public class TryWithIdenticalCatchesInspection extends BaseInspection { final PsiCatchSection catchSection = catchSections[i]; final PsiCodeBlock catchBlock = catchSection.getCatchBlock(); if (catchBlock == null) continue; - InputVariables inputVariables = new InputVariables(Collections.singletonList(catchSection.getParameter()), + final PsiParameter parameter = catchSection.getParameter(); + if (parameter == null) continue; + InputVariables inputVariables = new InputVariables(Collections.singletonList(parameter), statement.getProject(), new LocalSearchScope(catchBlock), false); diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkType.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkType.java index 986836c071d2..aff792523c35 100644 --- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkType.java +++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkType.java @@ -210,6 +210,11 @@ public class AndroidSdkType extends SdkType implements JavaSdkType { return AndroidUtils.ANDROID_ICON; } + @Override + public Icon getIconForAddAction() { + return getIcon(); + } + @Nullable private static Sdk getInternalJavaSdk(Sdk sdk) { final SdkAdditionalData data = sdk.getSdkAdditionalData(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/template/expressions/ChooseTypeExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/template/expressions/ChooseTypeExpression.java index 5d78bdff42f6..b2cc84051433 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/template/expressions/ChooseTypeExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/template/expressions/ChooseTypeExpression.java @@ -29,7 +29,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; -import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeEquals; import java.util.LinkedHashSet; import java.util.Set; @@ -52,9 +51,7 @@ public class ChooseTypeExpression extends Expression { Set result = new LinkedHashSet(); for (TypeConstraint constraint : constraints) { - if (constraint instanceof TypeEquals) { - result.add(PsiTypeLookupItem.createLookupItem(constraint.getType(), null)); - } else if (constraint instanceof SubtypeConstraint) { + if (constraint instanceof SubtypeConstraint) { result.add(PsiTypeLookupItem.createLookupItem(constraint.getDefaultType(), null)); } else if (constraint instanceof SupertypeConstraint) { processSupertypes(constraint.getType(), result); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java index 57e8e0283299..d1b609dfafa5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java @@ -272,6 +272,7 @@ public class GroovyExpectedTypesProvider { expression, PsiType.EMPTY_ARRAY).length > 0; } + @NotNull @Override public PsiType getDefaultType() { return PsiType.INT; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SubtypeConstraint.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SubtypeConstraint.java index 80821405f521..70b418b2a3bf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SubtypeConstraint.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SubtypeConstraint.java @@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiType; import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil.createType; @@ -30,7 +31,7 @@ import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions. public class SubtypeConstraint extends TypeConstraint { private final PsiType myDefaultType; - protected SubtypeConstraint(PsiType type, PsiType defaultType) { + protected SubtypeConstraint(@NotNull PsiType type, @NotNull PsiType defaultType) { super(type); myDefaultType = defaultType; } @@ -39,24 +40,16 @@ public class SubtypeConstraint extends TypeConstraint { return TypesUtil.isAssignableByMethodCallConversion(getType(), type, manager, scope); } + @NotNull public PsiType getDefaultType() { return myDefaultType; } - public static SubtypeConstraint create (PsiType type, PsiType defaultType) { - return new SubtypeConstraint(type, defaultType); - } - - public static SubtypeConstraint create (String fqName, String defaultFqName, PsiElement context) { - return new SubtypeConstraint(createType(fqName, context), - createType(defaultFqName, context)); - } - - public static SubtypeConstraint create (PsiType type) { + public static SubtypeConstraint create(@NotNull PsiType type) { return new SubtypeConstraint(type, type); } - public static SubtypeConstraint create (String fqName, PsiElement context) { + public static SubtypeConstraint create(String fqName, PsiElement context) { PsiClassType type = createType(fqName, context); return new SubtypeConstraint(type, type); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SupertypeConstraint.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SupertypeConstraint.java index f982d7a069a2..1cbbc9d463fd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SupertypeConstraint.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/SupertypeConstraint.java @@ -15,22 +15,19 @@ */ package org.jetbrains.plugins.groovy.lang.psi.expectedTypes; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiType; import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil.createType; - /** * @author ven */ public class SupertypeConstraint extends TypeConstraint { private final PsiType myDefaultType; - protected SupertypeConstraint(PsiType type, PsiType defaultType) { + protected SupertypeConstraint(@NotNull PsiType type, @NotNull PsiType defaultType) { super(type); myDefaultType = defaultType; } @@ -39,25 +36,17 @@ public class SupertypeConstraint extends TypeConstraint { return TypesUtil.isAssignableByMethodCallConversion(type, getType(), manager, scope); } + @NotNull public PsiType getDefaultType() { return myDefaultType; } - public static SupertypeConstraint create (PsiType type, PsiType defaultType) { + public static SupertypeConstraint create(@NotNull PsiType type, @NotNull PsiType defaultType) { return new SupertypeConstraint(type, defaultType); } - public static SupertypeConstraint create (String fqName, String defaultFqName, PsiElement context) { - return new SupertypeConstraint(createType(fqName, context), - createType(defaultFqName, context)); - } - - public static SupertypeConstraint create (PsiType type) { + public static SupertypeConstraint create(@NotNull PsiType type) { return new SupertypeConstraint(type, type); } - public static SupertypeConstraint create (String fqName, PsiElement context) { - PsiClassType type = createType(fqName, context); - return new SupertypeConstraint(type, type); - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeConstraint.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeConstraint.java index b0820455d8c3..78aa8407756e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeConstraint.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeConstraint.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.expectedTypes; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiType; import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.annotations.NotNull; /** * @author ven @@ -29,12 +30,14 @@ public abstract class TypeConstraint { public abstract boolean satisfied(PsiType type, PsiManager manager, GlobalSearchScope scope); + @NotNull public abstract PsiType getDefaultType(); - protected TypeConstraint(PsiType type) { + protected TypeConstraint(@NotNull PsiType type) { myType = type; } + @NotNull public PsiType getType() { return myType; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeEquals.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeEquals.java deleted file mode 100644 index 2f45163941d3..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/TypeEquals.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.lang.psi.expectedTypes; - -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiType; -import com.intellij.psi.search.GlobalSearchScope; - -import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil.createType; - -/** - * @author ven - */ -public class TypeEquals extends TypeConstraint { - protected TypeEquals(PsiType type) { - super(type); - } - - public boolean satisfied(PsiType type, PsiManager manager, GlobalSearchScope scope){ - return type.equals(myType); - } - - public PsiType getDefaultType() { - return getType(); - } - - public static TypeEquals create (PsiType type) { - return new TypeEquals(type); - } - - public static TypeEquals create (String fqName, PsiElement context) { - PsiClassType type = createType(fqName, context); - return new TypeEquals(type); - } -} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java index 7ea842423694..fe04a35201e6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java @@ -318,6 +318,7 @@ public class TypesUtil { return result; } + @NotNull public static PsiClassType createType(String fqName, @NotNull PsiElement context) { return createTypeByFQClassName(fqName, context); } @@ -447,6 +448,7 @@ public class TypesUtil { return PsiSubstitutorImpl.createSubstitutor(result); } + @NotNull public static PsiClassType createTypeByFQClassName(@NotNull String fqName, @NotNull PsiElement context) { return GroovyPsiManager.getInstance(context.getProject()).createTypeByFQClassName(fqName, context.getResolveScope()); } diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java index af994c2069a4..666f9850f69f 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestResultsSender.java @@ -94,9 +94,13 @@ public class JUnit4TestResultsSender extends RunListener { catch (Throwable ignore) {} } - if (assertion.getMessage() != null) { - final Matcher matcher = - Pattern.compile("\nExpected: \"(.*)\"\n got: \"(.*)\"\n", Pattern.DOTALL).matcher(assertion.getMessage()); + final String message = assertion.getMessage(); + if (message != null) { + Matcher matcher = + Pattern.compile("\nExpected: (.*)\n\\s*got: (.*)", Pattern.DOTALL).matcher(message); + if (!matcher.matches()) { + matcher = Pattern.compile("expected same:<(.*)> was not:<(.*)>", Pattern.DOTALL).matcher(message); + } if (matcher.matches()) { return ComparisonDetailsExtractor .create(assertion, matcher.group(1).replaceAll("\\\\n", "\n"), matcher.group(2).replaceAll("\\\\n", "\n")); diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index d0fc00e9ae3e..e642a1f88b26 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -47,7 +47,9 @@ commandline config configs configurator +contravariant controlfile +covariant cron ctrl datafile @@ -127,6 +129,8 @@ keepduplicates ldap likec linestring +labeler +labelers localhost localtime localtimestamp diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/ElementPresentationTemplateImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/ElementPresentationTemplateImpl.java index f26206ff9d59..c7362d83c9a3 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/ElementPresentationTemplateImpl.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/ElementPresentationTemplateImpl.java @@ -15,8 +15,8 @@ */ package com.intellij.util.xml.impl; +import com.intellij.ide.TypePresentationServiceImpl; import com.intellij.ide.presentation.Presentation; -import com.intellij.ide.presentation.PresentationTemplateImpl; import com.intellij.openapi.util.Ref; import com.intellij.util.xml.*; @@ -25,7 +25,7 @@ import javax.swing.*; /** * @author Dmitry Avdeev */ -public class ElementPresentationTemplateImpl extends PresentationTemplateImpl implements ElementPresentationTemplate { +public class ElementPresentationTemplateImpl extends TypePresentationServiceImpl.PresentationTemplateImpl implements ElementPresentationTemplate { public ElementPresentationTemplateImpl(Presentation presentation, Class aClass) { super(presentation, aClass); diff --git a/xml/impl/resources/standardSchemas/xhtml11/xhtml-events-1.mod b/xml/impl/resources/standardSchemas/xhtml11/xhtml-events-1.mod new file mode 100644 index 000000000000..03fd46cbb5c0 --- /dev/null +++ b/xml/impl/resources/standardSchemas/xhtml11/xhtml-events-1.mod @@ -0,0 +1,135 @@ + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildAddImpl.java b/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildAddImpl.java index a4cd94334935..3ee06ba99d3c 100644 --- a/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildAddImpl.java +++ b/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildAddImpl.java @@ -15,14 +15,8 @@ */ package com.intellij.pom.xml.impl.events; -import com.intellij.pom.PomModel; -import com.intellij.pom.event.PomModelEvent; -import com.intellij.pom.xml.XmlAspect; import com.intellij.pom.xml.XmlChangeVisitor; import com.intellij.pom.xml.events.XmlTagChildAdd; -import com.intellij.pom.xml.impl.XmlAspectChangeSetImpl; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlTagChild; @@ -42,14 +36,6 @@ public class XmlTagChildAddImpl implements XmlTagChildAdd { return myChild; } - public static PomModelEvent createXmlTagChildAdd(PomModel source, XmlTag context, XmlTagChild treeElement) { - final PomModelEvent event = new PomModelEvent(source); - final XmlAspectChangeSetImpl xmlAspectChangeSet = new XmlAspectChangeSetImpl(source, PsiTreeUtil.getParentOfType(context, XmlFile.class)); - xmlAspectChangeSet.add(new XmlTagChildAddImpl(context, treeElement)); - event.registerChangeSet(source.getModelAspect(XmlAspect.class), xmlAspectChangeSet); - return event; - } - @SuppressWarnings({"HardCodedStringLiteral"}) public String toString() { return "child added to " + getTag().getName() + " child: " + myChild.toString(); diff --git a/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildRemovedImpl.java b/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildRemovedImpl.java index 23c88d401220..dd92cac98792 100644 --- a/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildRemovedImpl.java +++ b/xml/impl/src/com/intellij/pom/xml/impl/events/XmlTagChildRemovedImpl.java @@ -15,17 +15,8 @@ */ package com.intellij.pom.xml.impl.events; -import com.intellij.pom.PomModel; -import com.intellij.pom.event.PomModelEvent; -import com.intellij.pom.xml.XmlAspect; import com.intellij.pom.xml.XmlChangeVisitor; -import com.intellij.pom.xml.events.XmlChange; import com.intellij.pom.xml.events.XmlTagChildRemoved; -import com.intellij.pom.xml.impl.XmlAspectChangeSetImpl; -import com.intellij.pom.xml.XmlChangeVisitor; -import com.intellij.pom.xml.impl.XmlAspectChangeSetImpl; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlTagChild; @@ -45,13 +36,6 @@ public class XmlTagChildRemovedImpl implements XmlTagChildRemoved { return myChild; } - public static PomModelEvent createXmlTagChildRemoved(PomModel source, XmlTag context, XmlTagChild treeElement) { - final PomModelEvent event = new PomModelEvent(source); - final XmlAspectChangeSetImpl xmlAspectChangeSet = new XmlAspectChangeSetImpl(source, PsiTreeUtil.getParentOfType(context, XmlFile.class)); - xmlAspectChangeSet.add(new XmlTagChildRemovedImpl(context, treeElement)); - event.registerChangeSet(source.getModelAspect(XmlAspect.class), xmlAspectChangeSet); - return event; - } @SuppressWarnings({"HardCodedStringLiteral"}) public String toString() { return "child removed from " + getTag().getName() + " child: " + myChild.toString();