diff --git a/.idea/artifacts/jps_plugins.xml b/.idea/artifacts/jps_plugins.xml index ef658048f36c..89f5927429ed 100644 --- a/.idea/artifacts/jps_plugins.xml +++ b/.idea/artifacts/jps_plugins.xml @@ -3,8 +3,6 @@ $PROJECT_DIR$/out/artifacts/jps - - diff --git a/.idea/modules.xml b/.idea/modules.xml index 00d78128e8be..ce8d7ca005f3 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -60,8 +60,6 @@ - - diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 38597d626387..b90f42d3b3b4 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -157,6 +157,7 @@ libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: " libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html") libraryLicense(name: "classworlds", libraryName: "classworlds-1.1.jar", version: "1.1", license: "codehaus", url: "http://classworlds.codehaus.org/", licenseUrl: "http://classworlds.codehaus.org/license.html") libraryLicense(name: "Android SDK Tools", libraryName: "android-sdk-tools", license: "Apache 2.0", url: "http://source.android.com/") +libraryLicense(name: "Android SDK Tools JPS", libraryName: "android-sdk-tools-jps", license: "Apache 2.0", url: "http://source.android.com/") libraryLicense(name: "Apache Commons BeanUtils", libraryName: "commons-beanutils.jar", version: "1.6", license: "Apache 2.0", url: "http://commons.apache.org/beanutils/") libraryLicense(name: "Apache Commons Codec", libraryName: "commons-codec", version: "1.3", license: "Apache 2.0", url: "http://commons.apache.org/codec/", licenseUrl: "http://commons.apache.org/license.html") libraryLicense(name: "Apache Commons Collections", libraryName: "commons-collections", version: "3.1", license: "Apache 2.0", url: "http://commons.apache.org/collections/", licenseUrl: "http://commons.apache.org/license.html") @@ -239,4 +240,3 @@ jetbrainsLibrary("JPS") jetbrainsLibrary("Maven Embedder") jetbrainsLibrary("tcServiceMessages") jetbrainsLibrary("optimizedFileManager.jar") -jetbrainsLibrary("RunTime") diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java index df36e2769cbf..83243e975e63 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaChainLookupElement.java @@ -19,11 +19,13 @@ import com.intellij.codeInsight.lookup.*; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.ClassConditionKey; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.util.PsiTreeUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Set; @@ -65,7 +67,16 @@ public class JavaChainLookupElement extends LookupElementDecorator() { + addAllClasses(parameters, parameters.getInvocationCount() <= 1, + JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer() { @Override public void consume(LookupElement element) { _result.addElement(element); @@ -68,8 +69,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { } public static void addAllClasses(CompletionParameters parameters, - final CompletionResultSet result, final boolean filterByScope, + @NotNull final PrefixMatcher matcher, @NotNull final Consumer consumer) { final PsiElement insertedElement = parameters.getPosition(); @@ -110,7 +111,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { } final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(insertedElement); - AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), filterByScope, new Consumer() { + AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer() { @Override public void consume(PsiClass psiClass) { if (lookingForAnnotations && !psiClass.isAnnotationType()) return; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 30f5c20fbef8..499040da4f31 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -106,7 +106,7 @@ public class JavaCompletionContributor extends CompletionContributor { withParent(or(psiElement(PsiResourceVariable.class), psiElement(PsiResourceList.class))))); @Nullable - private static ElementFilter getReferenceFilter(PsiElement position) { + public static ElementFilter getReferenceFilter(PsiElement position) { // Completion after extends in interface, type parameter and implements in class final PsiClass containingClass = PsiTreeUtil.getParentOfType(position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class); if (containingClass != null && psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&").accepts(position)) { @@ -239,7 +239,7 @@ public class JavaCompletionContributor extends CompletionContributor { if (!isClassNamePossible(parameters.getPosition()) || !mayStartClassName(result, parameters.isRelaxedMatching())) return; if (mayShowAllClasses(parameters)) { - JavaClassNameCompletionContributor.addAllClasses(parameters, result, parameters.getInvocationCount() <= 2, new Consumer() { + JavaClassNameCompletionContributor.addAllClasses(parameters, parameters.getInvocationCount() <= 2, result.getPrefixMatcher(), new Consumer() { @Override public void consume(LookupElement element) { if (!inheritors.alreadyProcessed(element)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index b803bc1d126d..14fe9f277dd1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -346,6 +346,9 @@ public class JavaCompletionUtil { @Nullable private static PsiType getPsiType(final Object o) { + if (o instanceof ResolveResult) { + return getPsiType(((ResolveResult)o).getElement()); + } if (o instanceof PsiVariable) { return ((PsiVariable)o).getType(); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index 9dcfb4a9f016..a70318059c7c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -15,10 +15,21 @@ */ package com.intellij.codeInsight.completion; +import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.util.CollectConsumer; import com.intellij.util.Consumer; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + /** * @author peter */ @@ -26,29 +37,87 @@ public class JavaNoVariantsDelegator extends NoVariantsDelegator { @Override protected void delegate(CompletionParameters parameters, CompletionResultSet result, Consumer passResult) { - if (parameters.getCompletionType() == CompletionType.BASIC && - parameters.getInvocationCount() <= 1 && - JavaCompletionContributor.mayStartClassName(result, false) && - JavaCompletionContributor.isClassNamePossible(parameters.getPosition())) { - final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); + if (parameters.getCompletionType() == CompletionType.BASIC) { + PsiElement position = parameters.getPosition(); + if (parameters.getInvocationCount() <= 1 && + JavaCompletionContributor.mayStartClassName(result, false) && + JavaCompletionContributor.isClassNamePossible(position)) { + suggestNonImportedClasses(parameters, result); + return; + } - JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), - true, new Consumer() { - @Override - public void consume(LookupElement element) { - JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); - if (classElement != null) { - classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); - } + suggestChainedCalls(parameters, result, position); + } - merger.consume(classElement); - } - }); - - merger.finishedClassProcessing(); - - } else if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) { + if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) { result.runRemainingContributors(parameters.withInvocationCount(3), passResult); } } + + private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result, PsiElement position) { + PsiElement parent = position.getParent(); + if (!(parent instanceof PsiJavaCodeReferenceElement)) { + return; + } + PsiElement qualifier = ((PsiJavaCodeReferenceElement)parent).getQualifier(); + if (!(qualifier instanceof PsiJavaCodeReferenceElement) || + ((PsiJavaCodeReferenceElement)qualifier).isQualified() || + ((PsiJavaCodeReferenceElement)qualifier).resolve() != null) { + return; + } + + String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset()); + CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix); + ElementFilter filter = JavaCompletionContributor.getReferenceFilter(position); + for (LookupElement base : suggestQualifierItems(parameters, (PsiJavaCodeReferenceElement)qualifier, filter)) { + PsiType type = JavaCompletionUtil.getLookupElementType(base); + if (type != null && !PsiType.VOID.equals(type)) { + PsiReferenceExpression ref = ReferenceExpressionCompletionContributor.createMockReference(position, type, base); + for (final LookupElement item : JavaSmartCompletionContributor.completeReference(position, ref, filter, true, true, parameters, + result.getPrefixMatcher())) { + qualifiedCollector.addElement(new JavaChainLookupElement(base, item)); + } + } + } + } + + private static Set suggestQualifierItems(CompletionParameters parameters, + PsiJavaCodeReferenceElement qualifier, + ElementFilter filter) { + String referenceName = qualifier.getReferenceName(); + if (referenceName == null) { + return Collections.emptySet(); + } + + PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName); + Set plainVariants = + JavaSmartCompletionContributor.completeReference(qualifier, qualifier, filter, true, true, parameters, qMatcher); + if (!plainVariants.isEmpty()) { + return plainVariants; + } + + final Set allClasses = new LinkedHashSet(); + JavaClassNameCompletionContributor.addAllClasses(parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset()), + true, qMatcher, new CollectConsumer(allClasses)); + return allClasses; + } + + private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) { + final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); + + JavaClassNameCompletionContributor.addAllClasses(parameters, + true, JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer() { + @Override + public void consume(LookupElement element) { + JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); + if (classElement != null) { + classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); + } + + merger.consume(classElement); + } + }); + + merger.finishedClassProcessing(); + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 649a4ed6e7ff..e4825f5781f2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -155,14 +155,15 @@ public class JavaSmartCompletionContributor extends CompletionContributor { final ElementFilter filter = getReferenceFilter(element); if (filter != null) { final List infos = Arrays.asList(getExpectedTypes(parameters)); - for (final LookupElement item : completeReference(element, reference, filter, true, parameters)) { + for (final LookupElement item : completeReference(element, reference, filter, true, false, parameters, result.getPrefixMatcher())) { if (item.getObject() instanceof PsiClass) { result.addElement(decorate(LookupElementDecorator.withInsertHandler((LookupItem)item, ConstructorInsertHandler.SMART_INSTANCE), infos)); } } } else if (INSIDE_TYPECAST_EXPRESSION.accepts(element)) { - for (final LookupElement item : completeReference(element, reference, new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()), false, parameters)) { + for (final LookupElement item : completeReference(element, reference, new GeneratorFilter(AssignableToFilter.class, new CastTypeGetter()), false, true, parameters, + result.getPrefixMatcher())) { result.addElement(item); } } @@ -182,7 +183,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor { final PsiElement element = parameters.getPosition(); final PsiReference reference = element.getContainingFile().findReferenceAt(parameters.getOffset()); assert reference != null; - for (final LookupElement item : completeReference(element, reference, THROWABLES_FILTER, true, parameters)) { + for (final LookupElement item : completeReference(element, reference, THROWABLES_FILTER, true, false, parameters, result.getPrefixMatcher())) { result.addElement(item); } } @@ -456,7 +457,12 @@ public class JavaSmartCompletionContributor extends CompletionContributor { return ExpectedTypesProvider.getExpectedTypes(expression, true, parameters.getCompletionType() == CompletionType.SMART, false); } - static Set completeReference(final PsiElement element, PsiReference reference, final ElementFilter filter, final boolean acceptClasses, CompletionParameters parameters) { + static Set completeReference(final PsiElement element, + PsiReference reference, + final ElementFilter filter, + final boolean acceptClasses, + final boolean acceptMembers, + CompletionParameters parameters, @Nullable final PrefixMatcher matcher) { if (reference instanceof PsiMultiReference) { reference = ContainerUtil.findInstance(((PsiMultiReference) reference).getReferences(), PsiJavaReference.class); } @@ -470,15 +476,18 @@ public class JavaSmartCompletionContributor extends CompletionContributor { } public boolean isClassAcceptable(Class hintClass) { - if (acceptClasses) { - return ReflectionCache.isAssignable(PsiClass.class, hintClass); + if (ReflectionCache.isAssignable(PsiClass.class, hintClass)) { + return acceptClasses; } - return ReflectionCache.isAssignable(PsiVariable.class, hintClass) || - ReflectionCache.isAssignable(PsiMethod.class, hintClass) || - ReflectionCache.isAssignable(CandidateInfo.class, hintClass); + if (ReflectionCache.isAssignable(PsiVariable.class, hintClass) || + ReflectionCache.isAssignable(PsiMethod.class, hintClass) || + ReflectionCache.isAssignable(CandidateInfo.class, hintClass)) { + return acceptMembers; + } + return false; } - }, true, parameters.getInvocationCount() <= 1, null, parameters); + }, true, parameters.getInvocationCount() <= 1, matcher, parameters); } return Collections.emptySet(); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index 277188306be0..24aa41aafa2e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -33,8 +33,11 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.filters.*; import com.intellij.psi.filters.element.ModifierFilter; import com.intellij.psi.filters.types.AssignableFromFilter; +import com.intellij.psi.impl.FakePsiElement; +import com.intellij.psi.impl.light.LightVariableBuilder; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -122,7 +125,7 @@ public class ReferenceExpressionCompletionContributor { final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2; final Set base = - JavaSmartCompletionContributor.completeReference(element, reference, filter, false, parameters.getParameters()); + JavaSmartCompletionContributor.completeReference(element, reference, filter, false, true, parameters.getParameters(), null); for (final LookupElement item : base) { addSingleArrayElementAccess(element, item, parameters, result); } @@ -177,7 +180,7 @@ public class ReferenceExpressionCompletionContributor { public boolean isClassAcceptable(Class hintClass) { return true; } - }), false, parameters.getParameters()); + }), false, true, parameters.getParameters(), null); for (LookupElement lookupElement : elements) { if (lookupElement.getObject() instanceof PsiMethod) { final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY); @@ -419,32 +422,43 @@ public class ReferenceExpressionCompletionContributor { final Consumer result, PsiType qualifierType, final PsiType expectedType, JavaSmartCompletionParameters parameters) throws IncorrectOperationException { - final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(place.getProject()); - PsiType varType = qualifierType; - if (varType instanceof PsiEllipsisType) { - varType = ((PsiEllipsisType)varType).getComponentType(); - } - if (varType instanceof PsiWildcardType || varType instanceof PsiCapturedWildcardType) { - varType = TypeConversionUtil.erasure(expectedType); - } - - final String typeText = varType.getCanonicalText(); - final JavaCodeFragment block = factory.createCodeBlockCodeFragment(typeText + " xxx;xxx.xxx;", place, false); - final PsiElement secondChild = block.getChildren()[1]; - if (!(secondChild instanceof PsiExpressionStatement)) { - LOG.error(typeText + " of " + varType.getClass()); - } - final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)secondChild; - final PsiReferenceExpression mockRef = (PsiReferenceExpression) expressionStatement.getExpression(); + final PsiReferenceExpression mockRef = createMockReference(place, qualifierType, qualifierItem); final ElementFilter filter = getReferenceFilter(place, true); for (final LookupElement item : completeFinalReference(place, mockRef, filter, parameters)) { - if (shoudChain(place, varType, expectedType, item)) { + if (shoudChain(place, qualifierType, expectedType, item)) { result.consume(new JavaChainLookupElement(qualifierItem, item)); } } } + public static PsiReferenceExpression createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) { + PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject()); + if (qualifierItem.getObject() instanceof PsiClass) { + return (PsiReferenceExpression)factory + .createExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place); + } + + return (PsiReferenceExpression) factory.createExpressionFromText("xxx.xxx", createContextWithXxxVariable(place, qualifierType)); + } + + public static FakePsiElement createContextWithXxxVariable(final PsiElement place, final PsiType varType) { + return new FakePsiElement() { + @Override + public boolean processDeclarations(@NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + PsiElement lastParent, + @NotNull PsiElement place) { + return processor.execute(new LightVariableBuilder("xxx", varType, place), ResolveState.initial()); + } + + @Override + public PsiElement getParent() { + return place; + } + }; + } + private static boolean shoudChain(PsiElement element, PsiType qualifierType, PsiType expectedType, LookupElement item) { if (item.getObject() instanceof PsiMethod) { final PsiMethod method = (PsiMethod)item.getObject(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java index 92134363acbf..883c17f21592 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java @@ -122,6 +122,7 @@ public class PullAsAbstractUpFix extends LocalQuickFixAndIntentionActionOnPsiEle } private static void pullUp(PsiMethod method, PsiClass containingClass, PsiClass baseClass) { + if (!CodeInsightUtilBase.prepareFileForWrite(baseClass.getContainingFile())) return; final MemberInfo memberInfo = new MemberInfo(method); memberInfo.setChecked(true); memberInfo.setToAbstract(true); diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java index 21c23437de84..d684041bc68b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java @@ -30,6 +30,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.filters.ClassFilter; import com.intellij.psi.filters.position.SuperParentFilter; import com.intellij.psi.javadoc.PsiDocComment; @@ -146,6 +147,11 @@ public class JavaTypedHandler extends TypedHandlerDelegate { handleAfterJavaLT(editor, JavaTokenType.LT, JavaTokenType.GT, INVALID_INSIDE_REFERENCE); return Result.STOP; } + else if (c == ':') { + if (autoIndentCase(editor, project, file)) { + return Result.STOP; + } + } return Result.CONTINUE; } @@ -283,4 +289,18 @@ public class JavaTypedHandler extends TypedHandlerDelegate { return false; } + + private static boolean autoIndentCase(Editor editor, Project project, PsiFile file) { + int offset = editor.getCaretModel().getOffset(); + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + PsiElement currElement = file.findElementAt(offset - 1); + if (currElement != null) { + PsiElement parent = currElement.getParent(); + if (parent != null && parent instanceof PsiSwitchLabelStatement) { + CodeStyleManager.getInstance(project).adjustLineIndent(file, parent.getTextOffset()); + return true; + } + } + return false; + } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java index 0ff43fa7f042..400611d56e47 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java @@ -45,6 +45,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; import java.util.List; /** @@ -85,8 +86,10 @@ public class JavaVariableInplaceIntroducer extends InplaceVariableIntroducer rangeMarkers = new ArrayList(occurrenceMarkers); + rangeMarkers.add(exprMarker); editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY, - occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()])); + rangeMarkers.toArray(new RangeMarker[rangeMarkers.size()])); } myExpression = expression; final PsiType defaultType = elementToRename.getType(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java index 370d0e4f271b..c67b7b7b0967 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java @@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.file.JavaDirectoryServiceImpl; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.move.MoveCallback; import com.intellij.util.ArrayUtil; @@ -76,9 +77,12 @@ public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHan @Override protected void run(Result result) throws Throwable { final List adjustedElements = new ArrayList(); - for (PsiElement element : elements) { + for (int i = 0, length = elements.length; i < length; i++) { + PsiElement element = elements[i]; if (element instanceof PsiClass) { - final PsiFile containingFile = obtainContainingFile(element, elements); + final PsiClass topLevelClass = PsiUtil.getTopLevelClass(element); + elements[i] = topLevelClass; + final PsiFile containingFile = obtainContainingFile(topLevelClass, elements); if (containingFile != null && !adjustedElements.contains(containingFile)) { adjustedElements.add(containingFile); } diff --git a/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java b/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java index e0b8236b9c72..57567b0a6d84 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java +++ b/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; public class CommandLineWrapper { + private static final String PREFIX = "-D"; public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, InstantiationException { @@ -54,9 +55,41 @@ public class CommandLineWrapper { reader.close(); } file.delete(); - String progClass = args[1]; - String[] progArgs = new String[args.length - 2]; - System.arraycopy(args, 2, progArgs, 0, progArgs.length); + + int startArgsIdx = 2; + if (args[1].equals("@vm_params")) { + startArgsIdx = 4; + final File vmParamsFile = new File(args[2]); + final BufferedReader vmParamsReader = new BufferedReader(new FileReader(vmParamsFile)); + try { + while (vmParamsReader.ready()) { + final String vmParam = vmParamsReader.readLine().trim(); + final int eqIdx = vmParam.indexOf("="); + String vmParamName; + String vmParamValue; + + if (eqIdx > -1 && eqIdx < vmParam.length() - 1) { + vmParamName = vmParam.substring(0, eqIdx); + vmParamValue = vmParam.substring(eqIdx + 1); + } else { + vmParamName = vmParam; + vmParamValue = ""; + } + vmParamName = vmParamName.trim(); + if (vmParamName.startsWith(PREFIX)) { + vmParamName = vmParamName.substring(PREFIX.length()); + System.setProperty(vmParamName, vmParamValue); + } + } + } + finally { + vmParamsReader.close(); + } + vmParamsFile.delete(); + } + String progClass = args[startArgsIdx - 1]; + String[] progArgs = new String[args.length - startArgsIdx]; + System.arraycopy(args, startArgsIdx, progArgs, 0, progArgs.length); ClassLoader loader = new URLClassLoader((URL[])urls.toArray(new URL[urls.size()]), null); final String classloader = System.getProperty("java.system.class.loader"); if (classloader != null) { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 6d46ad532c64..47542b0b1266 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -1221,4 +1221,16 @@ class Foo {{ myFixture.checkResult 'class Foo { int foo() { re() }}' } + public void testAmbiguousClassQualifier() { + myFixture.addClass("package foo; public class Util { public static void foo() {} }") + myFixture.addClass("package bar; public class Util { public static void bar() {} }") + myFixture.configureByText 'a.java', 'class Foo {{ }}' + type 'Util.' + assert myFixture.lookupElementStrings == ['Util.bar', 'Util.foo'] + type 'fo\n' + myFixture.checkResult '''import foo.Util; + +class Foo {{ Util.foo(); }}''' + } + } diff --git a/jps/.idea/artifacts/jps_gwt.xml b/jps/.idea/artifacts/jps_gwt.xml deleted file mode 100644 index bdd54326be60..000000000000 --- a/jps/.idea/artifacts/jps_gwt.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_javaee.xml b/jps/.idea/artifacts/jps_javaee.xml deleted file mode 100644 index 687d1ac5c3c5..000000000000 --- a/jps/.idea/artifacts/jps_javaee.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_jpa.xml b/jps/.idea/artifacts/jps_jpa.xml deleted file mode 100644 index 95ed475bb3ce..000000000000 --- a/jps/.idea/artifacts/jps_jpa.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_sources.xml b/jps/.idea/artifacts/jps_sources.xml index b9c9e404bca3..2f527656df83 100644 --- a/jps/.idea/artifacts/jps_sources.xml +++ b/jps/.idea/artifacts/jps_sources.xml @@ -3,9 +3,6 @@ $PROJECT_DIR$/out/artifacts - - - diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index de7c5fde53b0..1399c69ed651 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -77,11 +77,13 @@ public class IncProjectBuilder { } catch (ProjectBuildException e) { final Throwable cause = e.getCause(); - if (cause instanceof PersistentEnumerator.CorruptedException || cause instanceof MappingFailedException) { + if (cause instanceof PersistentEnumerator.CorruptedException || cause instanceof MappingFailedException || cause instanceof IOException) { // force rebuild - myMessageDispatcher.processMessage(new CompilerMessage(COMPILE_SERVER_NAME, BuildMessage.Kind.INFO, - "Internal caches are corrupted or have outdated format, forcing project rebuild: " + - e.getMessage())); + myMessageDispatcher.processMessage(new CompilerMessage( + COMPILE_SERVER_NAME, BuildMessage.Kind.INFO, + "Internal caches are corrupted or have outdated format, forcing project rebuild: " + + e.getMessage()) + ); flushContext(context); context = createContext(new AllProjectScope(scope.getProject(), Collections.emptySet(), true), false, true); runBuild(context); diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java index 9355a4a554d1..8af0a272f344 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java @@ -77,10 +77,10 @@ public class FieldPropertyTest extends IncrementalTestCase { } public void testNonIncremental1() throws Exception { - doTest(); + doTest(); } public void testNonIncremental2() throws Exception { - doTest(); + doTest(); } } diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java index 31e596cef0b7..48ed13b9920e 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/IncrementalTestCase.java @@ -19,8 +19,8 @@ import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import junit.framework.TestCase; -import junitx.framework.FileAssert; import org.apache.log4j.Level; import org.apache.log4j.PropertyConfigurator; import org.jetbrains.annotations.NonNls; @@ -342,7 +342,9 @@ public abstract class IncrementalTestCase extends TestCase { new AllProjectScope(project, Collections.emptySet(), false), true, false ); - FileAssert.assertEquals(new File(getBaseDir() + ".log"), new File(getWorkDir() + ".log")); + final String expected = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(getBaseDir() + ".log"))); + final String actual = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(getWorkDir() + ".log"))); + assertEquals(expected, actual); } finally { projectDescriptor.release(); diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java b/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java index a98010808e86..51d644f2ec40 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Callbacks.java @@ -28,5 +28,6 @@ public class Callbacks { void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr); void markOverride(String className, String methodName, String methodSignature); void registerConstantUsage(String className, String fieldName, String fieldOwner); + void registerImports(Collection imports, String rootClass); } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index 0c58185cef4a..67d9f9af2d2a 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -35,10 +35,18 @@ public class Mappings { private boolean myIsDifferentiated = false; private final List myChangedClasses; + private final List myChangedFiles; private void addChangedClass(final DependencyContext.S it) { - assert (myChangedClasses != null); + assert (myChangedClasses != null && myChangedFiles != null); myChangedClasses.add(it); + + final DependencyContext.S file = myClassToSourceFile.get(it); + + if (file != null) { + myChangedFiles.add(it); + } + myIsDifferentiated = true; } @@ -46,6 +54,10 @@ public class Mappings { return myChangedClasses; } + private Collection getChangedFiles() { + return myChangedFiles; + } + private boolean isDifferentiated() { return myIsDifferentiated; } @@ -110,6 +122,7 @@ public class Mappings { private Mappings(final Mappings base) throws IOException { myIsDelta = true; myChangedClasses = new LinkedList(); + myChangedFiles = new LinkedList(); myDeltaIsTransient = base.myDeltaIsTransient; myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "delta"); myContext = base.myContext; @@ -121,6 +134,7 @@ public class Mappings { public Mappings(final File rootDir, final boolean transientDelta) throws IOException { myIsDelta = false; myChangedClasses = null; + myChangedFiles = null; myDeltaIsTransient = transientDelta; myRootDir = rootDir; createImplementation(); @@ -1579,9 +1593,32 @@ public class Mappings { myClassToSourceFile.putAll(delta.myClassToSourceFile); } - mySourceFileToClasses.putAll(delta.mySourceFileToClasses); - mySourceFileToUsages.putAll(delta.mySourceFileToUsages); - mySourceFileToAnnotationUsages.putAll(delta.mySourceFileToAnnotationUsages); + if (delta.isDifferentiated()) { + for (DependencyContext.S f : delta.getChangedFiles()) { + mySourceFileToClasses.remove(f); + final Collection classes = delta.mySourceFileToClasses.get(f); + if (classes != null){ + mySourceFileToClasses.put(f, classes); + } + + mySourceFileToUsages.remove(f); + final Collection clusters = delta.mySourceFileToUsages.get(f); + if (clusters != null){ + mySourceFileToUsages.put(f, clusters); + } + + mySourceFileToAnnotationUsages.remove(f); + final Collection usages = delta.mySourceFileToAnnotationUsages.get(f); + if (usages != null){ + mySourceFileToAnnotationUsages.put(f, usages); + } + } + } + else { + mySourceFileToClasses.putAll(delta.mySourceFileToClasses); + mySourceFileToUsages.putAll(delta.mySourceFileToUsages); + mySourceFileToAnnotationUsages.putAll(delta.mySourceFileToAnnotationUsages); + } final Collection compiledSet = new HashSet(compiled.size()); @@ -1682,6 +1719,24 @@ public class Mappings { public void registerConstantUsage(final String className, final String fieldName, final String fieldOwner) { //To change body of implemented methods use File | Settings | File Templates. } + + @Override + public void registerImports(final Collection imports, final String rootClass) { + final DependencyContext.S rootClassName = myContext.get(rootClass); + final DependencyContext.S fileName = myClassToSourceFile.get(rootClassName); + + for (final String i : imports) { + final DependencyContext.S iname = myContext.get(i); + + myClassToClassDependency.put(rootClassName, iname); + + if (fileName != null) { + final UsageRepr.Cluster cluster = new UsageRepr.Cluster(); + cluster.addUsage(rootClassName, UsageRepr.createClassUsage(myContext, iname)); + mySourceFileToUsages.put(fileName, cluster); + } + } + } }; } diff --git a/jps/plugins/gwt/jps-gwt.iml b/jps/plugins/gwt/jps-gwt.iml deleted file mode 100644 index 704ab03cf56b..000000000000 --- a/jps/plugins/gwt/jps-gwt.iml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService b/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService deleted file mode 100644 index e6e827eede86..000000000000 --- a/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.jps.gwt.GwtCompilerOutputElementType \ No newline at end of file diff --git a/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.builders.ModuleBuilderService b/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.builders.ModuleBuilderService deleted file mode 100644 index 0a91a2e156a1..000000000000 --- a/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.builders.ModuleBuilderService +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.jps.gwt.GwtModuleBuilderService \ No newline at end of file diff --git a/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService b/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService deleted file mode 100644 index ca9265f096a7..000000000000 --- a/jps/plugins/gwt/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.jps.gwt.GwtFacetType \ No newline at end of file diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtCompilerOutputElement.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtCompilerOutputElement.groovy deleted file mode 100644 index 845cebc23b18..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtCompilerOutputElement.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.jetbrains.jps.artifacts.ComplexLayoutElement -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.Project -import org.jetbrains.jps.idea.IdeaProjectLoadingUtil -import org.jetbrains.jps.idea.Facet -import org.jetbrains.jps.artifacts.DirectoryCopyElement -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter - -/** - * @author nik - */ -class GwtCompilerOutputElement extends ComplexLayoutElement { - String facetId - ProjectLoadingErrorReporter errorReporter - - @Override - List getSubstitution(Project project) { - Facet facet = IdeaProjectLoadingUtil.findFacetByIdWithAssertion(project, facetId, errorReporter) - if (!(facet instanceof GwtFacet)) { - errorReporter.error("'$facetId' is not GWT facet!") - } - - GwtFacet gwtFacet = (GwtFacet)facet - return [new DirectoryCopyElement(dirPath: gwtFacet.tempOutputDir)] - } - - Facet findFacet(Project project) { - return IdeaProjectLoadingUtil.findFacetById(project, facetId) - } -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtCompilerOutputElementType.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtCompilerOutputElementType.groovy deleted file mode 100644 index 752ded36d090..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtCompilerOutputElementType.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.artifacts.LayoutElementTypeService -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter - -/** - * @author nik - */ -public class GwtCompilerOutputElementType extends LayoutElementTypeService { - public GwtCompilerOutputElementType() { - super("gwt-compiler-output") - } - - @Override - public LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) { - return new GwtCompilerOutputElement(facetId: tag."@facet", errorReporter: errorReporter) - } -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtFacet.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtFacet.groovy deleted file mode 100644 index 8da8527439b8..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtFacet.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.jetbrains.jps.Module -import org.jetbrains.jps.idea.Facet - -/** - * @author nik - */ -class GwtFacet extends Facet { - Module module - String compilerMaxHeapSize = "128" - String scriptOutputStyle = "DETAILED" - String additionalCompilerParameters = "" - String sdkPath - String tempOutputDir -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtFacetType.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtFacetType.groovy deleted file mode 100644 index 8ddf201eb5b9..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtFacetType.groovy +++ /dev/null @@ -1,42 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Module -import org.jetbrains.jps.idea.Facet -import org.jetbrains.jps.idea.FacetTypeService - -import org.jetbrains.jps.idea.IdeaProjectLoadingUtil - -/** - * @author nik - */ -class GwtFacetType extends FacetTypeService { - GwtFacetType() { - super("gwt") - } - - @Override - Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) { - def facet = new GwtFacet(module: module, name: name) - facetConfiguration.setting.each {Node child -> - String value = child."@value" - switch (child."@name") { - case "compilerMaxHeapSize": - facet.compilerMaxHeapSize = Integer.parseInt(value) - break - case "gwtScriptOutputStyle": - facet.scriptOutputStyle = value - break - case "additionalCompilerParameters": - facet.additionalCompilerParameters = value - break - case "gwtSdkUrl": - facet.sdkPath = macroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(value)) - break - } - } - - return facet - } - -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleBuilder.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleBuilder.groovy deleted file mode 100644 index 90d7368f3cc4..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleBuilder.groovy +++ /dev/null @@ -1,94 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.jetbrains.jps.ModuleBuildState -import org.jetbrains.jps.ModuleBuilder -import org.jetbrains.jps.ModuleChunk -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.artifacts.ArtifactLayoutElement -import org.jetbrains.jps.builders.BuildUtil -import org.jetbrains.jps.ProjectBuilder - -/** - * @author nik - */ -class GwtModuleBuilder implements ModuleBuilder { - def processModule(ModuleBuildState state, ModuleChunk moduleChunk, ProjectBuilder projectBuilder) { - List facets = [] - moduleChunk.modules.each { - it.facets.values().each { - if (it instanceof GwtFacet) { - facets << it - } - } - } - - if (facets.isEmpty()) return - - facets.each {GwtFacet facet -> - compileGwtFacet(facet, projectBuilder, state) - } - } - - def compileGwtFacet(GwtFacet facet, ProjectBuilder projectBuilder, ModuleBuildState state) { - if (!isIncludedInArtifact(facet, projectBuilder.project)) { - projectBuilder.info("GWT Facet in module '${facet.module.name}' isn't included in artifacts so GWT compiler won't be called") - return - } - - if (facet.tempOutputDir != null) return - - if (!new File(facet.sdkPath).exists()) { - projectBuilder.error("GWT SDK directory $facet.sdkPath not found") - } - - List gwtModules = GwtModulesSearcher.findGwtModules(facet.module.sourceRoots) - if (gwtModules.isEmpty()) { - projectBuilder.info("No GWT modules found in GWT facet in ${facet.module} module") - return - } - - String outputDir = projectBuilder.getTempDirectoryPath("GWT_Output_$facet.module.name") - facet.tempOutputDir = outputDir - - def ant = projectBuilder.binding.ant - BuildUtil.deleteDir(projectBuilder, outputDir) - ant.mkdir(dir: outputDir) - - gwtModules.each {String moduleName -> - projectBuilder.stage("Compiling GWT Module") - ant.java(fork: "true", classname: "com.google.gwt.dev.Compiler", failonerror: "true") { - jvmarg(line: "-Xmx${facet.compilerMaxHeapSize}m") - if (!facet.additionalCompilerParameters.isEmpty()) { - jvmarg(line: facet.additionalCompilerParameters) - } - classpath { - pathelement(location: "${facet.sdkPath}/gwt-dev.jar") - state.sourceRootsFromModuleWithDependencies.each { - pathelement(location: it) - } - state.classpath.each { - pathelement(location: it) - } - } - arg(value: "-war") - arg(value: outputDir) - arg(value: "-style") - arg(value: facet.scriptOutputStyle) - arg(value: moduleName) - } - } - } - - private boolean isIncludedInArtifact(GwtFacet gwtFacet, Project project) { - boolean included = false - project.artifacts.values()*.rootElement*.process(project) {LayoutElement element -> - if (element instanceof GwtCompilerOutputElement - && ((GwtCompilerOutputElement)element).findFacet(project) == gwtFacet) { - included = true - } - return !(element instanceof ArtifactLayoutElement) - } - return included - } -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleBuilderService.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleBuilderService.groovy deleted file mode 100644 index ee58cfeb3385..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleBuilderService.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.jetbrains.jps.builders.ModuleBuilderService -import org.jetbrains.jps.ProjectBuilder - -/** - * @author nik - */ -class GwtModuleBuilderService extends ModuleBuilderService { - @Override - registerBuilders(ProjectBuilder builder) { - builder.weavingBuilders << new GwtModuleBuilder() - } - -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleUtil.groovy b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleUtil.groovy deleted file mode 100644 index cd744b880ac6..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModuleUtil.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package org.jetbrains.jps.gwt - -import org.xml.sax.SAXParseException; - -/** - * @author nik - */ -class GwtModuleUtil { - public static boolean hasEntryPoints(File child) { - try { - def root = new XmlParser(false, false).parse(child) - return !root."entry-point".isEmpty() - } - catch (IOException e) { - return true; - } - catch (SAXParseException e) { - return true; - } - } -} diff --git a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModulesSearcher.java b/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModulesSearcher.java deleted file mode 100644 index b1e7658e06df..000000000000 --- a/jps/plugins/gwt/src/org/jetbrains/jps/gwt/GwtModulesSearcher.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.jetbrains.jps.gwt; - -import groovy.util.XmlParser; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * @author nik - */ -public class GwtModulesSearcher { - private static final String GWT_XML_SUFFIX = ".gwt.xml"; - - public static List findGwtModules(List sourcePaths) { - final List result = new ArrayList(); - for (CharSequence sourcePath : sourcePaths) { - collectGwtModules(new File(sourcePath.toString()), "", result); - } - return result; - } - - private static void collectGwtModules(File dir, String packageName, List result) { - if (!dir.isDirectory()) { - return; - } - - final File[] files = dir.listFiles(); - if (files != null) { - for (File child : files) { - final String name = child.getName(); - if (child.isFile() && name.endsWith(GWT_XML_SUFFIX)) { - if (GwtModuleUtil.hasEntryPoints(child)) { - result.add(packageName + name.substring(0, name.length() - GWT_XML_SUFFIX.length())); - } - } - else { - collectGwtModules(child, packageName + name + ".", result); - } - } - } - } -} diff --git a/jps/plugins/gwt/testData/modules/com/app/App.gwt.xml b/jps/plugins/gwt/testData/modules/com/app/App.gwt.xml deleted file mode 100644 index d31f3637779f..000000000000 --- a/jps/plugins/gwt/testData/modules/com/app/App.gwt.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/jps/plugins/gwt/testData/modules/com/app/InvalidXml.gwt.xml b/jps/plugins/gwt/testData/modules/com/app/InvalidXml.gwt.xml deleted file mode 100644 index 4e87e20e57f4..000000000000 --- a/jps/plugins/gwt/testData/modules/com/app/InvalidXml.gwt.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/jps/plugins/gwt/testData/modules/com/app/NoEntryPoints.gwt.xml b/jps/plugins/gwt/testData/modules/com/app/NoEntryPoints.gwt.xml deleted file mode 100644 index 86a82eb089d4..000000000000 --- a/jps/plugins/gwt/testData/modules/com/app/NoEntryPoints.gwt.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/jps/plugins/gwt/testSrc/org/jetbrains/jps/gwt/GwtModulesSearcherTest.java b/jps/plugins/gwt/testSrc/org/jetbrains/jps/gwt/GwtModulesSearcherTest.java deleted file mode 100644 index 0375f1105c49..000000000000 --- a/jps/plugins/gwt/testSrc/org/jetbrains/jps/gwt/GwtModulesSearcherTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.jetbrains.jps.gwt; - -import junit.framework.TestCase; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -/** - * @author nik - */ -public class GwtModulesSearcherTest extends TestCase { - public void test() { - List modules = GwtModulesSearcher.findGwtModules(Arrays.asList("plugins/gwt/testData/modules")); - assertEquals(new HashSet(Arrays.asList("com.app.App", "com.app.InvalidXml")), - new HashSet(modules)); - } -} diff --git a/jps/plugins/jpa/jps-jpa.iml b/jps/plugins/jpa/jps-jpa.iml deleted file mode 100644 index 9d7005eff21a..000000000000 --- a/jps/plugins/jpa/jps-jpa.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/jps/plugins/jpa/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService b/jps/plugins/jpa/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService deleted file mode 100644 index 93c232491864..000000000000 --- a/jps/plugins/jpa/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.jps.jpa.JpaFacetDescriptorsElementType \ No newline at end of file diff --git a/jps/plugins/jpa/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService b/jps/plugins/jpa/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService deleted file mode 100644 index 3617f029eafb..000000000000 --- a/jps/plugins/jpa/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.jps.jpa.JpaFacetType \ No newline at end of file diff --git a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacet.groovy b/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacet.groovy deleted file mode 100644 index 0ff329b873d5..000000000000 --- a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacet.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.jps.jpa - -import org.jetbrains.jps.idea.Facet - -/** - * @author nik - */ -class JpaFacet extends Facet { - final List descriptors = [] -} diff --git a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetDescriptorsElement.groovy b/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetDescriptorsElement.groovy deleted file mode 100644 index 55ef512d28cc..000000000000 --- a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetDescriptorsElement.groovy +++ /dev/null @@ -1,34 +0,0 @@ -package org.jetbrains.jps.jpa - -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.ComplexLayoutElement -import org.jetbrains.jps.artifacts.FileCopyElement -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.artifacts.LayoutElementFactory -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter - -/** - * @author nik - */ -class JpaFacetDescriptorsElement extends ComplexLayoutElement { - String facetId - ProjectLoadingErrorReporter errorReporter - - List getSubstitution(Project project) { - def moduleName = facetId.substring(0, facetId.indexOf('/')) - def facet = project.modules[moduleName]?.facets[facetId] - if (facet == null) { - errorReporter.error("Unknown facet id: $facetId") - } - - if (!(facet instanceof JpaFacet)) { - errorReporter.error("$facetId facet is not JPA facet") - } - - List result = [] - facet.descriptors.each {String path -> - result << LayoutElementFactory.createParentDirectories("META-INF", new FileCopyElement(filePath: path)) - } - return result - } -} diff --git a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetDescriptorsElementType.groovy b/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetDescriptorsElementType.groovy deleted file mode 100644 index 78d5de1d5440..000000000000 --- a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetDescriptorsElementType.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package org.jetbrains.jps.jpa - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.artifacts.LayoutElementTypeService -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter - -/** - * @author nik - */ -class JpaFacetDescriptorsElementType extends LayoutElementTypeService { - JpaFacetDescriptorsElementType() { - super("jpa-descriptors") - } - - @Override - LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) { - return new JpaFacetDescriptorsElement(facetId: tag."@facet", errorReporter: errorReporter) - } -} diff --git a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetType.groovy b/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetType.groovy deleted file mode 100644 index 50886e42cbef..000000000000 --- a/jps/plugins/jpa/src/org/jetbrains/jps/jpa/JpaFacetType.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package org.jetbrains.jps.jpa - -import org.jetbrains.jps.idea.FacetTypeService -import org.jetbrains.jps.idea.Facet -import org.jetbrains.jps.Module -import org.jetbrains.jps.MacroExpander - -import org.jetbrains.jps.idea.IdeaProjectLoadingUtil - -/** - * @author nik - */ -class JpaFacetType extends FacetTypeService { - JpaFacetType() { - super("jpa") - } - - @Override - Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) { - JpaFacet facet = new JpaFacet(name: name) - facetConfiguration?.deploymentDescriptor?.each {Node tag -> - String path = macroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(tag."@url")) - facet.descriptors << path - } - return facet - } - - -} diff --git a/jps/plugins/jpa/testData/jpaTest/jpaTest.iml b/jps/plugins/jpa/testData/jpaTest/jpaTest.iml deleted file mode 100644 index c44032a334dc..000000000000 --- a/jps/plugins/jpa/testData/jpaTest/jpaTest.iml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jps/plugins/jpa/testData/jpaTest/jpaTest.ipr b/jps/plugins/jpa/testData/jpaTest/jpaTest.ipr deleted file mode 100644 index 3b17b74a3a30..000000000000 --- a/jps/plugins/jpa/testData/jpaTest/jpaTest.ipr +++ /dev/null @@ -1,24 +0,0 @@ - - - - - $PROJECT_DIR$/out/artifacts/jpaTest - - - - - - - - - - - - - - - - - - - diff --git a/jps/plugins/jpa/testData/jpaTest/src/META-INF/persistence.xml b/jps/plugins/jpa/testData/jpaTest/src/META-INF/persistence.xml deleted file mode 100644 index ec93f1cad212..000000000000 --- a/jps/plugins/jpa/testData/jpaTest/src/META-INF/persistence.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/jps/plugins/jpa/testSrc/org/jetbrains/jps/JpaTest.groovy b/jps/plugins/jpa/testSrc/org/jetbrains/jps/JpaTest.groovy deleted file mode 100644 index 11255f751ab0..000000000000 --- a/jps/plugins/jpa/testSrc/org/jetbrains/jps/JpaTest.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package org.jetbrains.jps - -/** - * @author nik - */ -class JpaTest extends JpsBuildTestCase { - public void testOverwriteArtifacts() throws Exception { - doTest("plugins/jpa/testData/jpaTest/jpaTest.ipr", null, { - dir("artifacts") { - dir("jpaTest") { - dir("WEB-INF") { - dir("classes") { - dir("META-INF") { - file("persistence.xml") - } - } - } - } - } - dir("production") { - dir("jpaTest") { - dir("META-INF") { - file("persistence.xml") - } - } - } - }) - } -} diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java index b7ac712d6767..56eb0c10af62 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java @@ -100,4 +100,8 @@ public class CompletionParameters { public boolean isRelaxedMatching() { return myRelaxedMatching; } + + public CompletionParameters withPosition(PsiElement element, int offset) { + return new CompletionParameters(element, myOriginalFile, myCompletionType, offset, myInvocationCount, myLookup, myRelaxedMatching); + } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementPresentation.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementPresentation.java index 08f0eb90752e..e8552d0191e2 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementPresentation.java +++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementPresentation.java @@ -167,4 +167,10 @@ public class LookupElementPresentation { public void setTypeGrayed(boolean typeGrayed) { myTypeGrayed = typeGrayed; } + + public static LookupElementPresentation renderElement(LookupElement element) { + LookupElementPresentation presentation = new LookupElementPresentation(); + element.renderElement(presentation); + return presentation; + } } diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java index 23076fc95046..62ea6513fb23 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import java.io.*; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; +import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -147,32 +148,13 @@ public class JdkUtil { commandLine.setExePath(exePath); ParametersList parametersList = javaParameters.getVMParametersList(); - commandLine.addParameters(parametersList.getList()); - - // Value of -Dfile.encoding and charset of GeneralCommandLine should be in sync in order process's input and output be correctly handled. - String encoding = parametersList.getPropertyValue("file.encoding"); - if (encoding == null) { - Charset charset = javaParameters.getCharset(); - if (charset == null) charset = EncodingManager.getInstance().getDefaultCharset(); - if (charset == null) charset = CharsetToolkit.getDefaultSystemCharset(); - commandLine.addParameter("-Dfile.encoding=" + charset.name()); - commandLine.setCharset(charset); - } - else { - try { - Charset charset = Charset.forName(encoding); - commandLine.setCharset(charset); - } - catch (UnsupportedCharsetException ignore) { - } - } - commandLine.setEnvParams(javaParameters.getEnv()); commandLine.setPassParentEnvs(javaParameters.isPassParentEnvs()); final Class commandLineWrapper; if (forceDynamicClasspath && (commandLineWrapper = getCommandLineWrapperClass()) != null) { File classpathFile = null; + File vmParamsFile = null; if(!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){ try { classpathFile = FileUtil.createTempFile("classpath", null); @@ -199,16 +181,55 @@ public class JdkUtil { catch (IOException e) { LOG.error(e); } + + try { + vmParamsFile = FileUtil.createTempFile("vm_params", null); + final PrintWriter writer = new PrintWriter(vmParamsFile); + try { + for (String param : parametersList.getList()) { + if (param.startsWith("-D")) { + writer.println(param); + } + } + } + finally { + writer.close(); + } + } + catch (IOException e) { + LOG.error(e); + } } + final List list = parametersList.getList(); + if (vmParamsFile == null) { + commandLine.addParameters(list); + } else { + for (String param : list) { + if (!param.trim().startsWith("-D")) { + commandLine.addParameter(param); + } + } + } + appendEncoding(javaParameters, commandLine, parametersList); if (classpathFile != null) { commandLine.addParameter(commandLineWrapper.getName()); commandLine.addParameter(classpathFile.getAbsolutePath()); } + if (vmParamsFile != null) { + commandLine.addParameter("@vm_params"); + commandLine.addParameter(vmParamsFile.getAbsolutePath()); + } } - else if(!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){ + else if (!parametersList.hasParameter("-classpath") && !parametersList.hasParameter("-cp")){ + commandLine.addParameters(parametersList.getList()); + appendEncoding(javaParameters, commandLine, parametersList); + commandLine.addParameter("-classpath"); commandLine.addParameter(javaParameters.getClassPath().getPathsString()); + } else { + commandLine.addParameters(parametersList.getList()); + appendEncoding(javaParameters, commandLine, parametersList); } final String mainClass = javaParameters.getMainClass(); @@ -220,6 +241,26 @@ public class JdkUtil { return commandLine; } + private static void appendEncoding(SimpleJavaParameters javaParameters, GeneralCommandLine commandLine, ParametersList parametersList) { + // Value of -Dfile.encoding and charset of GeneralCommandLine should be in sync in order process's input and output be correctly handled. + String encoding = parametersList.getPropertyValue("file.encoding"); + if (encoding == null) { + Charset charset = javaParameters.getCharset(); + if (charset == null) charset = EncodingManager.getInstance().getDefaultCharset(); + if (charset == null) charset = CharsetToolkit.getDefaultSystemCharset(); + commandLine.addParameter("-Dfile.encoding=" + charset.name()); + commandLine.setCharset(charset); + } + else { + try { + Charset charset = Charset.forName(encoding); + commandLine.setCharset(charset); + } + catch (UnsupportedCharsetException ignore) { + } + } + } + @Nullable private static Class getCommandLineWrapperClass() { try { diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java index 6b6fd6351e66..452f22b6a61b 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogConsoleBase.java @@ -617,6 +617,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L myAlarm.addRequest(this, 100); } }; + if (myAlarm.isDisposed()) return; myAlarm.addRequest(runnable, 10); } diff --git a/platform/lang-impl/src/com/intellij/formatting/IndentInfo.java b/platform/lang-impl/src/com/intellij/formatting/IndentInfo.java index 6d7c0e80627b..16788a89382e 100644 --- a/platform/lang-impl/src/com/intellij/formatting/IndentInfo.java +++ b/platform/lang-impl/src/com/intellij/formatting/IndentInfo.java @@ -24,11 +24,6 @@ public class IndentInfo { private final int mySpaces; private final int myIndentSpaces; private final int myLineFeeds; - // - // The flag is used for compatibility with older versions of Intellij IDEA where spaces could be replaced with tabs inside a line of code, - // not only in the beginning of the line. - // - private static boolean myInlineTabsEnabled = "true".equalsIgnoreCase(System.getProperty("enable.inline.tabs")); /** @see WhiteSpace#setForceSkipTabulationsUsage(boolean) */ private boolean myForceSkipTabulationsUsage; @@ -63,45 +58,38 @@ public class IndentInfo { if (options.USE_TAB_CHARACTER && !myForceSkipTabulationsUsage) { if (options.SMART_TABS) { - return fillUsingSmartTabs(buffer, options); - } - else if (myLineFeeds > 0 || myInlineTabsEnabled) { - return fillUsingTabs(buffer, options); - } - } - int spaces = getTotalSpaces(); - if (spaces > 0) { - StringUtil.repeatSymbol(buffer, ' ', spaces); - } - return buffer.toString(); - - } - - private String fillUsingTabs(StringBuffer buffer, CommonCodeStyleSettings.IndentOptions options) { - int size = getTotalSpaces(); - while (size > 0) { - if (size >= options.TAB_SIZE) { - buffer.append('\t'); - size -= options.TAB_SIZE; + int tabCount = myIndentSpaces / options.TAB_SIZE; + int leftSpaces = myIndentSpaces - tabCount * options.TAB_SIZE; + if (tabCount > 0) { + StringUtil.repeatSymbol(buffer, '\t', tabCount); + } + if (leftSpaces + mySpaces > 0) { + StringUtil.repeatSymbol(buffer, ' ', leftSpaces + mySpaces); + } } else { - buffer.append(' '); - size--; + int size = getTotalSpaces(); + while (size > 0) { + if (size >= options.TAB_SIZE) { + buffer.append('\t'); + size -= options.TAB_SIZE; + } + else { + buffer.append(' '); + size--; + } + } + } + } + else { + int spaces = getTotalSpaces(); + if (spaces > 0) { + StringUtil.repeatSymbol(buffer, ' ', spaces); } } - return buffer.toString(); - } - private String fillUsingSmartTabs(StringBuffer buffer, CommonCodeStyleSettings.IndentOptions options) { - int tabCount = myIndentSpaces / options.TAB_SIZE; - int leftSpaces = myIndentSpaces - tabCount * options.TAB_SIZE; - if (tabCount > 0) { - StringUtil.repeatSymbol(buffer, '\t', tabCount); - } - if (leftSpaces + mySpaces > 0) { - StringUtil.repeatSymbol(buffer, ' ', leftSpaces + mySpaces); - } return buffer.toString(); + } public int getTotalSpaces() { diff --git a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java index 1fae47755094..3ab271d75bc3 100644 --- a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java +++ b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package com.intellij.ide; import com.intellij.CommonBundle; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.util.ExecUtil; import com.intellij.openapi.application.*; import com.intellij.openapi.diagnostic.Logger; @@ -42,6 +44,7 @@ import javax.swing.*; import java.awt.*; import java.io.*; import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.HashSet; @@ -58,20 +61,19 @@ public class BrowserUtil { // We have to violate the RFC since we need to distinguish // real schemes from local Windows paths; The only difference // with RFC is that we do not allow schemes with length=1 (in other case - // local paths like "C:/temp/index.html" whould be erroneously interpreted as + // local paths like "C:/temp/index.html" would be erroneously interpreted as // external URLs.) - @NonNls private static final Pattern ourExternalPrefix = Pattern.compile("^[\\w\\+\\.\\-]{2,}:"); - private static final Pattern ourAnchorsuffix = Pattern.compile("#(.*)$"); + private static final Pattern ourExternalPrefix = Pattern.compile("^[\\w\\+\\.\\-]{2,}:"); + private static final Pattern ourAnchorSuffix = Pattern.compile("#(.*)$"); - private BrowserUtil() { - } + private BrowserUtil() { } public static boolean isAbsoluteURL(String url) { return ourExternalPrefix.matcher(url.toLowerCase()).find(); } public static String getDocURL(String url) { - Matcher anchorMatcher = ourAnchorsuffix.matcher(url); + Matcher anchorMatcher = ourAnchorSuffix.matcher(url); if (anchorMatcher.find()) { return anchorMatcher.reset().replaceAll(""); @@ -81,7 +83,7 @@ public class BrowserUtil { } @Nullable - public static URL getURL(String url) throws java.net.MalformedURLException { + public static URL getURL(String url) throws MalformedURLException { if (!isAbsoluteURL(url)) { return new URL("file", "", url); } @@ -89,128 +91,95 @@ public class BrowserUtil { return VfsUtil.convertToURL(url); } - private static void launchBrowser(final String url, String[] command) { - try { - URL curl = getURL(url); + /** + * Main method: tries to launch a browser using every possible way. + * + * @param url an URL to open. + */ + public static void launchBrowser(@NonNls String url) { + LOG.debug("Launch browser: " + url); - if (curl != null) { - final String urlString = curl.toString(); - String[] commandLine; - if (SystemInfo.isWindows && isUseDefaultBrowser()) { - commandLine = new String[command.length + 2]; - System.arraycopy(command, 0, commandLine, 0, command.length); - commandLine[commandLine.length - 2] = "\"\""; - commandLine[commandLine.length - 1] = "\"" + redirectUrl(url, urlString) + "\""; - } - else { - commandLine = new String[command.length + 1]; - System.arraycopy(command, 0, commandLine, 0, command.length); - commandLine[commandLine.length - 1] = SystemInfo.isMac && isUseDefaultBrowser() ? escapeUrl(redirectUrl(url, urlString)) - : escapeUrl(urlString); - } - Runtime.getRuntime().exec(commandLine); - if (LOG.isDebugEnabled()) { - LOG.debug("Browser launched with command line: " + Arrays.toString(commandLine)); - } + if (url.startsWith("jar:")) { + url = extractFiles(url); + if (url == null) return; + } + + if (getGeneralSettingsInstance().isUseDefaultBrowser() && canStartDefaultBrowser()) { + final String[] command = getDefaultBrowserCommand(); + if (command != null) { + launchBrowserByCommand(url, command); } else { - showErrorMessage(IdeBundle.message("error.malformed.url", url), CommonBundle.getErrorTitle()); + launchBrowserUsingDesktopApi(url); } } - catch (final IOException e) { - showErrorMessage(IdeBundle.message("error.cannot.start.browser", e.getMessage()), - CommonBundle.getErrorTitle()); - } - } - - /** - * This method works around Windows 'start' command behaivor of dropping anchors from the url for local urls. - */ - private static String redirectUrl(String url, @NonNls String urlString) throws IOException { - if (url.indexOf('&') == -1 && (!urlString.startsWith("file:") || urlString.indexOf("#") == -1)) return urlString; - - File redirect = FileUtil.createTempFile("redirect", ".html"); - redirect.deleteOnExit(); - FileWriter writer = new FileWriter(redirect); - writer.write(""); - writer.close(); - return VfsUtil.pathToUrl(redirect.getAbsolutePath()); - } - - private static boolean isUseDefaultBrowser() { - Application application = ApplicationManager.getApplication(); - if (application == null) { - return true; - } else { - return getGeneralSettingsInstance().isUseDefaultBrowser(); + launchBrowserUsingStandardWay(url); } } - private static void showErrorMessage(final String message, final String title) { - final Application app = ApplicationManager.getApplication(); - if (app == null) { - return; // Not started yet. Not able to show message up. (Could happen in License panel under Linux). - } - - Runnable runnable = new Runnable() { - public void run() { - Messages.showMessageDialog(message, - title, - Messages.getErrorIcon()); - } - }; - - if (app.isDispatchThread()) { - runnable.run(); - } - else { - app.invokeLater(runnable, ModalityState.NON_MODAL); - } - } - - private static void launchBrowserUsingStandardWay(final String url) { - String[] command; - try { - String browserPath = getGeneralSettingsInstance().getBrowserPath(); - if (browserPath == null || browserPath.trim().length() == 0) { - showErrorMessage(IdeBundle.message("error.please.specify.path.to.web.browser"), - IdeBundle.message("title.browser.not.found")); - return; - } - - command = getOpenBrowserCommand(browserPath); - } - catch (NullPointerException e) { - // todo: fix the possible problem on startup, see SCR #35066 - command = getDefaultBrowserCommand(); - if (command == null) { - showErrorMessage(IdeBundle.message("error.please.open.url.manually", url, ApplicationNamesInfo.getInstance().getProductName()), - IdeBundle.message("title.browser.path.not.found")); - return; - } - } - // We do not need to check browserPath under Win32 - - launchBrowser(url, command); - } - private static GeneralSettings getGeneralSettingsInstance() { - final GeneralSettings settings = GeneralSettings.getInstance(); - if (settings != null) return settings; - return new GeneralSettings(); + final GeneralSettings settings = ApplicationManager.getApplication() != null ? GeneralSettings.getInstance() : null; + return settings != null ? settings : new GeneralSettings(); } - private static boolean launchDefaultBrowserUsingJdk6Api(String sUrl) { - try { - URL url = getURL(sUrl); - if (url == null) return false; - Desktop.getDesktop().browse(url.toURI()); - LOG.debug("Browser launched using JDK 1.6 API"); + public static boolean canStartDefaultBrowser() { + if (SystemInfo.isMac || SystemInfo.isWindows) { return true; } - catch (Exception e) { - return false; + else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen) { + return true; + } + else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + return true; + } + + return false; + } + + @Nullable + @NonNls + private static String[] getDefaultBrowserCommand() { + if (SystemInfo.isWindows9x) { + return new String[]{"command.com", "/c", "start"}; + } + else if (SystemInfo.isWindows) { + return new String[]{"cmd.exe", "/c", "start"}; + } + else if (SystemInfo.isMac) { + return new String[]{ExecUtil.getOpenCommandPath()}; + } + else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen) { + return new String[]{"xdg-open"}; + } + + return null; + } + + private static void launchBrowserByCommand(final String url, @NotNull final String[] command) { + URL curl; + try { + curl = getURL(url); + } + catch (MalformedURLException ignored) { + curl = null; + } + if (curl == null) { + showErrorMessage(IdeBundle.message("error.malformed.url", url), CommonBundle.getErrorTitle()); + return; + } + + try { + final GeneralCommandLine commandLine = new GeneralCommandLine(command); + commandLine.addParameter(curl.toString()); + commandLine.createProcess(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Browser launched with command line: " + commandLine.getCommandLineString()); + } + } + catch (final ExecutionException e) { + showErrorMessage(IdeBundle.message("error.cannot.start.browser", e.getMessage()), CommonBundle.getErrorTitle()); } } @@ -224,6 +193,84 @@ public class BrowserUtil { } } + private static boolean launchBrowserUsingDesktopApi(final String sUrl) { + try { + URL url = getURL(sUrl); + if (url == null) return false; + Desktop.getDesktop().browse(url.toURI()); + LOG.debug("Browser launched using JDK 1.6 API"); + return true; + } + catch (Exception e) { + return false; + } + } + + private static void launchBrowserUsingStandardWay(final String url) { + String browserPath = getGeneralSettingsInstance().getBrowserPath(); + if (StringUtil.isEmptyOrSpaces(browserPath)) { + showErrorMessage(IdeBundle.message("error.please.specify.path.to.web.browser"), IdeBundle.message("title.browser.not.found")); + return; + } + + launchBrowserByCommand(url, getOpenBrowserCommand(browserPath)); + } + + /** + * @deprecated use {@link #getOpenBrowserCommand(String)} instead + */ + @SuppressWarnings({"UnusedDeclaration"}) + public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath, final String... parameters) { + return getOpenBrowserCommand(browserPath); + } + + public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath) { + final String[] command; + if (SystemInfo.isMac) { + if (new File(browserPath).isFile()) { + // versions before 10.6 don't allow to pass command line arguments to browser via 'open' command + // so we use full path to browser executable in such case + command = new String[] {browserPath}; + } + else { + command = new String[]{ExecUtil.getOpenCommandPath(), "-a", browserPath}; + } + } + else if (SystemInfo.isWindows) { + if (new File(browserPath).isFile()) { + command = new String[]{browserPath}; + } + else { + command = new String[]{SystemInfo.isWindows9x ? "command.com" : "cmd.exe", "/c", "start", browserPath}; + } + } + else { + command = new String[]{browserPath}; + } + return command; + } + + private static void showErrorMessage(final String message, final String title) { + final Application app = ApplicationManager.getApplication(); + if (app == null) { + return; // Not started yet. Not able to show message up. (Could happen in License panel under Linux). + } + + Runnable runnable = new Runnable() { + public void run() { + Messages.showMessageDialog(message, title, Messages.getErrorIcon()); + } + }; + + if (app.isDispatchThread()) { + runnable.run(); + } + else { + app.invokeLater(runnable, ModalityState.NON_MODAL); + } + } + + @Nullable private static String extractFiles(String url) { try { int sharpPos = url.indexOf('#'); @@ -350,100 +397,10 @@ public class BrowserUtil { return new File(PathManager.getSystemPath(), "ExtractedFiles"); } - public static void launchBrowser(@NonNls String url) { - LOG.debug("Launch browser: " + url); - if (url.startsWith("jar:")) { - url = extractFiles(url); - if (url == null) return; - } - if (canStartDefaultBrowser() && isUseDefaultBrowser()) { - if (SystemInfo.isLinux && launchDefaultBrowserUsingJdk6Api(url)) { - return; - } - - launchBrowser(url, getDefaultBrowserCommand()); - } - else { - launchBrowserUsingStandardWay(url); - } - } - - @NonNls - private static String[] getDefaultBrowserCommand() { - if (SystemInfo.isWindows9x) { - return new String[]{"command.com", "/c", "start"}; - } - else if (SystemInfo.isWindows) { - return new String[]{"cmd.exe", "/c", "start"}; - } - else if (SystemInfo.isMac) { - return new String[]{ExecUtil.getOpenCommandPath()}; - } - else if (SystemInfo.isUnix) { - return new String[]{"mozilla"}; - } - else { - return null; - } - } - - public static boolean canStartDefaultBrowser() { - if (SystemInfo.isMac || SystemInfo.isWindows) { - return true; - } - - if (SystemInfo.isLinux && Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { - return true; - } - - return false; - } - public static boolean isOpenCommandSupportArgs() { return SystemInfo.isMacOSSnowLeopard; } - /** - * @deprecated use {@link #getOpenBrowserCommand(String)} instead - */ - public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath, final String... parameters) { - return getOpenBrowserCommand(browserPath); - } - - public static String[] getOpenBrowserCommand(final @NonNls @NotNull String browserPath) { - String[] command; - if (SystemInfo.isMac) { - File browserExecutable = new File(browserPath); - if (browserExecutable.isFile()) { - //versions before 10.6 don't allow to pass command line arguments to browser via 'open' command so we use full path to browser executable in such cases - command = new String[] {browserPath}; - } - else { - command = new String[]{ExecUtil.getOpenCommandPath(), "-a", browserPath}; - } - } - else if (SystemInfo.isWindows9x) { - if (browserPath.indexOf(File.separatorChar) != -1) { - command = new String[]{browserPath}; - } - else { - command = new String[]{"command.com", "/c", "start", browserPath}; - } - } - else if (SystemInfo.isWindows) { - if (browserPath.indexOf(File.separatorChar) != -1) { - command = new String[]{browserPath}; - } - else { - command = new String[]{"cmd.exe", "/c", "start", browserPath}; - } - } - else { - command = new String[]{browserPath}; - } - return command; - } - private static class ConfirmExtractDialog extends OptionsDialog { private ConfirmExtractDialog() { super(null); diff --git a/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java b/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java index 76425e774f16..856ee05b2227 100644 --- a/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java +++ b/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.intellij.util.ui; import com.intellij.CommonBundle; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -50,7 +51,7 @@ public abstract class OptionsDialog extends DialogWrapper { } } - protected OptionsDialog(Project project) { + protected OptionsDialog(@Nullable Project project) { super(project, true); myProject = project; setDoNotAskOption(new MyDoNotAsk()); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 9360c401f53d..cbe973491f77 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vfs.newvfs.persistent; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.ManagingFS; @@ -122,8 +123,10 @@ public class RefreshWorker { else { long currentTimestamp = persistence.getTimeStamp(file); long upToDateTimestamp = delegate.getTimeStamp(file); + long currentLength = SystemInfo.isUnix ? persistence.getLength(file) : -1; + long upToDateLength = SystemInfo.isUnix ? delegate.getLength(file) : -1; - if (currentTimestamp != upToDateTimestamp) { + if (currentTimestamp != upToDateTimestamp || currentLength != upToDateLength) { scheduleUpdateContent(file); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 2967be12aeee..d96b8b17f2b8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -39,6 +39,7 @@ import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupFactory; @@ -2186,6 +2187,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements if (root != null) { JComponent toFocus = IdeFocusTraversalPolicy.getPreferredFocusedComponent(root); if (toFocus != null) { + if (DialogWrapper.findInstance(toFocus) != null) { + return new ActionCallback.Done(); //IDEA-80929 + } return IdeFocusManager.findInstanceByComponent(toFocus).requestFocus(toFocus, forced); } } diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 82b6261c6940..a2613b7af5c5 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -3,7 +3,6 @@ error.malformed.url=Malformed url: {0} error.cannot.start.browser=Cannot start browser: {0} error.please.specify.path.to.web.browser=Please specify a path to web browser in File | Settings | Web Browsers title.browser.not.found=Browser Not Found -error.please.open.url.manually=Please open URL ({0}) manually. {1} can''t open it in browser title.browser.path.not.found=Browser Path Not Found action.sort.alphabetically=Sort Alphabetically button.finish=&Finish diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 2d36ef88f549..0b87b66a01b1 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -443,7 +443,6 @@ - @@ -653,7 +652,7 @@ - + @@ -698,7 +697,6 @@ serviceImplementation="com.intellij.openapi.vcs.impl.CodeSmellDetectorImpl"/> - diff --git a/plugins/IntelliLang/java-support/resources/javaInjections.xml b/plugins/IntelliLang/java-support/resources/javaInjections.xml index f685f36e0415..2c49267f9269 100644 --- a/plugins/IntelliLang/java-support/resources/javaInjections.xml +++ b/plugins/IntelliLang/java-support/resources/javaInjections.xml @@ -102,10 +102,12 @@ Session.createQuery (org.hibernate) + Session.createSQLQuery (org.hibernate) + diff --git a/plugins/android/rt/android-rt.iml b/plugins/android/rt/android-rt.iml index 13bee7b61859..59171f56fad5 100644 --- a/plugins/android/rt/android-rt.iml +++ b/plugins/android/rt/android-rt.iml @@ -10,7 +10,7 @@ - + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 0b133fffb90b..56b61fa3179e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -45,6 +45,7 @@ import com.intellij.util.PairConsumer; import com.intellij.util.ProcessingContext; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; @@ -64,18 +65,18 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatem import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.CompleteReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator; import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil; import org.jetbrains.plugins.groovy.refactoring.inline.InlineMethodConflictSolver; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.intellij.patterns.PlatformPatterns.psiElement; import static com.intellij.patterns.PsiJavaPatterns.elementType; +import static com.intellij.util.containers.CollectionFactory.arrayList; import static com.intellij.util.containers.CollectionFactory.hashMap; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.SEPARATORS; @@ -176,18 +177,20 @@ public class GroovyCompletionContributor extends CompletionContributor { private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) { - addAllClasses(parameters, result, new Consumer() { + addAllClasses(parameters, new Consumer() { @Override public void consume(LookupElement element) { result.addElement(element); } - }, inheritors); + }, inheritors, result.getPrefixMatcher()); } - public static void addAllClasses(CompletionParameters parameters, CompletionResultSet result, final Consumer consumer, final InheritorsHolder inheritors) { + public static void addAllClasses(CompletionParameters parameters, + final Consumer consumer, + final InheritorsHolder inheritors, final PrefixMatcher matcher) { final PsiElement position = parameters.getPosition(); final ElementFilter filter = getClassFilter(position); - AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), parameters.getInvocationCount() <= 1, + AllClassesGetter.processJavaClasses(parameters, matcher, parameters.getInvocationCount() <= 1, new Consumer() { @Override public void consume(PsiClass psiClass) { @@ -310,21 +313,21 @@ public class GroovyCompletionContributor extends CompletionContributor { addUnfinishedMethodTypeParameters(position, result); - final PsiElement parent = position.getParent(); - GrReferenceElement reference; - if (parent instanceof GrReferenceElement) { - reference = (GrReferenceElement)parent; - if (reference.getParent() instanceof GrImportStatement && reference.getQualifier() != null) { - result.addElement(LookupElementBuilder.create("*")); - } - } else if (couldContainReference(position)) { - reference = GroovyPsiElementFactory.getInstance(position.getProject()).createReferenceElementFromText("Foo", position); - } else { + GrReferenceElement reference = findGroovyReference(position); + if (reference == null) { return; } + if (reference.getParent() instanceof GrImportStatement && reference.getQualifier() != null) { + result.addElement(LookupElementBuilder.create("*")); + } + InheritorsHolder inheritors = new InheritorsHolder(position, result); - completeReference(parameters, result, reference, inheritors); + if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) { + GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritors); + } + + result.addAllElements(completeReference(parameters, reference, inheritors, result.getPrefixMatcher())); if (reference.getQualifier() == null) { GroovySmartCompletionContributor.addExpectedClassMembers(parameters, result); @@ -361,6 +364,17 @@ public class GroovyCompletionContributor extends CompletionContributor { } + @Nullable private static GrReferenceElement findGroovyReference(PsiElement position) { + final PsiElement parent = position.getParent(); + if (parent instanceof GrReferenceElement) { + return (GrReferenceElement)parent; + } + if (couldContainReference(position)) { + return GroovyPsiElementFactory.getInstance(position.getProject()).createReferenceElementFromText("Foo", position); + } + return null; + } + private static boolean couldContainReference(PsiElement position) { return IN_CATCH_TYPE.accepts(position) || AFTER_AT.accepts(position) || @@ -408,31 +422,31 @@ public class GroovyCompletionContributor extends CompletionContributor { super.fillCompletionVariants(parameters, result); } - private static void completeReference(final CompletionParameters parameters, - final CompletionResultSet result, - GrReferenceElement reference, final InheritorsHolder inheritorsHolder) { + static LinkedHashSet completeReference(final CompletionParameters parameters, + GrReferenceElement reference, final InheritorsHolder inheritorsHolder, final PrefixMatcher matcher) { final PsiElement position = parameters.getPosition(); - if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) { - GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritorsHolder); - } - - final int invocationCount = parameters.getInvocationCount(); - final boolean firstCompletionInvoked = invocationCount < 2; - - final String prefix = result.getPrefixMatcher().getPrefix(); - final boolean skipAccessors = firstCompletionInvoked && !prefix.startsWith("g") && !prefix.startsWith("s") && !prefix.startsWith("i"); - result.restartCompletionOnPrefixChange("g"); - result.restartCompletionOnPrefixChange("i"); - result.restartCompletionOnPrefixChange("s"); - final Map staticMembers = hashMap(); final PsiElement qualifier = reference.getQualifier(); final PsiType qualifierType = qualifier instanceof GrExpression ? ((GrExpression)qualifier).getType() : null; + LinkedHashSet result = new LinkedHashSet(); + if (reference instanceof GrReferenceExpression && (qualifier instanceof GrExpression || qualifier == null)) { + for (String string : CompleteReferenceExpression.getVariantsWithSameQualifier(matcher, (GrExpression)qualifier, (GrReferenceExpression)reference)) { + result.add(GroovyCompletionUtil.getLookupElement(string)); + } + if (parameters.getInvocationCount() < 2 && qualifier != null && qualifierType == null) { + if (parameters.getInvocationCount() == 1) { + showInfo(); + } + return result; + } + } + final ElementFilter classFilter = getClassFilter(position); - reference.processVariants(result.getPrefixMatcher(), parameters, new Consumer() { + final List items = arrayList(); + reference.processVariants(matcher, parameters, new Consumer() { public void consume(Object element) { if (element instanceof PsiClass && inheritorsHolder.alreadyProcessed((PsiClass)element)) { return; @@ -445,15 +459,11 @@ public class GroovyCompletionContributor extends CompletionContributor { element = ((LookupElement)element).getObject(); } - final LookupElement lookupElement = element instanceof PsiClass - ? GroovyCompletionUtil.createClassLookupItem(CompletionUtil.getOriginalOrSelf((PsiClass)element)) - : GroovyCompletionUtil.getLookupElement(element); + LookupElement lookupElement = element instanceof PsiClass + ? GroovyCompletionUtil.createClassLookupItem(CompletionUtil.getOriginalOrSelf((PsiClass)element)) + : GroovyCompletionUtil.getLookupElement(element); Object object = lookupElement.getObject(); - PsiSubstitutor substitutor = null; - GroovyResolveResult resolveResult = null; if (object instanceof GroovyResolveResult) { - resolveResult = (GroovyResolveResult)object; - substitutor = resolveResult.getSubstitutor(); object = ((GroovyResolveResult)object).getElement(); } @@ -461,44 +471,9 @@ public class GroovyCompletionContributor extends CompletionContributor { return; } - final boolean autopopup = parameters.getInvocationCount() == 0; - //skip default groovy methods - if (firstCompletionInvoked && - object instanceof GrGdkMethod && - GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor, qualifierType)) { - if (!autopopup) { - showInfo(); - } - return; - } - - //skip operator methods - if (firstCompletionInvoked && - object instanceof PsiMethod && - GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName())) { - if (!checkForIterator((PsiMethod)object)) { - if (!autopopup) { - showInfo(); - } - return; - } - } - - //skip accessors if there is no get, set, is prefix - if (skipAccessors && object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) { - if (!autopopup) { - showInfo(); - } - return; - } - - //skip inaccessible elements - if (firstCompletionInvoked && resolveResult != null && !resolveResult.isAccessible()) { - if (!autopopup) { - showInfo(); - } - return; - } + int priority = assignPriority(lookupElement, qualifierType); + lookupElement = JavaCompletionUtil.highlightIfNeeded(qualifierType, + PrioritizedLookupElement.withPriority(lookupElement, priority), object); if ((object instanceof PsiMethod || object instanceof PsiField) && ((PsiModifierListOwner)object).hasModifierProperty(PsiModifier.STATIC)) { @@ -510,7 +485,8 @@ public class GroovyCompletionContributor extends CompletionContributor { if (object instanceof PsiClass && !classFilter.isAcceptable(object, position)) { return; } - result.addElement(JavaCompletionUtil.highlightIfNeeded(qualifierType, lookupElement, object)); + + items.add(lookupElement); } }); @@ -522,7 +498,7 @@ public class GroovyCompletionContributor extends CompletionContributor { member = ((GrAccessorMethod)member).getProperty(); } final String name = member.getName(); - if (name == null || !result.getPrefixMatcher().prefixMatches(name)) { + if (name == null || !matcher.prefixMatches(name)) { staticMembers.remove(member); return; } @@ -532,7 +508,26 @@ public class GroovyCompletionContributor extends CompletionContributor { }); } - result.addAllElements(staticMembers.values()); + items.addAll(staticMembers.values()); + + for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { + LookupElement element = iterator.next(); + PrioritizedLookupElement prio = element.as(PrioritizedLookupElement.CLASS_CONDITION_KEY); + if (prio == null || prio.getPriority() >= 0) { + result.add(element); + iterator.remove(); + } + } + result.addAll(items); + + return result; + } + + private static void showInfo() { + if (StringUtil.isEmpty(CompletionService.getCompletionService().getAdvertisementText())) { + CompletionService.getCompletionService() + .setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods")); + } } private static boolean checkForIterator(PsiMethod method) { @@ -545,11 +540,39 @@ public class GroovyCompletionContributor extends CompletionContributor { return InheritanceUtil.isInheritorOrSelf(containingClass, iterator, true); } - private static void showInfo() { - if (StringUtil.isEmpty(CompletionService.getCompletionService().getAdvertisementText())) { - CompletionService.getCompletionService() - .setAdvertisementText(GroovyBundle.message("invoke.completion.second.time.to.show.skipped.methods")); + + private static int assignPriority(LookupElement lookupElement, PsiType qualifierType) { + Object object = lookupElement.getObject(); + PsiSubstitutor substitutor = null; + GroovyResolveResult resolveResult = null; + if (object instanceof GroovyResolveResult) { + resolveResult = (GroovyResolveResult)object; + substitutor = resolveResult.getSubstitutor(); + object = ((GroovyResolveResult)object).getElement(); } + + // default groovy methods + if (object instanceof GrGdkMethod && + GroovyCompletionUtil.skipDefGroovyMethod((GrGdkMethod)object, substitutor, qualifierType)) { + return -1; + } + + // operator methods + if (object instanceof PsiMethod && + GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(((PsiMethod)object).getName()) && !checkForIterator((PsiMethod)object)) { + return -3; + } + + // accessors if there is no get, set, is prefix + if (object instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyAccessor((PsiMethod)object)) { + return -1; + } + + // inaccessible elements + if (resolveResult != null && !resolveResult.isAccessible()) { + return -2; + } + return 0; } static StaticMemberProcessor completeStaticMembers(CompletionParameters parameters) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java index 957e080bd9f0..55a8f20a93e5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java @@ -16,9 +16,21 @@ package org.jetbrains.plugins.groovy.lang.completion; import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiType; import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; /** * @author peter @@ -27,27 +39,114 @@ public class GroovyNoVariantsDelegator extends NoVariantsDelegator { @Override protected void delegate(CompletionParameters parameters, CompletionResultSet result, Consumer passResult) { - if (parameters.getCompletionType() == CompletionType.BASIC && - parameters.getInvocationCount() <= 1 && - JavaCompletionContributor.mayStartClassName(result, false) && - GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) && - !MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) { - final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); - - GroovyCompletionContributor.addAllClasses(parameters, result, - new Consumer() { - @Override - public void consume(LookupElement element) { - JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); - if (classElement != null) { - classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); - } - merger.consume(classElement); - } - }, new InheritorsHolder(parameters.getPosition(), result)); - - merger.finishedClassProcessing(); + if (parameters.getCompletionType() == CompletionType.BASIC) { + if (parameters.getInvocationCount() <= 1 && + JavaCompletionContributor.mayStartClassName(result, false) && + GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) && + !MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) { + suggestNonImportedClasses(parameters, result); + } + suggestChainedCalls(parameters, result); } } + + private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) { + final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result); + + GroovyCompletionContributor.addAllClasses(parameters, new Consumer() { + @Override + public void consume(LookupElement element) { + JavaPsiClassReferenceElement classElement = + element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); + if (classElement != null) { + classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); + } + merger.consume(classElement); + } + }, new InheritorsHolder(parameters.getPosition(), result), result.getPrefixMatcher()); + + merger.finishedClassProcessing(); + } + + private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + PsiElement parent = position.getParent(); + if (!(parent instanceof GrReferenceElement)) { + return; + } + PsiElement qualifier = ((GrReferenceElement)parent).getQualifier(); + if (!(qualifier instanceof GrReferenceElement) || + ((GrReferenceElement)qualifier).getQualifier() != null || + ((GrReferenceElement)qualifier).resolve() != null) { + return; + } + + String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset()); + final CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix); + InheritorsHolder inheritors = new InheritorsHolder(position, result); + for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, inheritors)) { + final PsiType type = JavaCompletionUtil.getLookupElementType(base); + if (type != null && !PsiType.VOID.equals(type)) { + GrReferenceElement ref = createMockReference(position, type, base); + PsiElement refName = ref.getReferenceNameElement(); + assert refName != null; + for (LookupElement element : GroovyCompletionContributor.completeReference( + parameters.withPosition(refName, refName.getTextRange().getStartOffset()), ref, inheritors, result.getPrefixMatcher())) { + qualifiedCollector.addElement(new JavaChainLookupElement(base, element) { + @Override + protected boolean shouldParenthesizeQualifier(PsiFile file, int startOffset, int endOffset) { + return false; + } + }); + } + } + } + } + + private static GrReferenceElement createMockReference(final PsiElement place, @NotNull PsiType qualifierType, LookupElement qualifierItem) { + GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(place.getProject()); + if (qualifierItem.getObject() instanceof PsiClass) { + return factory + .createReferenceExpressionFromText(((PsiClass)qualifierItem.getObject()).getQualifiedName() + ".xxx", place); + } + + return factory.createReferenceExpressionFromText("xxx.xxx", + ReferenceExpressionCompletionContributor + .createContextWithXxxVariable(place, qualifierType)); + } + + + private static Set suggestQualifierItems(CompletionParameters _parameters, + GrReferenceElement qualifier, + InheritorsHolder inheritors) { + CompletionParameters parameters = + _parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset()); + String referenceName = qualifier.getReferenceName(); + if (referenceName == null) { + return Collections.emptySet(); + } + + final PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName); + final Set variants = new LinkedHashSet(); + for (LookupElement element : GroovyCompletionContributor.completeReference(parameters, qualifier, inheritors, qMatcher)) { + if (qMatcher.prefixMatches(element)) { + variants.add(element); + } + } + + if (variants.isEmpty()) { + GroovyCompletionContributor.addAllClasses(parameters, new Consumer() { + @Override + public void consume(LookupElement element) { + if (qMatcher.prefixMatches(element)) { + variants.add(element); + } + } + }, inheritors, qMatcher); + } + return variants; + } + + } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 54bdbe6af25b..2c4a6af49cfb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -25,7 +25,6 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; @@ -48,7 +47,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrRe import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; -import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; @@ -88,7 +86,6 @@ public class CompleteReferenceExpression { private static void getVariantsImpl(PrefixMatcher matcher, GrReferenceExpression refExpr, CompleteReferenceProcessor processor) { GrExpression qualifier = refExpr.getQualifierExpression(); - getVariantsWithSameQualifier(matcher, qualifier, refExpr, processor); if (qualifier == null) { ResolveUtil.treeWalkUp(refExpr, processor, true); @@ -228,7 +225,8 @@ public class CompleteReferenceExpression { return; } } - getVariantsFromQualifierType(refExpr, processor, GrClassImplUtil.getGroovyObjectType(refExpr), project); + getVariantsFromQualifierType(refExpr, processor, + PsiType.getJavaLangObject(refExpr.getManager(), qualifier.getResolveScope()), project); } else if (qualifierType instanceof PsiIntersectionType) { for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) { @@ -256,20 +254,19 @@ public class CompleteReferenceExpression { } } - private static String[] getVariantsWithSameQualifier(PrefixMatcher matcher,GrExpression qualifier, GrReferenceExpression refExpr, CompleteReferenceProcessor processor) { - if (qualifier != null && qualifier.getType() != null) return ArrayUtil.EMPTY_STRING_ARRAY; + public static Set getVariantsWithSameQualifier(PrefixMatcher matcher, @Nullable GrExpression qualifier, GrReferenceExpression refExpr) { + if (qualifier != null && qualifier.getType() != null) return Collections.emptySet(); final PsiElement scope = PsiTreeUtil.getParentOfType(refExpr, GrMember.class, PsiFile.class); Set result = new LinkedHashSet(); - addVariantsWithSameQualifier(matcher, scope, refExpr, qualifier, result, processor); - return ArrayUtil.toStringArray(result); + addVariantsWithSameQualifier(matcher, scope, refExpr, qualifier, result); + return result; } private static void addVariantsWithSameQualifier(PrefixMatcher matcher, PsiElement element, GrReferenceExpression patternExpression, GrExpression patternQualifier, - Set result, - CompleteReferenceProcessor processor) { + Set result) { if (element instanceof GrReferenceExpression && element != patternExpression && !PsiUtil.isLValue((GroovyPsiElement)element)) { final GrReferenceExpression refExpr = (GrReferenceExpression)element; final String refName = refExpr.getReferenceName(); @@ -279,21 +276,19 @@ public class CompleteReferenceExpression { if (PsiEquivalenceUtil.areElementsEquivalent(hisQualifier, patternQualifier)) { if (refExpr.resolve() == null) { result.add(refName); - processor.consume(refName); } } } else if (hisQualifier == null && patternQualifier == null) { if (refExpr.resolve() == null) { result.add(refName); - processor.consume(refName); } } } } for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) { - addVariantsWithSameQualifier(matcher, child, patternExpression, patternQualifier, result, processor); + addVariantsWithSameQualifier(matcher, child, patternExpression, patternQualifier, result); } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy index fbdb4e312da7..1c6f897345d6 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GrCompletionWithLibraryTest.groovy @@ -170,7 +170,67 @@ toString wait wait wait -with\ +with +getThisProp +setThisProp +getSuperProp +setSuperProp +addShutdownHook +any +any +asBoolean +asType +collect +collect +dump +each +eachWithIndex +every +every +find +findAll +findIndexOf +findIndexOf +findIndexValues +findIndexValues +findLastIndexOf +findLastIndexOf +getAt +getClass +getMetaClass +getMetaPropertyValues +getProperties +grep +hasPerInstanceMetaClass +hasProperty +identity +inject +inspect +is +isCase +iterator +metaClass +primitiveArrayGet +primitiveArrayGet +primitiveArrayGet +primitiveArrayPut +print +print +printf +printf +println +println +println +putAt +respondsTo +respondsTo +setMetaClass +split +sprintf +sprintf +use +use +use\ """.split('\n') } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy index 5cb4306414a9..e47e50a569e7 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy @@ -56,7 +56,7 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase { public void testNoLookupFocusOnUnresolvedQualifier() { myFixture.configureByText("a.groovy", """xxx.""") type 'h' //hashCode - assert !lookup.focused + assert !lookup } public void testNoLookupFocusOnUntypedQualifier() { @@ -65,7 +65,7 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase { xxx. }""") type 'h' - assert !lookup.focused + assert !lookup } public void testPossibleClosureParameter() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 94794bebd83b..fe133175c2fb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -891,16 +891,6 @@ class B extends A { checkCompletion "assex", ' ', 'assert x' } - public void testDontShowAccessors() { - assertNull doContainsTest("getFoo", """ -class MyClass { - def foo -} - -def a = new MyClass() -a.""") - } - public void testPreferInstanceof() { caseSensitiveNone() @@ -1072,7 +1062,7 @@ class X { } public void testSortOrder0() { - doVariantableTest 'se', 'setMetaClass', 'setProperty', 'setSe' + doVariantableTest 'se', 'setProperty', 'setMetaClass', 'setSe' } public void testPrimitiveCastOverwrite() { @@ -1118,9 +1108,29 @@ public class KeyVO { checkSingleItemCompletion 'class Foo impl {}', 'class Foo implements {}' } + public void testAmbiguousClassQualifier() { + myFixture.addClass("package foo; public class Util { public static void foo() {} }") + myFixture.addClass("package bar; public class Util { public static void bar() {} }") + myFixture.configureByText 'a.groovy', 'Util.' + myFixture.completeBasic() + assert myFixture.lookupElementStrings[0..1] == ['Util.bar', 'Util.foo'] + + def presentation = LookupElementPresentation.renderElement(myFixture.lookupElements[0]) + assert 'Util.bar' == presentation.itemText + assert '() (bar)' == presentation.tailText + assert !presentation.tailGrayed + + myFixture.type 'f\n' + myFixture.checkResult '''import foo.Util + +Util.foo()''' + } + public void testPreferInterfacesInImplements() { myFixture.addClass('interface FooIntf {}') myFixture.addClass('class FooClass {}') doVariantableTest('FooIntf', 'FooClass') } + + public void testPropertyChain() { doBasicTest() } } \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyTransformationsTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyTransformationsTest.groovy index a46a38e51faa..0228220fa5ea 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyTransformationsTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyTransformationsTest.groovy @@ -50,7 +50,7 @@ class GroovyTransformationsTest extends LightCodeInsightFixtureTestCase { public void testVetoableTransform() throws Throwable { doPlainTest() } - public void testNewifyTransform1() throws Throwable { doVariantsTest('newInstance', 'new', 'new', 'newInstance') } + public void testNewifyTransform1() throws Throwable { doVariantsTest('newInstance', 'new', 'new', 'newInstance', 'negative', 'next') } public void testNewifyTransform2() throws Throwable { doVariantsTest('Leaf', 'Leaf', 'Leaf') } diff --git a/plugins/groovy/testdata/groovy/completion/PropertyChain.groovy b/plugins/groovy/testdata/groovy/completion/PropertyChain.groovy new file mode 100644 index 000000000000..cc24bcc939bc --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/PropertyChain.groovy @@ -0,0 +1,8 @@ +class A { + File myFile; + + def foo() { + myf.cap + } + +} \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/completion/PropertyChain_after.groovy b/plugins/groovy/testdata/groovy/completion/PropertyChain_after.groovy new file mode 100644 index 000000000000..84c0be7c409a --- /dev/null +++ b/plugins/groovy/testdata/groovy/completion/PropertyChain_after.groovy @@ -0,0 +1,8 @@ +class A { + File myFile; + + def foo() { + myFile.canonicalPath + } + +} \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/oldCompletion/reference/tupleObjCompl.test b/plugins/groovy/testdata/groovy/oldCompletion/reference/tupleObjCompl.test index dc46468034b5..3da80cb6eb56 100644 --- a/plugins/groovy/testdata/groovy/oldCompletion/reference/tupleObjCompl.test +++ b/plugins/groovy/testdata/groovy/oldCompletion/reference/tupleObjCompl.test @@ -1,4 +1,3 @@ def (street, home, postCode) def s = street.toS ------ -toString \ No newline at end of file +----- \ No newline at end of file diff --git a/plugins/groovy/testdata/groovy/oldCompletion/reference/untyped.test b/plugins/groovy/testdata/groovy/oldCompletion/reference/untyped.test index 62a56f8f57b3..369b6e64961c 100644 --- a/plugins/groovy/testdata/groovy/oldCompletion/reference/untyped.test +++ b/plugins/groovy/testdata/groovy/oldCompletion/reference/untyped.test @@ -1,3 +1,2 @@ unknown.metaCl ------ -metaClass \ No newline at end of file +----- \ No newline at end of file diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltVariableContext.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltVariableContext.java index 120fd516d802..ff860ddc2e87 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltVariableContext.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltVariableContext.java @@ -61,6 +61,7 @@ public class XsltVariableContext implements VariableContext { final VariantsProcessor processor = new VariantsProcessor(context); ResolveUtil.treeWalkUp(processor, context); + processForwardGlobals(context, processor); return processor.getResult(); } @@ -75,19 +76,32 @@ public class XsltVariableContext implements VariableContext { final ResolveProcessor processor = new ResolveProcessor(reference.getReferencedName(), context); final XPathVariable variable = (XPathVariable)ResolveUtil.treeWalkUp(processor, context); - if (variable == null) { - final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class, true); - if (file != null) { - XsltIncludeIndex.processBackwardDependencies(file, new Processor() { - public boolean process(XmlFile xmlFile) { - processor.processExternalFile(xmlFile, context); - return processor.shouldContinue(); - } - }); - return (XPathVariable)processor.getResult(); - } + if (variable != null) { + return variable; } - return variable; + if (!processForwardGlobals(context, processor)) { + final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class, true); + if (file != null) { + XsltIncludeIndex.processBackwardDependencies(file, new Processor() { + public boolean process(XmlFile xmlFile) { + processor.processExternalFile(xmlFile, context); + return processor.shouldContinue(); + } + }); + } + } + return (XPathVariable)processor.getResult(); + } + + private static boolean processForwardGlobals(XmlTag context, VariableProcessor processor) { + while (context != null && !XsltSupport.isTopLevelElement(context)) { + context = context.getParentTag(); + } + while (context != null && processor.shouldContinue()) { + processor.process(context); + context = PsiTreeUtil.getNextSiblingOfType(context, XmlTag.class); + } + return !processor.shouldContinue(); } @Nullable @@ -141,6 +155,8 @@ public class XsltVariableContext implements VariableContext { processVarOrParamImpl(tag); } } + + protected abstract boolean shouldContinue(); } static class VariantsProcessor extends VariableProcessor { diff --git a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java index e0234af216c8..08f6041879b4 100644 --- a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java +++ b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java @@ -40,6 +40,10 @@ public class XsltResolveTest extends TestBase { doVariableResolveTest(true); } + public void testResolveForwardVariable() throws Throwable { + doVariableResolveTest(true); + } + public void testResolveSingleVariable() throws Throwable { doVariableResolveTest(false); } diff --git a/plugins/xpath/xpath-lang/testData/xslt/resolve/resolveForwardVariable.xsl b/plugins/xpath/xpath-lang/testData/xslt/resolve/resolveForwardVariable.xsl new file mode 100644 index 000000000000..2ccc54fdc968 --- /dev/null +++ b/plugins/xpath/xpath-lang/testData/xslt/resolve/resolveForwardVariable.xsl @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 472fdda42908..bdef3c17b07e 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -213,10 +213,12 @@ + + order="before javaMemberName, before javaLegacy, after liveTemplates"/> + order="after xml"/> + + diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java index fdb43c9d78a3..95f0884d0f54 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java +++ b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ public class BrowsersConfiguration implements PersistentStateComponent return new FirefoxSettings(); } }, - CHROME(XmlBundle.message("browsers.chrome"), getWindowsPathToChrome(), "google-chrome", null, IconLoader.getIcon("/xml/browsers/chrome16.png")) { + CHROME(XmlBundle.message("browsers.chrome"), getWindowsPathToChrome(), "google-chrome", "Google Chrome", IconLoader.getIcon("/xml/browsers/chrome16.png")) { @Override public BrowserSpecificSettings createBrowserSpecificSettings() { return new ChromeSettings();