diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java index 067509811f73..11fbe73d9ed0 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java @@ -26,7 +26,7 @@ public interface CompilationStatusListener extends EventListener { /** * Invoked in a Swing dispatch thread after the compilation is finished. * - * @param aborted true if compilatioin has been cancelled + * @param aborted true if compilation has been cancelled * @param errors error count * @param warnings warning count * @param compileContext context for the finished compilation diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleConfigurable.java index 8c90e730598d..d49e9be5576a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleConfigurable.java @@ -99,7 +99,7 @@ public class ModuleConfigurable extends ProjectStructureElementConfigurable() { @Override public void handleInsert(InsertionContext context, LookupElement item) { + if (context.getCompletionChar() != Lookup.REPLACE_SELECT_CHAR) return; + context.commitDocument(); PsiDocTag docTag = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiDocTag.class, false); if (docTag != null) { - int tagEnd = docTag.getTextRange().getEndOffset(); + Document document = context.getDocument(); + int tagEnd = DocTagSelectioner.getDocTagRange(docTag, document.getCharsSequence(), 0).getEndOffset(); int tail = context.getTailOffset(); if (tail < tagEnd) { - context.getDocument().deleteString(tail, tagEnd); + document.deleteString(tail, tagEnd); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java index c64d304249cb..d706a2d60ab0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/DocTagSelectioner.java @@ -36,7 +36,11 @@ public class DocTagSelectioner extends WordSelectioner { @Override public List select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) { List result = super.select(e, editorText, cursorOffset, editor); + result.add(getDocTagRange((PsiDocTag)e, editorText, cursorOffset)); + return result; + } + public static TextRange getDocTagRange(PsiDocTag e, CharSequence documentText, int minOffset) { TextRange range = e.getTextRange(); int endOffset = range.getEndOffset(); @@ -49,7 +53,7 @@ public class DocTagSelectioner extends WordSelectioner { int childStartOffset = child.getTextRange().getStartOffset(); - if (childStartOffset <= cursorOffset) { + if (childStartOffset <= minOffset) { break; } @@ -71,10 +75,8 @@ public class DocTagSelectioner extends WordSelectioner { endOffset = Math.min(childStartOffset, endOffset); } - startOffset = CharArrayUtil.shiftBackward(editorText, startOffset - 1, "* \t") + 1; + startOffset = CharArrayUtil.shiftBackward(documentText, startOffset - 1, "* \t") + 1; - result.add(new TextRange(startOffset, endOffset)); - - return result; + return new TextRange(startOffset, endOffset); } } diff --git a/java/java-impl/src/com/intellij/lang/java/JavaLiteralEscaper.java b/java/java-impl/src/com/intellij/lang/java/JavaLiteralEscaper.java deleted file mode 100644 index 4d3712d6ae08..000000000000 --- a/java/java-impl/src/com/intellij/lang/java/JavaLiteralEscaper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.lang.java; - -import com.intellij.lang.LiteralEscaper; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiJavaToken; -import com.intellij.psi.JavaTokenType; -import com.intellij.openapi.util.text.StringUtil; - -/** - * @author yole - */ -public class JavaLiteralEscaper implements LiteralEscaper { - @Override - public String getEscapedText(final PsiElement context, final String originalText) { - if (context instanceof PsiJavaToken && ((PsiJavaToken)context).getTokenType() == JavaTokenType.STRING_LITERAL) { - return StringUtil.escapeStringCharacters(originalText); - } - return originalText; - } - - @Override - public String escapeText(String originalText) { - return StringUtil.escapeStringCharacters(originalText); - } - - @Override - public String unescapeText(String originalText) { - return StringUtil.unescapeStringCharacters(originalText); - } -} diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index f6637fde49e1..ff3543a37f16 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -120,7 +120,7 @@ public class GenericsUtil { PsiType mapping2 = subst2.substitute(parameter); if (mapping1 != null && mapping2 != null) { - substitutor = substitutor.put(parameter, getLeastContainingTypeArgument(mapping1, mapping2, compared, manager)); + substitutor = substitutor.put(parameter, getLeastContainingTypeArgument(mapping1, mapping2, compared, manager, type1.equals(mapping1) && type2.equals(mapping2) ? aSuper : null, parameter)); } else { substitutor = substitutor.put(parameter, null); @@ -150,9 +150,23 @@ public class GenericsUtil { private static PsiType getLeastContainingTypeArgument(PsiType type1, PsiType type2, Set> compared, - PsiManager manager) { + PsiManager manager, + PsiClass nestedLayer, + PsiTypeParameter parameter) { Pair types = new Pair(type1, type2); - if (compared.contains(types)) return PsiWildcardType.createUnbounded(manager); + if (compared.contains(types)) { + if (nestedLayer != null) { + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + for (PsiTypeParameter param : PsiUtil.typeParametersIterable(nestedLayer)) { + subst = subst.put(param, PsiWildcardType.createUnbounded(manager)); + } + subst = subst.put(parameter, getLeastContainingTypeArgument(type1, type2, compared, manager, null, null)); + + final PsiClassType boundType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(nestedLayer, subst); + return PsiWildcardType.createExtends(manager, boundType); + } + return PsiWildcardType.createUnbounded(manager); + } compared.add(types); try { @@ -180,7 +194,7 @@ public class GenericsUtil { } } else if (type2 instanceof PsiWildcardType) { - return getLeastContainingTypeArgument(type2, type1, compared, manager); + return getLeastContainingTypeArgument(type2, type1, compared, manager, null, null); } //Done with wildcards diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java index fc1d2957c2da..a00e8806eb76 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java @@ -87,7 +87,12 @@ public class LambdaHighlightingUtil { @Nullable public static String checkInterfaceFunctional(PsiType functionalInterfaceType) { - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + if (functionalInterfaceType instanceof PsiIntersectionType) { + for (PsiType type : ((PsiIntersectionType)functionalInterfaceType).getConjuncts()) { + if (checkInterfaceFunctional(type) == null) return null; + } + } + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(functionalInterfaceType)); final PsiClass aClass = resolveResult.getElement(); if (aClass != null) { if (checkReturnTypeApplicable(resolveResult, aClass)) { @@ -95,7 +100,7 @@ public class LambdaHighlightingUtil { } return checkInterfaceFunctional(aClass); } - return null; + return functionalInterfaceType.getPresentableText() + " is not a functional interface"; } private static boolean checkReturnTypeApplicable(PsiClassType.ClassResolveResult resolveResult, final PsiClass aClass) { diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 464299f2ab07..41c4aa51cac1 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -484,23 +484,30 @@ public class LambdaUtil { } } else if (parent instanceof PsiReturnStatement) { - final PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); - if (method != null) { - return method.getReturnType(); + final PsiLambdaExpression gParent = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class); + if (gParent != null) { + return getFunctionalInterfaceTypeByContainingLambda(gParent); + } else { + final PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); + if (method != null) { + return method.getReturnType(); + } } } else if (parent instanceof PsiLambdaExpression) { - final PsiType parentInterfaceType = ((PsiLambdaExpression)parent).getFunctionalInterfaceType(); - if (parentInterfaceType != null) { - return getFunctionalInterfaceReturnType(parentInterfaceType); - } + return getFunctionalInterfaceTypeByContainingLambda((PsiLambdaExpression)parent); } return null; } + private static PsiType getFunctionalInterfaceTypeByContainingLambda(@NotNull PsiLambdaExpression parentLambda) { + final PsiType parentInterfaceType = parentLambda.getFunctionalInterfaceType(); + return parentInterfaceType != null ? getFunctionalInterfaceReturnType(parentInterfaceType) : null; + } + private static int adjustLambdaIdx(int lambdaIdx, PsiMethod resolve, PsiParameter[] parameters) { final int finalLambdaIdx; - if (((PsiMethod)resolve).isVarArgs() && lambdaIdx >= parameters.length) { + if (resolve.isVarArgs() && lambdaIdx >= parameters.length) { finalLambdaIdx = parameters.length - 1; } else { finalLambdaIdx = lambdaIdx; @@ -524,7 +531,6 @@ public class LambdaUtil { final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class); if (lambdaExpression != null) { - final PsiParameterList parameterList = lambdaExpression.getParameterList(); PsiType type = getFunctionalInterfaceType(lambdaExpression, true, parameterIndex); if (type == null) { type = getFunctionalInterfaceType(lambdaExpression, false); diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index fc040080d808..44055a7f08b0 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -541,7 +541,7 @@ public class ExceptionUtil { List result = ContainerUtil.newArrayList(); for (PsiClassType referencedType : referencedTypes) { - final PsiType type = substitutor.substitute(referencedType); + final PsiType type = GenericsUtil.eliminateWildcards(substitutor.substitute(referencedType), false); if (!(type instanceof PsiClassType)) continue; PsiClassType classType = (PsiClassType)type; PsiClass exceptionClass = ((PsiClassType)type).resolve(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 1162f18a00e2..d24bfd9ff654 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -863,7 +863,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { PsiType patternType, final ConstraintType constraintType, final int depth) { - if (arg instanceof PsiCapturedWildcardType) arg = ((PsiCapturedWildcardType)arg).getWildcard(); //reopen + if (arg instanceof PsiCapturedWildcardType && (depth < 2 || constraintType != ConstraintType.EQUALS)) arg = ((PsiCapturedWildcardType)arg).getWildcard(); //reopen if (patternType.equals(param)) { return processArgType(arg, constraintType, depth < 2); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java index 74d1350b3dc7..f6c790a362c9 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java @@ -382,7 +382,8 @@ public class PsiLiteralExpressionImpl @Override @NotNull public PsiReference[] getReferences() { - return PsiReferenceService.getService().getContributedReferences(this); + PsiReference[] references = PsiReferenceService.getService().getContributedReferences(this); + return references; } @Override diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnhandledExceptions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnhandledExceptions.java new file mode 100644 index 000000000000..54eac1eedabe --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting6/UnhandledExceptions.java @@ -0,0 +1,13 @@ +interface I { + void m() throws T; +} + +class C { + void x(I i) { + i.m(); + } + + void y(I i) { + i.m(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57311.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57311.java index 2be9a4f1e4ff..9ed409cfc19f 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57311.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57311.java @@ -4,7 +4,7 @@ class A { } void bar(A x){ - baz(x.foo()); + baz(x.foo()); } void baz(A> x){} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57312.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57312.java new file mode 100644 index 000000000000..70be0d2c31ba --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57312.java @@ -0,0 +1,11 @@ +class A { + A>> foo(){ + return null; + } + + void bar(A x){ + baz(x.foo()); + } + + void baz(A>> x){} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57439.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57439.java new file mode 100644 index 000000000000..544d6c16a605 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57439.java @@ -0,0 +1,43 @@ +class A {} + +class B extends A> { + void bar(B b, B eb, B sb, B s) { + foo(b); + foo(eb); + foo(sb); + foo(s); + + foo1(b); + foo1(eb); + foo1(sb); + foo1(s); + + foo2(b); + foo2(eb); + foo2(sb); + foo2(s); + + foo3(b); + foo3(eb); + foo3(sb); + foo3(s); + + foo4(b); + foo4(eb); + foo4(sb); + foo4(s); + + foo5(b); + foo5(eb); + foo5(sb); + foo5(s); + } + + + void foo(A> x) {} + void foo1(A> x) {} + void foo2(A> x) {} + void foo3(A> x) {} + void foo4(A> x) {} + void foo5(A> x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java index a197bf02df7b..b201ac5aa7ae 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java @@ -8,7 +8,7 @@ class Test { } void foo() { - List> l = this.asList(String.class, Integer.class); + List> l = this.asList(String.class, Integer.class); l.size(); List objects = this.asList(new String(), new Integer(0)); objects.size(); @@ -146,7 +146,7 @@ class IDEADEV25515 { } public static final - List> SIMPLE_TYPES = + List> SIMPLE_TYPES = asList(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/ Boolean.class, Boolean.TYPE /*,String[].class */ /*,BigDecimal.class*/); @@ -179,3 +179,43 @@ public class MaximalType { class M extends MaximalType implements L{} class M2 extends MaximalType implements L{} ///////////// + + +class IDEA67676 { + interface I<T> {} + interface A extends I>{} + interface Com2 { + void foo(T t, U u); + } + interface Com1 { + void foo(T t); + } + + abstract class X { + abstract T foo(T x, T y); + + void bar(A x, A y) { + A, ? extends Com2>> f = foo(x, y); + f.hashCode(); + } + + void boo(A x, A y) { + A, ? extends Com2>> f = foo(x, y); + f.hashCode(); + } + + void baz(A x, A y) { + A>> f = foo(x, y); + f.hashCode(); + } + } + + abstract class A1 implements Com1 {} + abstract class B1 implements Com1 {} + + abstract class A2 implements Com2 {} + abstract class B2 implements Com2 {} + + abstract class A3 implements Com2 {} + abstract class B3 implements Com2 {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/CastInContexts.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/CastInContexts.java index 1f577f8ca40f..b9d5d4b2eb69 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/CastInContexts.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/CastInContexts.java @@ -22,6 +22,6 @@ class CastInContexts { } { - int i = (int) ()-> 1; + int i = (int) ()-> 1; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/FunctionalInterfaceCheck.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/FunctionalInterfaceCheck.java new file mode 100644 index 000000000000..74537d41e2c0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/FunctionalInterfaceCheck.java @@ -0,0 +1,5 @@ +class Demo { + public static void main(String[] args) { + Runnable r = () -> () -> () -> {}; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java index b0656f5c0ecc..7af6276e5d31 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/NoInferenceResult.java @@ -16,7 +16,7 @@ class NoInferenceResult { void test() { m((String s1) -> (String s2) -> s1 + s2); - m((String s1) -> {return (String s2) -> s1 + s2;}); + m((String s1) -> {return (String s2) -> s1 + s2;}); m((String s1) -> s1.length()); m((String s1) -> s1); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java index 39ba57fcdc17..e23d2c71bfcf 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java @@ -48,7 +48,7 @@ class Test2 { } { - X x = () -> 123; + X x = () -> 123; X x1 = () -> 123; } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy index a42fde0fe8ed..fedb91c8dfd6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavadocCompletionTest.groovy @@ -221,6 +221,7 @@ class Foo { class Foo { /** * @param intParam so xxx + * @throws Foo */ void foo2(int intParam, Object param2) { } @@ -234,7 +235,20 @@ class Foo { myFixture.assertPreferredCompletionItems 0, 'some', 'some integer param' myFixture.lookup.currentItem = myFixture.lookupElements[1] myFixture.type('\t') - assert !myFixture.editor.document.text.contains('xxx') + myFixture.checkResult ''' +class Foo { + /** + * @param intParam some integer param + * @throws Foo + */ + void foo2(int intParam, Object param2) { } + + /** + * @param intParam some integer param + */ + void foo(int intParam, Object param2) { } +} +''' } public void "test see super class"() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 3abcc3c5536d..dda5aecf3a81 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -307,6 +307,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA109556() { doTest5(false); } public void testIDEA107440() { doTest5(false); } public void testIDEA57289() { doTest5(false); } + public void testIDEA57439() { doTest5(false); } + public void testIDEA57312() { doTest5(false); } public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java index b7790ae82d0d..4af4e6bcdf27 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk6Test.java @@ -58,4 +58,5 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase { public void testClassObjectAccessibility() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(false, false); } public void testRedundantCastInConditionalExpression() throws Exception { setLanguageLevel(LanguageLevel.JDK_1_6); doTest(true, false); } public void testJava5CastConventions() { setLanguageLevel(LanguageLevel.JDK_1_5); doTest(true, false); } + public void testUnhandledExceptions() { doTest(true, false); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java index d8c404b274a0..10b35d3d6c56 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java @@ -89,6 +89,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testConflictResolution() throws Exception {doTest();} public void testIDEA108195() throws Exception {doTest();} public void testDiamondInference() throws Exception { doTest();} + public void testFunctionalInterfaceCheck() throws Exception { doTest();} private void doTest() { doTest(false); diff --git a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java index 05280434f3d0..bc938beda8ff 100644 --- a/platform/bootstrap/src/com/intellij/ide/Bootstrap.java +++ b/platform/bootstrap/src/com/intellij/ide/Bootstrap.java @@ -35,7 +35,7 @@ public class Bootstrap { } public static void main(String[] args, String mainClass, String methodName, List classpathElements) throws Exception { - UrlClassLoader newClassLoader = ClassloaderUtil.initClassloader(classpathElements); + UrlClassLoader newClassLoader = ClassloaderUtil.initClassloader(classpathElements, args.length == 0); WindowsCommandLineProcessor.ourMirrorClass = Class.forName(WindowsCommandLineProcessor.class.getName(), true, newClassLoader); Class klass = Class.forName(PLUGIN_MANAGER, true, newClassLoader); diff --git a/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java b/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java index 6d6f715d026d..801c459303a3 100644 --- a/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java +++ b/platform/bootstrap/src/com/intellij/ide/ClassloaderUtil.java @@ -49,7 +49,7 @@ public class ClassloaderUtil extends ClassUtilCore { return Logger.getInstance("ClassloaderUtil"); } - public static UrlClassLoader initClassloader(final List classpathElements) throws Exception { + public static UrlClassLoader initClassloader(final List classpathElements, boolean updatePlugins) throws Exception { PathManager.loadProperties(); addParentClasspath(classpathElements); @@ -60,7 +60,7 @@ public class ClassloaderUtil extends ClassUtilCore { UrlClassLoader newClassLoader = new UrlClassLoader(classpathElements, null, true, true); // prepare plugins - if (!isLoadingOfExternalPluginsDisabled()) { + if (updatePlugins && !isLoadingOfExternalPluginsDisabled()) { try { StartupActionScriptManager.executeActionScript(); } diff --git a/platform/bootstrap/src/com/intellij/idea/Main.java b/platform/bootstrap/src/com/intellij/idea/Main.java index 4f52325eed11..4ea58e732286 100644 --- a/platform/bootstrap/src/com/intellij/idea/Main.java +++ b/platform/bootstrap/src/com/intellij/idea/Main.java @@ -59,12 +59,14 @@ public class Main { throw new HeadlessException("Unable to detect graphics environment"); } - try { - installPatch(); - } - catch (Throwable t) { - showMessage("Update Failed", t); - System.exit(UPDATE_FAILED); + if (args.length == 0) { + try { + installPatch(); + } + catch (Throwable t) { + showMessage("Update Failed", t); + System.exit(UPDATE_FAILED); + } } } diff --git a/platform/core-api/src/com/intellij/lang/Language.java b/platform/core-api/src/com/intellij/lang/Language.java index 4c9e7ec9ecfb..c087bd24506a 100644 --- a/platform/core-api/src/com/intellij/lang/Language.java +++ b/platform/core-api/src/com/intellij/lang/Language.java @@ -221,4 +221,11 @@ public abstract class Language extends UserDataHolderBase { } return null; } + + /** Fake language identifier without registering */ + protected Language(String id, @SuppressWarnings("UnusedParameters") boolean register) { + myID = id; + myBaseLanguage = null; + myMimeTypes = null; + } } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java index b2c18c6bd5b9..39016299b6be 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java @@ -405,11 +405,22 @@ public class ExternalSystemApiUtil { @NotNull public static String getProjectRepresentationName(@NotNull String targetProjectPath, @Nullable String rootProjectPath) { if (rootProjectPath == null) { - return new File(targetProjectPath).getParentFile().getName(); + File rootProjectDir = new File(targetProjectPath); + if (rootProjectDir.isFile()) { + rootProjectDir = rootProjectDir.getParentFile(); + } + return rootProjectDir.getName(); + } + File rootProjectDir = new File(rootProjectPath); + if (rootProjectDir.isFile()) { + rootProjectDir = rootProjectDir.getParentFile(); + } + File targetProjectDir = new File(targetProjectPath); + if (targetProjectDir.isFile()) { + targetProjectDir = targetProjectDir.getParentFile(); } - File rootProjectDir = new File(rootProjectPath).getParentFile(); StringBuilder buffer = new StringBuilder(); - for (File f = new File(targetProjectPath).getParentFile(); f != null && !FileUtil.filesEqual(f, rootProjectDir); f = f.getParentFile()) { + for (File f = targetProjectDir; f != null && !FileUtil.filesEqual(f, rootProjectDir); f = f.getParentFile()) { buffer.insert(0, f.getName()).insert(0, ":"); } buffer.insert(0, rootProjectDir.getName()); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java index 266b3bb5d33b..b5091d710cfc 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskSettingsControl.java @@ -117,7 +117,7 @@ public class ExternalSystemTaskSettingsControl implements ExternalSystemSettings String path = myOriginalSettings.getExternalProjectPath(); if (StringUtil.isEmpty(path)) { - path = ExternalSystemApiUtil.getLastUsedExternalProjectPath(myExternalSystemId); + path = ""; } myProjectPathField.setText(path); myTasksTextField.setText(StringUtil.join(myOriginalSettings.getTaskNames(), " ")); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java index 4e8e245f3433..bcf49e497ea0 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectPathField.java @@ -241,6 +241,9 @@ public class ExternalProjectPathField extends ComponentWithBrowseButton { - public static final LanguageLiteralEscapers INSTANCE = new LanguageLiteralEscapers(); - - private LanguageLiteralEscapers() { - super("com.intellij.lang.literalEscaper", new LiteralEscaper() { - @Override - public String getEscapedText(final PsiElement context, final String originalText) { - return originalText; - } - - @Override - public String escapeText(String originalText) { - return originalText; - } - - @Override - public String unescapeText(String originalText) { - return originalText; - } - }); - } -} diff --git a/platform/lang-api/src/com/intellij/lang/LiteralEscaper.java b/platform/lang-api/src/com/intellij/lang/LiteralEscaper.java deleted file mode 100644 index 2108f2cd136a..000000000000 --- a/platform/lang-api/src/com/intellij/lang/LiteralEscaper.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.lang; - -import com.intellij.psi.PsiElement; - -/** - * @author yole - */ -public interface LiteralEscaper { - String getEscapedText(PsiElement context, String originalText); - String escapeText(String originalText); - String unescapeText(String originalText); -} diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/Injectable.java b/platform/lang-api/src/com/intellij/psi/injection/Injectable.java similarity index 74% rename from plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/Injectable.java rename to platform/lang-api/src/com/intellij/psi/injection/Injectable.java index 3cee69134201..717414aaf380 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/Injectable.java +++ b/platform/lang-api/src/com/intellij/psi/injection/Injectable.java @@ -13,20 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.intellij.plugins.intelliLang.references; +package com.intellij.psi.injection; import com.intellij.lang.Language; import com.intellij.openapi.fileTypes.FileType; import com.intellij.util.ui.EmptyIcon; -import org.intellij.plugins.intelliLang.inject.InjectedLanguage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; /** * @author Dmitry Avdeev @@ -41,6 +36,11 @@ public abstract class Injectable implements Comparable { @NotNull public abstract String getDisplayName(); + @Nullable + public String getAdditionalDescription() { + return null; + } + @NotNull public Icon getIcon() { return EmptyIcon.ICON_16; @@ -57,15 +57,13 @@ public abstract class Injectable implements Comparable { @Nullable public abstract Language getLanguage(); - public static List getAllInjectables() { - Language[] languages = InjectedLanguage.getAvailableLanguages(); - List list = new ArrayList(); - for (Language language : languages) { - list.add(fromLanguage(language)); - } - list.addAll(Arrays.asList(ReferenceInjector.EXTENSION_POINT_NAME.getExtensions())); - Collections.sort(list); - return list; + public Language toLanguage() { + return getLanguage() == null ? new Language(getId(), false) { + @Override + public String getDisplayName() { + return Injectable.this.getDisplayName(); + } + } : getLanguage(); } public static Injectable fromLanguage(final Language language) { @@ -79,8 +77,14 @@ public abstract class Injectable implements Comparable { @NotNull @Override public String getDisplayName() { + return language.getDisplayName(); + } + + @Nullable + @Override + public String getAdditionalDescription() { final FileType ft = language.getAssociatedFileType(); - return language.getDisplayName() + (ft != null ? " (" + ft.getDescription() + ")" : ""); + return ft != null ? " (" + ft.getDescription() + ")" : null; } @NotNull diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/ReferenceInjector.java b/platform/lang-api/src/com/intellij/psi/injection/ReferenceInjector.java similarity index 82% rename from plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/ReferenceInjector.java rename to platform/lang-api/src/com/intellij/psi/injection/ReferenceInjector.java index 90397bebbd67..80ad118108d3 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/ReferenceInjector.java +++ b/platform/lang-api/src/com/intellij/psi/injection/ReferenceInjector.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.intellij.plugins.intelliLang.references; +package com.intellij.psi.injection; import com.intellij.lang.Language; import com.intellij.openapi.extensions.ExtensionPointName; @@ -26,18 +26,23 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; /** + * This will work only in presence of IntelliLang plugin. + * * @author Dmitry Avdeev * Date: 01.08.13 */ public abstract class ReferenceInjector extends Injectable { - final static ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("org.intellij.intelliLang.referenceInjector"); + public final static ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.referenceInjector"); @Override public final Language getLanguage() { return null; } + /** + * Generated references should be soft ({@link com.intellij.psi.PsiReference#isSoft()}) + */ @NotNull public abstract PsiReference[] getReferences(@NotNull PsiElement element, @NotNull final ProcessingContext context, @NotNull TextRange range); diff --git a/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java b/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java index f678716132f0..a28983107fa5 100644 --- a/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java +++ b/platform/lang-impl/src/com/intellij/codeEditor/printing/PrintManager.java @@ -15,11 +15,7 @@ */ package com.intellij.codeEditor.printing; -import com.intellij.CommonBundle; import com.intellij.ide.highlighter.HighlighterFactory; -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; -import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -160,8 +156,7 @@ class PrintManager { printerJob.cancel(); } catch (Exception e) { - Notifications.Bus.notify(new Notification("Print", CommonBundle.getErrorTitle(), e.getMessage(), NotificationType.ERROR)); - LOG.warn(e); + LOG.error(e); } } }); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index 682d442e479d..ab4cc84710bb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -341,7 +341,7 @@ class ParameterInfoComponent extends JPanel { myLabel.setForeground(FOREGROUND_COLOR); if (flagsMap.isEmpty()) { - myLabel.setText(XmlStringUtil.wrapInHtml(text)); + myLabel.setText(XmlStringUtil.wrapInHtml(XmlStringUtil.escapeString(text))); } else { String labelText = buildLabelText(text, flagsMap); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index c080c87c5c62..bfb072b71e8d 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -21,6 +21,7 @@ import com.intellij.ide.IdeEventQueue; import com.intellij.ide.SearchTopHitProvider; import com.intellij.ide.ui.LafManager; import com.intellij.ide.ui.LafManagerListener; +import com.intellij.ide.ui.search.BooleanOptionDescription; import com.intellij.ide.ui.search.OptionDescription; import com.intellij.ide.ui.search.SearchableOptionsRegistrarImpl; import com.intellij.ide.util.gotoByName.*; @@ -58,6 +59,7 @@ import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.OnOffButton; import com.intellij.util.Alarm; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; @@ -330,11 +332,19 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component cmp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (myLocationString != null) { + if (myLocationString != null || value instanceof BooleanOptionDescription) { final JPanel panel = new JPanel(new BorderLayout()); - panel.setBackground(UIUtil.getListBackground()); + panel.setBackground(UIUtil.getListBackground(isSelected)); panel.add(cmp, BorderLayout.CENTER); - panel.add(myLocation.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus), BorderLayout.EAST); + final Component rightComponent; + if (value instanceof BooleanOptionDescription) { + final OnOffButton button = new OnOffButton(); + button.setSelected(((BooleanOptionDescription)value).isOptionEnabled()); + rightComponent = button; + } else { + rightComponent = myLocation.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + panel.add(rightComponent, BorderLayout.EAST); cmp = panel; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java index 08948eff23c6..bfdf2914a636 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java @@ -59,7 +59,9 @@ public class MarkRootAction extends DumbAwareAction { public void actionPerformed(AnActionEvent e) { Module module = e.getData(LangDataKeys.MODULE); VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); - assert vFiles != null; + if (module == null || vFiles == null) { + return; + } final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); for (VirtualFile vFile : vFiles) { ContentEntry entry = findContentEntry(model, vFile); diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java index 051d4cb3bcec..bf8c41fce241 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java @@ -138,10 +138,7 @@ public class ScopeViewPane extends AbstractProjectViewPane { @Override @NotNull public String[] getSubIds() { - NamedScope[] scopes = myDependencyValidationManager.getScopes(); - scopes = ArrayUtil.mergeArrays(scopes, myNamedScopeManager.getScopes()); - scopes = NonProjectFilesScope.removeFromList(scopes); - scopes = ArrayUtil.remove(scopes, CustomScopesProviderEx.getAllScope()); + NamedScope[] scopes = getShownScopes(); String[] ids = new String[scopes.length]; for (int i = 0; i < scopes.length; i++) { final NamedScope scope = scopes[i]; @@ -150,6 +147,14 @@ public class ScopeViewPane extends AbstractProjectViewPane { return ids; } + private NamedScope[] getShownScopes() { + NamedScope[] scopes = myDependencyValidationManager.getScopes(); + scopes = ArrayUtil.mergeArrays(scopes, myNamedScopeManager.getScopes()); + scopes = NonProjectFilesScope.removeFromList(scopes); + scopes = ArrayUtil.remove(scopes, CustomScopesProviderEx.getAllScope()); + return scopes; + } + @Override @NotNull public String getPresentableSubIdName(@NotNull final String subId) { @@ -183,15 +188,13 @@ public class ScopeViewPane extends AbstractProjectViewPane { if (psiFile == null) return; if (!(element instanceof PsiElement)) return; - List allScopes = new ArrayList(); - ContainerUtil.addAll(allScopes, myDependencyValidationManager.getScopes()); - ContainerUtil.addAll(allScopes, myNamedScopeManager.getScopes()); - for (int i = 0; i < allScopes.size(); i++) { - final NamedScope scope = allScopes.get(i); + NamedScope[] allScopes = getShownScopes(); + for (int i = 0; i < allScopes.length; i++) { + final NamedScope scope = allScopes[i]; String name = scope.getName(); if (name.equals(getSubId())) { - allScopes.set(i, allScopes.get(0)); - allScopes.set(0, scope); + allScopes[i] = allScopes[0]; + allScopes[0] = scope; break; } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java index 7c525027cf0f..909b44799a02 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java @@ -45,6 +45,7 @@ import com.intellij.util.Query; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; @@ -300,4 +301,9 @@ public abstract class CallerChooserBase extends DialogWrap return myTree; } + @Nullable + @Override + protected String getDimensionServiceKey() { + return "caller.chooser.dialog"; + } } diff --git a/platform/platform-api/src/com/intellij/ide/DataManager.java b/platform/platform-api/src/com/intellij/ide/DataManager.java index 4a0201581a8c..c535abf50392 100644 --- a/platform/platform-api/src/com/intellij/ide/DataManager.java +++ b/platform/platform-api/src/com/intellij/ide/DataManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -17,6 +17,7 @@ package com.intellij.ide; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.AsyncResult; import com.intellij.openapi.util.Key; @@ -29,7 +30,8 @@ import java.awt.*; public abstract class DataManager { public static DataManager getInstance() { - return ApplicationManager.getApplication().getComponent(DataManager.class); + Application application = ApplicationManager.getApplication(); + return application != null ? application.getComponent(DataManager.class) : null; } @NonNls public static final String CLIENT_PROPERTY_DATA_PROVIDER = "DataProvider"; diff --git a/platform/platform-api/src/com/intellij/ide/dnd/DnDManager.java b/platform/platform-api/src/com/intellij/ide/dnd/DnDManager.java index b0ca95badc0d..9fb73e0cae4d 100644 --- a/platform/platform-api/src/com/intellij/ide/dnd/DnDManager.java +++ b/platform/platform-api/src/com/intellij/ide/dnd/DnDManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +24,7 @@ import java.awt.*; public abstract class DnDManager { public static DnDManager getInstance() { Application application = ApplicationManager.getApplication(); - if (application == null) { - return null; - } - return (DnDManager)application.getPicoContainer().getComponentInstance(DnDManager.class.getName()); + return application != null ? (DnDManager)application.getPicoContainer().getComponentInstance(DnDManager.class.getName()) : null; } public abstract void registerSource(DnDSource source, JComponent component); @@ -41,6 +38,6 @@ public abstract class DnDManager { public abstract void registerTarget(DnDTarget target, JComponent component); public abstract void unregisterTarget(DnDTarget target, JComponent component); - + public abstract Component getLastDropHandler(); } diff --git a/platform/platform-api/src/com/intellij/ide/ui/UISimpleSettingsProvider.java b/platform/platform-api/src/com/intellij/ide/ui/UISimpleSettingsProvider.java index 38fe94bb028b..2623a55208a9 100644 --- a/platform/platform-api/src/com/intellij/ide/ui/UISimpleSettingsProvider.java +++ b/platform/platform-api/src/com/intellij/ide/ui/UISimpleSettingsProvider.java @@ -23,10 +23,25 @@ import com.intellij.util.Consumer; */ public class UISimpleSettingsProvider implements SearchTopHitProvider { private static UISettingsOptionDescription CYCLING_SCROLLING = new UISettingsOptionDescription("CYCLING_SCROLLING", "Cyclic scrolling", "appearance"); + private static UISettingsOptionDescription MEMORY_INDICATOR = new UISettingsOptionDescription("SHOW_MEMORY_INDICATOR", "Show Memory Indicator", "appearance"); @Override public void consumeTopHits(String pattern, Consumer collector) { + pattern = pattern.trim().toLowerCase(); + if (pattern.startsWith("cyc") || pattern.startsWith("scr") || patternContains(pattern, "scroll")) { + collector.consume(CYCLING_SCROLLING); + } else if (patternContains(pattern, "memo")) { + collector.consume(MEMORY_INDICATOR); + } + } + private static boolean patternContains(String pattern, String search) { + for (String s : pattern.split(" ")) { + if (s.contains(search)) { + return true; + } + } + return false; } } diff --git a/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java b/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java new file mode 100644 index 000000000000..11dadb6a64e5 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/OnOffButton.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui.components; + +import com.intellij.ui.Gray; +import com.intellij.util.ui.GraphicsUtil; +import com.intellij.util.ui.UIUtil; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicToggleButtonUI; +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public class OnOffButton extends JToggleButton { + private String myOnText; + private String myOffText; + public OnOffButton() { + setUI(OnOffButtonUI.createUI(this)); + setOpaque(false); + setBorder(null); + } + + public String getOnText() { + return myOnText == null ? "ON" : myOnText; + } + + public void setOnText(String onText) { + myOnText = onText; + } + + public String getOffText() { + return myOffText == null ? "OFF" : myOffText; + } + + public void setOffText(String offText) { + myOffText = offText; + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + } + + public static class OnOffButtonUI extends BasicToggleButtonUI { + private final OnOffButton myButton; + + public OnOffButtonUI(OnOffButton checkBox) { + myButton = checkBox; + } + + @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) + public static ComponentUI createUI(JComponent c) { + return new OnOffButtonUI((OnOffButton)c); + } + + @Override + public Dimension getPreferredSize(JComponent c) { + final OnOffButton button = (OnOffButton)c; + String text = button.getOffText().length() > button.getOnText().length() ? button.getOffText() : button.getOnText(); + text = text.toUpperCase(); + final FontMetrics fm = c.getFontMetrics(c.getFont()); + int w = fm.stringWidth(text); + int h = fm.getHeight(); + h += 2*4; + w += 3 * h / 2 + 4; + return new Dimension(w, h); + } + @Override + public void paint(Graphics gr, JComponent c) { + final OnOffButton button = (OnOffButton)c; + final Dimension size = button.getSize(); + int w = size.width-4; + int h = size.height-4; + if (h % 2 == 1) { + h--; + } + Graphics2D g = ((Graphics2D)gr); + GraphicsUtil.setupAAPainting(g); + g.translate(1,1); + if (button.isSelected()) { + g.setColor(new Color(13, 41, 62)); + g.fillRoundRect(0, 0, w, h, h, h); + g.setColor(UIUtil.getBorderColor()); + g.drawRoundRect(0, 0, w, h, h, h); + g.setColor(Gray._128); + g.fillOval(w - h + 1, 1, h - 1, h - 1); + g.setColor(UIUtil.getListForeground(true)); + g.drawString(button.getOnText(), h/2, h - 4); + } else { + g.setColor(UIUtil.getPanelBackground()); + g.fillRoundRect(0, 0, w, h, h, h); + g.setColor(UIUtil.getBorderColor()); + g.drawRoundRect(0, 0, w, h, h, h); + g.setColor(UIUtil.getLabelDisabledForeground()); + g.drawString(button.getOffText(), h + 4 , h - 4); + g.setColor(Gray._128); + g.fillOval(0, 0, h - 1, h - 1); + } + g.translate(-1, -1); + } + + @Override + public Dimension getMinimumSize(JComponent c) { + return getPreferredSize(c); + } + + @Override + public Dimension getMaximumSize(JComponent c) { + return getPreferredSize(c); + } + } +} diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java index 3778292dc9c1..6b9a48d3e6a8 100644 --- a/platform/platform-api/src/com/intellij/util/Alarm.java +++ b/platform/platform-api/src/com/intellij/util/Alarm.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -284,21 +284,16 @@ public class Alarm implements Disposable { myFuture = null; } - if (myThreadToUse == ThreadToUse.SWING_THREAD && !isEdt()) { - try { + try { + if (myThreadToUse == ThreadToUse.SWING_THREAD && !isEdt()) { SwingUtilities.invokeAndWait(task); } - catch (Exception e) { - LOG.error(e); - } - } - else { - try { + else { task.run(); } - catch (Exception e) { - LOG.error(e); - } + } + catch (Exception e) { + LOG.error("Exception in task " + task, e); } } }; diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java index 52ad3df3abb5..c3be5108c4ae 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java @@ -684,6 +684,9 @@ public class HintManagerImpl extends HintManager implements Disposable { } public void showInformationHint(@NotNull Editor editor, @NotNull JComponent component, boolean showByBalloon) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + return; + } LightweightHint hint = new LightweightHint(component); Point p = getHintPosition(hint, editor, ABOVE); showEditorHint(hint, editor, p, HIDE_BY_ANY_KEY | HIDE_BY_TEXT_CHANGE | HIDE_BY_SCROLLING, 0, false); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 440dafba4a00..5c39ebce4732 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -5596,7 +5596,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi mySelectionModel.setSelection(caretOffset, caretOffset); } else { - if (!e.isPopupTrigger() && eventArea == EditorMouseEventArea.EDITING_AREA) { + if (!e.isPopupTrigger() + && (eventArea == EditorMouseEventArea.EDITING_AREA || eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA)) + { switch (e.getClickCount()) { case 2: selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords() && mySettings.isCamelWords()); diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 295d94c40d93..6bda69e29358 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -103,6 +103,7 @@ + @@ -144,11 +145,6 @@ - - - - diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index bb3e5ba7ebe4..a7227be4a095 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -305,5 +305,6 @@ groupKey="group.names.portability.issues" enabledByDefault="false" level="WARNING" implementationClass="com.intellij.codeStyle.InconsistentLineSeparatorsInspection"/> + diff --git a/platform/platform-resources/src/META-INF/RemoteServers.xml b/platform/platform-resources/src/META-INF/RemoteServers.xml index 54bd764d2533..a72377709dc4 100644 --- a/platform/platform-resources/src/META-INF/RemoteServers.xml +++ b/platform/platform-resources/src/META-INF/RemoteServers.xml @@ -8,8 +8,8 @@ serviceImplementation="com.intellij.remoteServer.impl.configuration.RemoteServersManagerImpl"/> - + diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index f778527950c1..769a2c2a55b5 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -111,8 +111,6 @@ - - diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java index 94c600ab94eb..5279f527175c 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java @@ -6,10 +6,10 @@ import com.intellij.openapi.project.Project; import com.intellij.remoteServer.configuration.ServerConfiguration; import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurator; import com.intellij.remoteServer.runtime.ServerConnector; +import com.intellij.remoteServer.runtime.ServerTaskExecutor; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import java.util.concurrent.Executor; /** * @author nik @@ -42,5 +42,5 @@ public abstract class ServerType { public abstract DeploymentConfigurator createDeployer(Project project); @NotNull - public abstract ServerConnector createConnector(@NotNull C configuration, @NotNull Project project, @NotNull Executor asyncTasksExecutor); + public abstract ServerConnector createConnector(@NotNull C configuration, @NotNull ServerTaskExecutor asyncTasksExecutor); } diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/RemoteOperationCallback.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/RemoteOperationCallback.java new file mode 100644 index 000000000000..49a5c9f787a5 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/RemoteOperationCallback.java @@ -0,0 +1,10 @@ +package com.intellij.remoteServer.runtime; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface RemoteOperationCallback { + void errorOccurred(@NotNull String errorMessage); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnection.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnection.java index ab5a32b54be6..a73037bc80fb 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnection.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnection.java @@ -4,6 +4,7 @@ import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; import com.intellij.remoteServer.configuration.deployment.DeploymentSource; import com.intellij.remoteServer.runtime.deployment.DeploymentStatus; +import com.intellij.remoteServer.runtime.deployment.DeploymentTask; import org.jetbrains.annotations.NotNull; /** @@ -20,9 +21,12 @@ public interface ServerConnection { String getStatusText(); - void deploy(@NotNull DeploymentSource source, @NotNull D configuration); + void connect(@NotNull Runnable onFinished); - void undeploy(@NotNull DeploymentSource source, @NotNull D configuration); + + void deploy(@NotNull DeploymentTask task); + + void undeploy(@NotNull DeploymentTask task); @NotNull DeploymentStatus getDeploymentStatus(@NotNull DeploymentSource source); diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnectionManager.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnectionManager.java index 6a22b11ba374..494504c68062 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnectionManager.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnectionManager.java @@ -1,7 +1,6 @@ package com.intellij.remoteServer.runtime; import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.project.Project; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.ServerConfiguration; import org.jetbrains.annotations.NotNull; @@ -13,8 +12,8 @@ import java.util.Collection; */ public abstract class ServerConnectionManager { @NotNull - public static ServerConnectionManager getInstance(@NotNull Project project) { - return ServiceManager.getService(project, ServerConnectionManager.class); + public static ServerConnectionManager getInstance() { + return ServiceManager.getService(ServerConnectionManager.class); } @NotNull diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnector.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnector.java index 3520941d42c9..e3b16f04245c 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnector.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerConnector.java @@ -12,8 +12,7 @@ public abstract class ServerConnector { public abstract void disconnect(); - public interface ConnectionCallback { + public interface ConnectionCallback extends RemoteOperationCallback { void connected(@NotNull ServerRuntimeInstance serverRuntimeInstance); - void connectionFailed(@NotNull String errorMessage); } } diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerRuntimeData.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerRuntimeData.java deleted file mode 100644 index 04cd1507600b..000000000000 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerRuntimeData.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.intellij.remoteServer.runtime; - -/** - * @author nik - */ -public interface ServerRuntimeData { -} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerTaskExecutor.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerTaskExecutor.java new file mode 100644 index 000000000000..05f72923e1c4 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/ServerTaskExecutor.java @@ -0,0 +1,14 @@ +package com.intellij.remoteServer.runtime; + +import com.intellij.util.ThrowableRunnable; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.Executor; + +/** + * @author nik + */ +public interface ServerTaskExecutor extends Executor { + void submit(@NotNull Runnable command); + void submit(@NotNull ThrowableRunnable command, @NotNull RemoteOperationCallback callback); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java new file mode 100644 index 000000000000..73708bad843b --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/DeploymentTask.java @@ -0,0 +1,20 @@ +package com.intellij.remoteServer.runtime.deployment; + +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; +import com.intellij.remoteServer.configuration.deployment.DeploymentSource; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface DeploymentTask { + @NotNull + DeploymentSource getSource(); + + @NotNull + D getConfiguration(); + + @NotNull + Project getProject(); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java index a844f9f59a95..2d0e08e7de18 100644 --- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java @@ -1,7 +1,7 @@ package com.intellij.remoteServer.runtime.deployment; import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; -import com.intellij.remoteServer.configuration.deployment.DeploymentSource; +import com.intellij.remoteServer.runtime.RemoteOperationCallback; import org.jetbrains.annotations.NotNull; /** @@ -9,15 +9,11 @@ import org.jetbrains.annotations.NotNull; */ public abstract class ServerRuntimeInstance { - public abstract void deploy(@NotNull DeploymentSource source, @NotNull D configuration, - @NotNull DeploymentOperationCallback callback); + public abstract void deploy(@NotNull DeploymentTask task, @NotNull DeploymentOperationCallback callback); - public abstract void undeploy(@NotNull DeploymentSource source, @NotNull D configuration, - @NotNull DeploymentOperationCallback callback); + public abstract void undeploy(@NotNull DeploymentTask task, @NotNull DeploymentOperationCallback callback); - public interface DeploymentOperationCallback { + public interface DeploymentOperationCallback extends RemoteOperationCallback { void succeeded(); - - void failed(@NotNull String errorMessage); } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.form b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.form new file mode 100644 index 000000000000..38c658d0bc71 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.form @@ -0,0 +1,39 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java index 50e6b1317949..1a65ddd4c06b 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java @@ -1,15 +1,27 @@ package com.intellij.remoteServer.impl.configuration; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.remoteServer.runtime.ConnectionStatus; +import com.intellij.remoteServer.runtime.ServerConnection; +import com.intellij.remoteServer.runtime.ServerConnectionManager; +import com.intellij.util.concurrency.Semaphore; import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.concurrent.atomic.AtomicReference; /** * @author nik @@ -19,6 +31,9 @@ public class RemoteServerConfigurable extends NamedConfigurable> private final RemoteServer myServer; private String myServerName; private boolean myNew; + private JPanel myMainPanel; + private JPanel mySettingsPanel; + private JButton myTestConnectionButton; public RemoteServerConfigurable(RemoteServer server, Runnable treeUpdater, boolean isNew) { super(true, treeUpdater); @@ -41,10 +56,58 @@ public class RemoteServerConfigurable extends NamedConfigurable> @Override public JComponent createOptionsPanel() { - JComponent component = myConfigurable.createComponent(); - JPanel panel = new JPanel(new BorderLayout()); - panel.add(component, BorderLayout.NORTH); - return panel; + mySettingsPanel.add(BorderLayout.CENTER, myConfigurable.createComponent()); + myTestConnectionButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + apply(); + } + catch (ConfigurationException exc) { + Messages.showErrorDialog(myMainPanel, "Cannot test connection: " + exc.getMessage(), exc.getTitle()); + return; + } + testConnection(); + } + }); + return myMainPanel; + } + + private void testConnection() { + final ServerConnection connection = ServerConnectionManager.getInstance().getOrCreateConnection(myServer); + final AtomicReference showResultRef = new AtomicReference(null); + new Task.Modal(null, "Connecting...", true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + indicator.setIndeterminate(true); + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + connection.connect(new Runnable() { + @Override + public void run() { + showResultRef.set(new Runnable() { + @Override + public void run() { + if (connection.getStatus() == ConnectionStatus.CONNECTED) { + Messages.showInfoMessage(myMainPanel, "Connection successful", "Test Connection"); + } + else if (connection.getStatus() == ConnectionStatus.DISCONNECTED) { + Messages.showErrorDialog(myMainPanel, "Cannot connect: " + connection.getStatusText(), "Test Connection"); + } + } + }); + semaphore.up(); + } + }); + while (!indicator.isCanceled()) { + semaphore.waitFor(500); + } + Runnable showResult = showResultRef.get(); + if (showResult != null) { + ApplicationManager.getApplication().invokeLater(showResult); + } + } + }.queue(); } @Nls diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java index 04dab47703dc..94015e971890 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java @@ -25,6 +25,7 @@ import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.ServerConfiguration; import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; import com.intellij.remoteServer.configuration.deployment.DeploymentSource; +import com.intellij.remoteServer.impl.runtime.deployment.DeploymentTaskImpl; import com.intellij.remoteServer.runtime.ServerConnection; import com.intellij.remoteServer.runtime.ServerConnectionManager; import org.jetbrains.annotations.NotNull; @@ -51,8 +52,8 @@ public class DeployToServerState implements } @Override - public void deploy(@NotNull final DeploymentSource source, @NotNull final D configuration) { - runOnInstance(new ParameterizedRunnable>() { + public void connect(@NotNull final Runnable onFinished) { + disconnect(); + connectIfNeeded(new ServerConnector.ConnectionCallback() { @Override - public void run(ServerRuntimeInstance instance) { - myDeploymentInfos.put(source, new DeploymentInformation(DeploymentStatus.DEPLOYING)); - instance.deploy(source, configuration, new UpdateDeploymentStatusCallback(source, DeploymentStatus.DEPLOYED, - DeploymentStatus.NOT_DEPLOYED)); + public void connected(@NotNull ServerRuntimeInstance serverRuntimeInstance) { + onFinished.run(); + } + + @Override + public void errorOccurred(@NotNull String errorMessage) { + onFinished.run(); + } + }); + } + + private void disconnect() { + if (myStatus == ConnectionStatus.CONNECTED) { + myRuntimeInstance = null; + myConnector.disconnect(); + myStatus = ConnectionStatus.DISCONNECTED; + } + } + + @Override + public void deploy(@NotNull final DeploymentTask task) { + connectIfNeeded(new ConnectionCallbackBase() { + @Override + public void connected(@NotNull ServerRuntimeInstance instance) { + myDeploymentInfos.put(task.getSource(), new DeploymentInformation(DeploymentStatus.DEPLOYING)); + instance.deploy(task, new UpdateDeploymentStatusCallback(task.getSource(), DeploymentStatus.DEPLOYED, + DeploymentStatus.NOT_DEPLOYED)); } }); } @Override - public void undeploy(@NotNull final DeploymentSource source, @NotNull final D configuration) { - runOnInstance(new ParameterizedRunnable>() { + public void undeploy(@NotNull final DeploymentTask task) { + connectIfNeeded(new ConnectionCallbackBase() { @Override - public void run(ServerRuntimeInstance instance) { - instance.undeploy(source, configuration, new UpdateDeploymentStatusCallback(source, DeploymentStatus.NOT_DEPLOYED, DeploymentStatus.DEPLOYED)); + public void connected(@NotNull ServerRuntimeInstance instance) { + myDeploymentInfos.put(task.getSource(), new DeploymentInformation(DeploymentStatus.UNDEPLOYING)); + instance.undeploy(task, new UpdateDeploymentStatusCallback(task.getSource(), DeploymentStatus.NOT_DEPLOYED, + DeploymentStatus.DEPLOYED)); } }); } @@ -76,10 +103,10 @@ public class ServerConnectionImpl implements return information != null ? information.getStatus() : DeploymentStatus.NOT_DEPLOYED; } - private void runOnInstance(final ParameterizedRunnable> action) { + private void connectIfNeeded(final ServerConnector.ConnectionCallback callback) { final ServerRuntimeInstance instance = myRuntimeInstance; if (instance != null) { - action.run(instance); + callback.connected(instance); return; } @@ -89,18 +116,25 @@ public class ServerConnectionImpl implements public void connected(@NotNull ServerRuntimeInstance instance) { myStatus = ConnectionStatus.CONNECTED; myRuntimeInstance = instance; - action.run(instance); + callback.connected(instance); } @Override - public void connectionFailed(@NotNull String errorMessage) { + public void errorOccurred(@NotNull String errorMessage) { myStatus = ConnectionStatus.DISCONNECTED; myRuntimeInstance = null; myStatusText = errorMessage; + callback.errorOccurred(errorMessage); } }); } + private static abstract class ConnectionCallbackBase implements ServerConnector.ConnectionCallback { + @Override + public void errorOccurred(@NotNull String errorMessage) { + } + } + private class UpdateDeploymentStatusCallback implements ServerRuntimeInstance.DeploymentOperationCallback { private final DeploymentSource mySource; private DeploymentStatus mySuccessStatus; @@ -118,7 +152,7 @@ public class ServerConnectionImpl implements } @Override - public void failed(@NotNull String errorMessage) { + public void errorOccurred(@NotNull String errorMessage) { myDeploymentInfos.put(mySource, new DeploymentInformation(myFailedStatus, errorMessage)); } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java index 5029686fb5aa..66a56da6ddd5 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java @@ -1,13 +1,11 @@ package com.intellij.remoteServer.impl.runtime; -import com.intellij.openapi.project.Project; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.ServerConfiguration; import com.intellij.remoteServer.runtime.ServerConnection; import com.intellij.remoteServer.runtime.ServerConnectionManager; -import com.intellij.util.concurrency.SequentialTaskExecutor; import org.jetbrains.annotations.NotNull; -import org.jetbrains.ide.PooledThreadExecutor; import java.util.Collection; import java.util.Collections; @@ -19,20 +17,15 @@ import java.util.Map; */ public class ServerConnectionManagerImpl extends ServerConnectionManager { private Map, ServerConnection> myConnections = new HashMap, ServerConnection>(); - private final PooledThreadExecutor myPooledThreadExecutor = new PooledThreadExecutor(); - private final Project myProject; - - public ServerConnectionManagerImpl(Project project) { - myProject = project; - } @NotNull @Override public ServerConnection getOrCreateConnection(@NotNull RemoteServer server) { + ApplicationManager.getApplication().assertIsDispatchThread(); ServerConnection connection = myConnections.get(server); if (connection == null) { - SequentialTaskExecutor executor = new SequentialTaskExecutor(myPooledThreadExecutor); - connection = new ServerConnectionImpl(server, server.getType().createConnector(server.getConfiguration(), myProject, executor)); + ServerTaskExecutorImpl executor = new ServerTaskExecutorImpl(); + connection = new ServerConnectionImpl(server, server.getType().createConnector(server.getConfiguration(), executor)); myConnections.put(server, connection); } return connection; @@ -41,6 +34,7 @@ public class ServerConnectionManagerImpl extends ServerConnectionManager { @NotNull @Override public Collection getConnections() { + ApplicationManager.getApplication().assertIsDispatchThread(); return Collections.unmodifiableCollection(myConnections.values()); } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java new file mode 100644 index 000000000000..43722962fcbd --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerTaskExecutorImpl.java @@ -0,0 +1,48 @@ +package com.intellij.remoteServer.impl.runtime; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.remoteServer.runtime.RemoteOperationCallback; +import com.intellij.remoteServer.runtime.ServerTaskExecutor; +import com.intellij.util.ThrowableRunnable; +import com.intellij.util.concurrency.SequentialTaskExecutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.ide.PooledThreadExecutor; + +/** + * @author nik + */ +public class ServerTaskExecutorImpl implements ServerTaskExecutor { + private static final Logger LOG = Logger.getInstance(ServerTaskExecutorImpl.class); + private static final PooledThreadExecutor POOLED_THREAD_EXECUTOR = new PooledThreadExecutor(); + private final SequentialTaskExecutor myTaskExecutor; + + public ServerTaskExecutorImpl() { + myTaskExecutor = new SequentialTaskExecutor(POOLED_THREAD_EXECUTOR); + } + + @Override + public void execute(@NotNull Runnable command) { + myTaskExecutor.execute(command); + } + + @Override + public void submit(@NotNull Runnable command) { + execute(command); + } + + @Override + public void submit(@NotNull final ThrowableRunnable command, @NotNull final RemoteOperationCallback callback) { + execute(new Runnable() { + @Override + public void run() { + try { + command.run(); + } + catch (Throwable e) { + LOG.info(e); + callback.errorOccurred(e.getMessage()); + } + } + }); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeploymentInformation.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java similarity index 91% rename from platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeploymentInformation.java rename to platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java index 54e2d35ad325..97117e4788b7 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeploymentInformation.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentInformation.java @@ -1,4 +1,4 @@ -package com.intellij.remoteServer.impl.runtime; +package com.intellij.remoteServer.impl.runtime.deployment; import com.intellij.remoteServer.runtime.deployment.DeploymentStatus; import org.jetbrains.annotations.NotNull; diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java new file mode 100644 index 000000000000..f9ecc769d705 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/deployment/DeploymentTaskImpl.java @@ -0,0 +1,37 @@ +package com.intellij.remoteServer.impl.runtime.deployment; + +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration; +import com.intellij.remoteServer.configuration.deployment.DeploymentSource; +import com.intellij.remoteServer.runtime.deployment.DeploymentTask; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class DeploymentTaskImpl implements DeploymentTask { + private final DeploymentSource mySource; + private final D myConfiguration; + private final Project myProject; + + public DeploymentTaskImpl(DeploymentSource source, D configuration, Project project) { + mySource = source; + myConfiguration = configuration; + myProject = project; + } + + @NotNull + public DeploymentSource getSource() { + return mySource; + } + + @NotNull + public D getConfiguration() { + return myConfiguration; + } + + @NotNull + public Project getProject() { + return myProject; + } +} diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 142e23c898e5..31c7afcb8a93 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -667,7 +667,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig myFile.getName() + " at caret position, offset " + myEditor.getCaretModel().getOffset() + "\"" + - " psi structure: " + DebugUtil.psiToString(myFile, true); + " psi structure: " + DebugUtil.psiToString(myFile, true, true); return element; } diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index bd2a44f46293..4e1754bffbee 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -136,7 +136,6 @@ public class AllIcons { public static final Icon ShowHiddens = IconLoader.getIcon("/actions/showHiddens.png"); // 16x16 public static final Icon ShowImportStatements = IconLoader.getIcon("/actions/showImportStatements.png"); // 16x16 public static final Icon ShowReadAccess = IconLoader.getIcon("/actions/showReadAccess.png"); // 16x16 - public static final Icon ShowSource = IconLoader.getIcon("/actions/showSource.png"); // 16x16 public static final Icon ShowViewer = IconLoader.getIcon("/actions/showViewer.png"); // 16x16 public static final Icon ShowWriteAccess = IconLoader.getIcon("/actions/showWriteAccess.png"); // 16x16 public static final Icon SortAsc = IconLoader.getIcon("/actions/sortAsc.png"); // 9x8 diff --git a/platform/util/src/com/intellij/util/ReflectionAssignabilityCache.java b/platform/util/src/com/intellij/util/ReflectionAssignabilityCache.java index e9e2cecc45e3..a5a1c68a7f14 100644 --- a/platform/util/src/com/intellij/util/ReflectionAssignabilityCache.java +++ b/platform/util/src/com/intellij/util/ReflectionAssignabilityCache.java @@ -19,6 +19,7 @@ import com.intellij.util.containers.ConcurrentFactoryMap; /** * @author peter + * @see ReflectionCache */ public class ReflectionAssignabilityCache { private final ConcurrentFactoryMap> myCache = new ConcurrentFactoryMap>() { diff --git a/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java b/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java index 8b11f497f457..efc36a5cb1cb 100644 --- a/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java @@ -18,6 +18,7 @@ package com.intellij.util.xmlb; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.xmlb.annotations.OptionTag; import org.jdom.Attribute; @@ -64,7 +65,9 @@ class OptionTagBinding implements Binding { Element targetElement = new Element(myTagName); Object value = accessor.read(o); - targetElement.setAttribute(myNameAttribute, myName); + if (!StringUtil.isEmpty(myNameAttribute)) { + targetElement.setAttribute(myNameAttribute, myName); + } if (value == null) return targetElement; @@ -123,6 +126,9 @@ class OptionTagBinding implements Binding { Element e = (Element)node; if (!e.getName().equals(myTagName)) return false; String name = e.getAttributeValue(myNameAttribute); + if (StringUtil.isEmpty(myNameAttribute)) { + return name == null || name.equals(myName); + } return name != null && name.equals(myName); } diff --git a/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java b/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java index 3f921b3ed206..669d0116e734 100644 --- a/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java +++ b/platform/util/src/com/intellij/util/xmlb/annotations/OptionTag.java @@ -23,7 +23,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Store value in tag like <option name="optionName" value="optionValue"/> + *

Store value in tag like {@code

+ *

nameAttribute can be empty, in which case it is skipped: {@code

* * @author nik */ diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ThreeStateBoolean.java b/platform/vcs-api/src/com/intellij/openapi/vcs/ThreeStateBoolean.java deleted file mode 100644 index 69bad16990ea..000000000000 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ThreeStateBoolean.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.vcs; - -public enum ThreeStateBoolean { - yes, - no, - z; - - public static ThreeStateBoolean getInstance(final boolean value) { - return value ? yes : no; - } -} diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java index d482a19b5fd0..f5e2de674959 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java @@ -21,14 +21,13 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.impl.IgnoreSpaceEnum; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.DefaultJDOMExternalizer; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.PlatformUtils; -import org.jdom.Element; +import com.intellij.util.xmlb.XmlSerializerUtil; +import com.intellij.util.xmlb.annotations.AbstractCollection; +import com.intellij.util.xmlb.annotations.OptionTag; +import com.intellij.util.xmlb.annotations.Property; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -38,28 +37,18 @@ import java.util.List; /** * author: lesya */ - @State( name = "VcsManagerConfiguration", - storages = { - @Storage( - file = StoragePathMacros.WORKSPACE_FILE - ) - } -) -public final class VcsConfiguration implements PersistentStateComponent { + storages = { @Storage(file = StoragePathMacros.WORKSPACE_FILE) }) +public final class VcsConfiguration implements PersistentStateComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.VcsConfiguration"); public final static long ourMaximumFileForBaseRevisionSize = 500 * 1000; @NonNls static final String VALUE_ATTR = "value"; - @NonNls private static final String CONFIRM_MOVE_TO_FAILED_COMMIT_ELEMENT = "confirmMoveToFailedCommit"; - @NonNls private static final String CONFIRM_REMOVE_EMPTY_CHANGELIST_ELEMENT = "confirmRemoveEmptyChangelist"; @NonNls public static final String PATCH = "patch"; @NonNls public static final String DIFF = "diff"; - private Project myProject; - public boolean OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT = true; public boolean CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT = !PlatformUtils.isPyCharm() && !PlatformUtils.isRubyMine(); public boolean CHECK_NEW_TODO = true; @@ -71,7 +60,9 @@ public final class VcsConfiguration implements PersistentStateComponent public boolean PERFORM_ADD_REMOVE_IN_BACKGROUND = true; public boolean PERFORM_ROLLBACK_IN_BACKGROUND = false; public volatile boolean CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND = false; + @OptionTag(tag = "confirmMoveToFailedCommit", nameAttribute = "") public VcsShowConfirmationOption.Value MOVE_TO_FAILED_COMMIT_CHANGELIST = VcsShowConfirmationOption.Value.SHOW_CONFIRMATION; + @OptionTag(tag = "confirmRemoveEmptyChangelist", nameAttribute = "") public VcsShowConfirmationOption.Value REMOVE_EMPTY_INACTIVE_CHANGELISTS = VcsShowConfirmationOption.Value.SHOW_CONFIRMATION; public int CHANGED_ON_SERVER_INTERVAL = 60; public boolean SHOW_ONLY_CHANGED_IN_SELECTION_DIFF = true; @@ -132,7 +123,9 @@ public final class VcsConfiguration implements PersistentStateComponent public boolean FORCE_NON_EMPTY_COMMENT = false; public boolean CLEAR_INITIAL_COMMIT_MESSAGE = false; - private final ArrayList myLastCommitMessages = new ArrayList(); + @Property(surroundWithTag = false) + @AbstractCollection(elementTag = "MESSAGE", elementValueAttribute = "value", surroundWithTag = false) + public List myLastCommitMessages = new ArrayList(); public String LAST_COMMIT_MESSAGE = null; public boolean MAKE_NEW_CHANGELIST_ACTIVE = false; @@ -145,7 +138,6 @@ public final class VcsConfiguration implements PersistentStateComponent public float FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION = 0.8f; public float FILE_HISTORY_DIALOG_SPLITTER_PROPORTION = 0.5f; - public String ACTIVE_VCS_NAME = null; public boolean UPDATE_GROUP_BY_PACKAGES = false; public boolean UPDATE_GROUP_BY_CHANGELIST = false; public boolean UPDATE_FILTER_BY_SCOPE = false; @@ -160,71 +152,15 @@ public final class VcsConfiguration implements PersistentStateComponent private final PerformInBackgroundOption myCheckoutOption = new CheckoutInBackgroundOption(); private final PerformInBackgroundOption myAddRemoveOption = new AddRemoveInBackgroundOption(); - public VcsConfiguration(final Project project) { - myProject = project; + public VcsConfiguration() { } - public Element getState() { - try { - final Element e = new Element("state"); - writeExternal(e); - return e; - } - catch (WriteExternalException e1) { - LOG.error(e1); - return null; - } + public VcsConfiguration getState() { + return this; } - public void loadState(Element state) { - try { - readExternal(state); - } - catch (InvalidDataException e) { - LOG.error(e); - } - } - - public void readExternal(Element element) throws InvalidDataException { - DefaultJDOMExternalizer.readExternal(this, element); - Element child = element.getChild(CONFIRM_MOVE_TO_FAILED_COMMIT_ELEMENT); - if (child != null) { - MOVE_TO_FAILED_COMMIT_CHANGELIST = VcsShowConfirmationOption.Value.fromString(child.getAttributeValue(VALUE_ATTR)); - } - child = element.getChild(CONFIRM_REMOVE_EMPTY_CHANGELIST_ELEMENT); - if (child != null) { - REMOVE_EMPTY_INACTIVE_CHANGELISTS = VcsShowConfirmationOption.Value.fromString(child.getAttributeValue(VALUE_ATTR)); - } - final List messages = element.getChildren(MESSAGE_ELEMENT_NAME); - for (final Object message : messages) { - saveCommitMessage(((Element)message).getAttributeValue(VALUE_ATTR)); - } - if (ACTIVE_VCS_NAME != null && ACTIVE_VCS_NAME.length() > 0) { - StartupManager.getInstance(myProject).registerStartupActivity(new Runnable() { - public void run() { - ProjectLevelVcsManager.getInstance(myProject).setDirectoryMapping("", ACTIVE_VCS_NAME); - } - }); - } - } - - public void writeExternal(Element element) throws WriteExternalException { - DefaultJDOMExternalizer.writeExternal(this, element); - if (MOVE_TO_FAILED_COMMIT_CHANGELIST != VcsShowConfirmationOption.Value.SHOW_CONFIRMATION) { - Element confirmChild = new Element(CONFIRM_MOVE_TO_FAILED_COMMIT_ELEMENT); - confirmChild.setAttribute(VALUE_ATTR, MOVE_TO_FAILED_COMMIT_CHANGELIST.toString()); - element.addContent(confirmChild); - } - if (REMOVE_EMPTY_INACTIVE_CHANGELISTS != VcsShowConfirmationOption.Value.SHOW_CONFIRMATION) { - Element confirmChild = new Element(CONFIRM_REMOVE_EMPTY_CHANGELIST_ELEMENT); - confirmChild.setAttribute(VALUE_ATTR, REMOVE_EMPTY_INACTIVE_CHANGELISTS.toString()); - element.addContent(confirmChild); - } - for (String message : myLastCommitMessages) { - final Element messageElement = new Element(MESSAGE_ELEMENT_NAME); - messageElement.setAttribute(VALUE_ATTR, message); - element.addContent(messageElement); - } + public void loadState(VcsConfiguration state) { + XmlSerializerUtil.copyBean(state, this); } public static VcsConfiguration getInstance(Project project) { @@ -232,17 +168,12 @@ public final class VcsConfiguration implements PersistentStateComponent } public void saveCommitMessage(final String comment) { - LAST_COMMIT_MESSAGE = comment; - if (comment == null || comment.length() == 0) return; - myLastCommitMessages.remove(comment); - while (myLastCommitMessages.size() >= MAX_STORED_MESSAGES) { myLastCommitMessages.remove(0); } - myLastCommitMessages.add(comment); } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsShowConfirmationOption.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsShowConfirmationOption.java index 0eb8ca02c32d..9322251a1871 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsShowConfirmationOption.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsShowConfirmationOption.java @@ -16,34 +16,27 @@ package com.intellij.openapi.vcs; public interface VcsShowConfirmationOption { + enum Value { - SHOW_CONFIRMATION(0), - DO_NOTHING_SILENTLY(1), - DO_ACTION_SILENTLY(2); + // NB: don't reorder enum values, otherwise you may break user settings based on the obsolete implementation + SHOW_CONFIRMATION, + DO_NOTHING_SILENTLY, + DO_ACTION_SILENTLY; - private final int myId; - - Value(final int id) { - myId = id; - } - - public int getId() { - return myId; - } - public String toString() { - return String.valueOf(myId); + // compatibility with the old implementation + return String.valueOf(ordinal()); } + @Deprecated public static Value fromString(String s){ - if (s == null) return SHOW_CONFIRMATION; if (s.equals("1")) return DO_NOTHING_SILENTLY; if (s.equals("2")) return DO_ACTION_SILENTLY; return SHOW_CONFIRMATION; } } - public static final VcsShowConfirmationOption STATIC_SHOW_CONFIRMATION = new VcsShowConfirmationOption() { + VcsShowConfirmationOption STATIC_SHOW_CONFIRMATION = new VcsShowConfirmationOption() { @Override public Value getValue() { return Value.SHOW_CONFIRMATION; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java index c9bfa4baeaa3..781e4fd949a6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java @@ -216,8 +216,10 @@ public class VcsGeneralConfigurationPanel implements SearchableConfigurable { myForceNonEmptyComment.setSelected(settings.FORCE_NON_EMPTY_COMMENT); myClearInitialCommitMessage.setSelected(settings.CLEAR_INITIAL_COMMIT_MESSAGE); myCbOfferToMoveChanges.setSelected(settings.OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT); - int id = settings.REMOVE_EMPTY_INACTIVE_CHANGELISTS.getId(); - UIUtil.setSelectedButton(myEmptyChangelistRemovingGroup, id == 0 ? 0 : id == 1 ? 2 : 1); + VcsShowConfirmationOption.Value value = settings.REMOVE_EMPTY_INACTIVE_CHANGELISTS; + UIUtil.setSelectedButton(myEmptyChangelistRemovingGroup, value == VcsShowConfirmationOption.Value.SHOW_CONFIRMATION + ? 0 + : value == VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY ? 2 : 1); myShowReadOnlyStatusDialog.setSelected(getReadOnlyStatusHandler().getState().SHOW_DIALOG); if (settings.MOVE_TO_FAILED_COMMIT_CHANGELIST == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { myFailedCommitChangelistCombo.setSelectedIndex(0); diff --git a/plugins/IntelliLang/IntelliLang-tests/test/org/intellij/plugins/intelliLang/ReferenceInjectionTest.java b/plugins/IntelliLang/IntelliLang-tests/test/org/intellij/plugins/intelliLang/ReferenceInjectionTest.java index f3890bcc67d8..75fead477579 100644 --- a/plugins/IntelliLang/IntelliLang-tests/test/org/intellij/plugins/intelliLang/ReferenceInjectionTest.java +++ b/plugins/IntelliLang/IntelliLang-tests/test/org/intellij/plugins/intelliLang/ReferenceInjectionTest.java @@ -1,11 +1,17 @@ package org.intellij.plugins.intelliLang; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiReference; import com.intellij.psi.impl.PsiModificationTrackerImpl; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; import org.intellij.plugins.intelliLang.inject.InjectLanguageAction; import org.intellij.plugins.intelliLang.inject.UnInjectLanguageAction; import org.intellij.plugins.intelliLang.references.FileReferenceInjector; +import org.intellij.plugins.intelliLang.references.InjectedReferencesContributor; +import org.intellij.plugins.intelliLang.references.InjectedReferencesInspection; import org.jdom.Element; /** @@ -27,6 +33,11 @@ public class ReferenceInjectionTest extends LightPlatformCodeInsightFixtureTestC assertFalse(new InjectLanguageAction().isAvailable(getProject(), myFixture.getEditor(), myFixture.getFile())); assertTrue(new UnInjectLanguageAction().isAvailable(getProject(), myFixture.getEditor(), myFixture.getFile())); + myFixture.configureByText("bar.xml", + "http://foo.bar\" \n" + + " xxx=\"bar\"/>"); + myFixture.testHighlighting(); + UnInjectLanguageAction.invokeImpl(getProject(), myFixture.getEditor(), myFixture.getFile()); assertNull(myFixture.getReferenceAtCaretPosition()); } @@ -60,4 +71,44 @@ public class ReferenceInjectionTest extends LightPlatformCodeInsightFixtureTestC UnInjectLanguageAction.invokeImpl(getProject(), myFixture.getEditor(), myFixture.getFile()); assertNull(myFixture.getReferenceAtCaretPosition()); } + + public void testInjectIntoJava() throws Exception { + myFixture.configureByText("Foo.java", "class Foo {\n" + + " String bar() {\n" + + " return \"bar.xml\";\n" + + " } \n" + + "}"); + assertNull(getInjectedReferences()); + + InjectLanguageAction.invokeImpl(getProject(), myFixture.getEditor(), myFixture.getFile(), new FileReferenceInjector()); + assertNotNull(getInjectedReferences()); + + UnInjectLanguageAction.invokeImpl(getProject(), myFixture.getEditor(), myFixture.getFile()); + assertNull(getInjectedReferences()); + } + + private PsiReference[] getInjectedReferences() { + PsiElement element = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); + element = PsiTreeUtil.getParentOfType(element, PsiLanguageInjectionHost.class); + assertNotNull(element); + element.getReferences(); + return InjectedReferencesContributor.getInjectedReferences(element); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFixture.enableInspections(new InjectedReferencesInspection()); + } + + @Override + protected void tearDown() throws Exception { + myFixture.disableInspections(new InjectedReferencesInspection()); + super.tearDown(); + } + + @Override + protected boolean isWriteActionRequired() { + return false; + } } diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java index 3b2a2fbad60b..464aa38ccc03 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/MethodParameterInjection.java @@ -26,7 +26,7 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.util.IncorrectOperationException; import gnu.trove.THashMap; -import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; +import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -42,7 +42,7 @@ public class MethodParameterInjection extends BaseInjection { private final Map myParameterMap = new THashMap(); public MethodParameterInjection() { - super(LanguageInjectionSupport.JAVA_SUPPORT_ID); + super(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); } @NotNull diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java index 1bbcbaa55ac8..b2f1360b59d9 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java @@ -69,7 +69,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { myConfiguration = configuration; myProject = project; myTemporaryPlacesRegistry = temporaryPlacesRegistry; - mySupport = InjectorUtils.findNotNullInjectionSupport(LanguageInjectionSupport.JAVA_SUPPORT_ID); + mySupport = InjectorUtils.findNotNullInjectionSupport(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); myXmlIndex = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider>() { public Result> compute() { final Map, BaseInjection> map = new THashMap, BaseInjection>(); @@ -139,7 +139,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { if (!hasLiteral) return; final Language tempLanguage = tempInjectedLanguage == null ? null : tempInjectedLanguage.getLanguage(); final PsiFile finalContainingFile = containingFile; - InjectionProcessor injectionProcessor = new InjectionProcessor(myConfiguration, operands) { + InjectionProcessor injectionProcessor = new InjectionProcessor(myConfiguration, mySupport, operands) { @Override protected void processInjection(Language language, List> list, @@ -162,7 +162,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { } }; if (tempLanguage != null) { - BaseInjection baseInjection = new BaseInjection(LanguageInjectionSupport.JAVA_SUPPORT_ID); + BaseInjection baseInjection = new BaseInjection(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); baseInjection.setInjectedLanguageId(tempInjectedLanguage.getID()); injectionProcessor.processInjectionInner(baseInjection, false); InjectorUtils.putInjectedFileUserData(registrar, LanguageInjectionSupport.TEMPORARY_INJECTED_LANGUAGE, tempInjectedLanguage); @@ -175,12 +175,14 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { public static class InjectionProcessor { private final Configuration myConfiguration; + private final LanguageInjectionSupport mySupport; private final PsiElement[] myOperands; private boolean myShouldStop; private boolean myUnparsable; - public InjectionProcessor(Configuration configuration, PsiElement... operands) { + public InjectionProcessor(Configuration configuration, LanguageInjectionSupport support, PsiElement... operands) { myConfiguration = configuration; + mySupport = support; myOperands = operands; } @@ -301,11 +303,11 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { } private boolean processCommentInjections(PsiVariable owner) { - Ref causeRef = Ref.create(); + Ref causeRef = Ref.create(); PsiElement anchor = owner.getFirstChild() instanceof PsiComment? (owner.getModifierList() != null? owner.getModifierList() : owner.getTypeElement()) : owner; if (anchor == null) return true; - BaseInjection injection = InjectorUtils.findCommentInjection(anchor, LanguageInjectionSupport.JAVA_SUPPORT_ID, causeRef); + BaseInjection injection = mySupport.findCommentInjection(anchor, causeRef); return injection == null || processCommentInjectionInner(owner, causeRef.get(), injection); } @@ -351,7 +353,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector { final String id = AnnotationUtilEx.calcAnnotationValue(annotations, "value"); final String prefix = AnnotationUtilEx.calcAnnotationValue(annotations, "prefix"); final String suffix = AnnotationUtilEx.calcAnnotationValue(annotations, "suffix"); - final BaseInjection injection = new BaseInjection(LanguageInjectionSupport.JAVA_SUPPORT_ID); + final BaseInjection injection = new BaseInjection(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID); if (prefix != null) injection.setPrefix(prefix); if (suffix != null) injection.setSuffix(suffix); if (id != null) injection.setInjectedLanguageId(id); diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java index 70843dbd4763..7bf11d2cdb65 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java @@ -61,6 +61,7 @@ import org.intellij.plugins.intelliLang.inject.config.ui.configurables.MethodPar import org.intellij.plugins.intelliLang.util.ContextComputationProcessor; import org.intellij.plugins.intelliLang.util.PsiUtilEx; import org.jdom.Element; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -75,6 +76,8 @@ import static org.intellij.plugins.intelliLang.inject.config.MethodParameterInje */ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSupport { + @NonNls public static final String JAVA_SUPPORT_ID = "java"; + private static boolean isMine(final PsiLanguageInjectionHost psiElement) { return PsiUtilEx.isStringOrCharacterLiteral(psiElement); } @@ -93,6 +96,11 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo return new Configurable[]{new AdvancedSettingsUI(project, configuration)}; } + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return host instanceof PsiLiteralExpression; + } + public boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement) { if (!isMine(psiElement)) return false; return doInjectInJava(psiElement.getProject(), psiElement, language.getID()); @@ -105,7 +113,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo final PsiLiteralExpression host = (PsiLiteralExpression)psiElement; final Project project = host.getProject(); final Configuration configuration = Configuration.getProjectInstance(project); - collectInjections(host, configuration, injectionsMap, annotations); + collectInjections(host, configuration, this, injectionsMap, annotations); if (injectionsMap.isEmpty() && annotations.isEmpty()) return false; final ArrayList originalInjections = new ArrayList(injectionsMap.keySet()); @@ -129,7 +137,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo final PsiLiteralExpression host = (PsiLiteralExpression)psiElement; final Project project = host.getProject(); final Configuration configuration = Configuration.getProjectInstance(project); - collectInjections(host, configuration, injectionsMap, annotations); + collectInjections(host, configuration, this, injectionsMap, annotations); if (injectionsMap.isEmpty() || !annotations.isEmpty()) return false; final BaseInjection originalInjection = injectionsMap.keySet().iterator().next(); @@ -146,7 +154,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } - private BaseInjection showInjectionUI(final Project project, final MethodParameterInjection methodParameterInjection) { + private static BaseInjection showInjectionUI(final Project project, final MethodParameterInjection methodParameterInjection) { final AbstractInjectionPanel panel = new MethodParameterPanel(methodParameterInjection, project); panel.reset(); final DialogBuilder builder = new DialogBuilder(project); @@ -343,10 +351,12 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } } - private static void collectInjections(final PsiLiteralExpression host, final Configuration configuration, + private static void collectInjections(PsiLiteralExpression host, + Configuration configuration, + JavaLanguageInjectionSupport support, final HashMap> injectionsMap, final ArrayList annotations) { - new ConcatenationInjector.InjectionProcessor(configuration, host) { + new ConcatenationInjector.InjectionProcessor(configuration, support, host) { @Override protected boolean processCommentInjectionInner(PsiVariable owner, PsiElement comment, BaseInjection injection) { diff --git a/plugins/IntelliLang/src/META-INF/plugin.xml b/plugins/IntelliLang/src/META-INF/plugin.xml index a7bc30e9fc9b..59b3948cc0c4 100644 --- a/plugins/IntelliLang/src/META-INF/plugin.xml +++ b/plugins/IntelliLang/src/META-INF/plugin.xml @@ -16,7 +16,6 @@ - @@ -51,11 +50,10 @@ - - - - + diff --git a/plugins/IntelliLang/src/inspectionDescriptions/InjectedReferences.html b/plugins/IntelliLang/src/inspectionDescriptions/InjectedReferences.html new file mode 100644 index 000000000000..ee9e97976427 --- /dev/null +++ b/plugins/IntelliLang/src/inspectionDescriptions/InjectedReferences.html @@ -0,0 +1,5 @@ + + +Checks references injected by IntelliLang plugin. + + \ No newline at end of file diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java index 867833638a08..821284f9abc9 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java @@ -186,14 +186,10 @@ public class Configuration implements PersistentStateComponent, Modific @NonNls public static final String COMPONENT_NAME = "LanguageInjectionConfiguration"; // element names - @NonNls private static final String TAG_INJECTION_NAME = "TAGS"; - @NonNls private static final String ATTRIBUTE_INJECTION_NAME = "ATTRIBUTES"; - @NonNls private static final String PARAMETER_INJECTION_NAME = "PARAMETERS"; @NonNls private static final String INSTRUMENTATION_TYPE_NAME = "INSTRUMENTATION"; @NonNls private static final String LANGUAGE_ANNOTATION_NAME = "LANGUAGE_ANNOTATION"; @NonNls private static final String PATTERN_ANNOTATION_NAME = "PATTERN_ANNOTATION"; @NonNls private static final String SUBST_ANNOTATION_NAME = "SUBST_ANNOTATION"; - @NonNls private static final String ENTRY_NAME = "entry"; @NonNls private static final String RESOLVE_REFERENCES = "RESOLVE_REFERENCES"; @NonNls private static final String LOOK_FOR_VAR_ASSIGNMENTS = "LOOK_FOR_VAR_ASSIGNMENTS"; @NonNls private static final String USE_DFA_IF_AVAILABLE = "USE_DFA_IF_AVAILABLE"; @@ -242,7 +238,6 @@ public class Configuration implements PersistentStateComponent, Modific for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) { supports.put(support.getId(), support); } - loadStateOld(element, supports.get(LanguageInjectionSupport.XML_SUPPORT_ID), supports.get(LanguageInjectionSupport.JAVA_SUPPORT_ID)); for (Element child : element.getChildren("injection")){ final String key = child.getAttributeValue("injector-id"); final LanguageInjectionSupport support = supports.get(key); @@ -268,31 +263,6 @@ public class Configuration implements PersistentStateComponent, Modific return places.length != 0 && result.length == 0? null : result; } - private void loadStateOld(Element element, final LanguageInjectionSupport xmlSupport, final LanguageInjectionSupport javaSupport) { - if (xmlSupport != null) { - final Element xmlTagMarker = new Element("XmlTagInjection"); - myInjections.get(LanguageInjectionSupport.XML_SUPPORT_ID).addAll(readExternal(element.getChild(TAG_INJECTION_NAME), new Factory() { - public BaseInjection create() { - return xmlSupport.createInjection(xmlTagMarker); - } - })); - final Element xmlAttributeMarker = new Element("XmlAttributeInjection"); - myInjections.get(LanguageInjectionSupport.XML_SUPPORT_ID).addAll(readExternal(element.getChild(ATTRIBUTE_INJECTION_NAME), new Factory() { - public BaseInjection create() { - return xmlSupport.createInjection(xmlAttributeMarker); - } - })); - } - if (javaSupport != null) { - final Element javaMethodMarker = new Element("MethodParameterInjection"); - myInjections.get(LanguageInjectionSupport.JAVA_SUPPORT_ID).addAll(readExternal(element.getChild(PARAMETER_INJECTION_NAME), new Factory() { - public BaseInjection create() { - return javaSupport.createInjection(javaMethodMarker); - } - })); - } - } - private static boolean readBoolean(Element element, String key, boolean defValue) { final String value = JDOMExternalizerUtil.readField(element, key); if (value == null) return defValue; @@ -361,20 +331,6 @@ public class Configuration implements PersistentStateComponent, Modific return element; } - @SuppressWarnings({"unchecked"}) - private static List readExternal(Element element, Factory factory) { - final List injections = new ArrayList(); - if (element != null) { - final List list = element.getChildren(ENTRY_NAME); - for (Element entry : list) { - final T o = factory.create(); - o.loadState(entry); - injections.add(o); - } - } - return injections; - } - public static Configuration getInstance() { return ServiceManager.getService(Configuration.class); } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java index ed8dead6c460..24a8730b24e0 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java @@ -55,7 +55,7 @@ import org.intellij.plugins.intelliLang.inject.InjectorUtils; import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.intellij.plugins.intelliLang.inject.config.InjectionPlace; -import org.intellij.plugins.intelliLang.references.ReferenceInjector; +import com.intellij.psi.injection.ReferenceInjector; import org.jdom.Document; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java index 68869a4eb445..bcfd9c5c2b8a 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java @@ -16,6 +16,7 @@ package org.intellij.plugins.intelliLang.inject; +import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.fileTypes.FileTypeManager; @@ -25,6 +26,7 @@ import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; @@ -35,6 +37,7 @@ import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.intellij.plugins.intelliLang.inject.config.ui.BaseInjectionPanel; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -44,7 +47,22 @@ import javax.swing.*; */ public abstract class AbstractLanguageInjectionSupport extends LanguageInjectionSupport { - public boolean useDefaultInjector(final PsiElement host) { + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return useDefaultInjector(host); // todo temporary plugin compatibility fix. TBR + } + + public boolean useDefaultInjector(final PsiLanguageInjectionHost host) { + return false; + } + + @Nullable + @Override + public BaseInjection findCommentInjection(@NotNull PsiElement host, @Nullable Ref commentRef) { + return InjectorUtils.findCommentInjection(host, "comment", commentRef); + } + + public boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement) { return false; } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java index 1bbc1e40b1f2..1869f1f6e63c 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/CommentLanguageInjector.java @@ -1,15 +1,15 @@ package org.intellij.plugins.intelliLang.inject; -import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostInjector; import com.intellij.lang.injection.MultiHostRegistrar; -import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.Trinity; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.util.ArrayUtil; +import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -18,29 +18,53 @@ import java.util.List; */ public class CommentLanguageInjector implements MultiHostInjector { + private final LanguageInjectionSupport[] mySupports; + private final LanguageInjectionSupport myInjectorSupport = new AbstractLanguageInjectionSupport() { + @NotNull + @Override + public String getId() { + return "comment"; + } + + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return true; + } + + @NotNull + @Override + public Class[] getPatternClasses() { + return ArrayUtil.EMPTY_CLASS_ARRAY; + } + }; + + + /** @noinspection UnusedParameters*/ + public CommentLanguageInjector(Configuration configuration) { + List supports = new ArrayList(InjectorUtils.getActiveInjectionSupports()); + supports.add(myInjectorSupport); + mySupports = ArrayUtil.toObjectArray(supports, LanguageInjectionSupport.class); + } + @NotNull public List> elementsToInjectIn() { return Collections.singletonList(PsiLanguageInjectionHost.class); } public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + if (!(context instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost)context).isValidHost()) return; PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; - if (!host.isValidHost()) return; - if (context.getClass().getSimpleName().startsWith("XmlAttribute")) return; // no injection in XML attributes, they cannot be commented - ElementManipulator manipulator = ElementManipulators.getManipulator(host); - if (manipulator == null) return; - TextRange rangeInElement = manipulator.getRangeInElement(host); - if (rangeInElement.isEmpty()) return; - PsiElement anchor = rangeInElement.getStartOffset() == 0 ? context.getParent() : context; // handle XmlText - BaseInjection injection = InjectorUtils.findCommentInjection(anchor, "comment", Ref.create()); - //BaseInjection injection = InjectorUtils.findCommentInjection(context, "comment", Ref.create()); - if (injection == null) return; - InjectedLanguage injectedLanguage = InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false); - Language language = injectedLanguage != null ? injectedLanguage.getLanguage() : null; - if (language != null) { - Trinity info = - Trinity.create(host, injectedLanguage, rangeInElement); - InjectorUtils.registerInjection(language, Collections.singletonList(info), context.getContainingFile(), registrar); + + boolean applicableFound = false; + for (LanguageInjectionSupport support : mySupports) { + if (!support.isApplicableTo(host)) continue; + if (support == myInjectorSupport && applicableFound) continue; + applicableFound = true; + + BaseInjection injection = support.findCommentInjection(host, null); + if (injection == null) continue; + if (!InjectorUtils.registerInjectionSimple(host, injection, support, registrar)) continue; + return; } } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java index 1847cd26e274..f95bea6947f2 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/DefaultLanguageInjector.java @@ -16,11 +16,8 @@ package org.intellij.plugins.intelliLang.inject; -import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostInjector; import com.intellij.lang.injection.MultiHostRegistrar; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.Trinity; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.util.ArrayUtil; @@ -28,7 +25,6 @@ import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -47,30 +43,18 @@ public final class DefaultLanguageInjector implements MultiHostInjector { return Collections.singletonList(PsiLanguageInjectionHost.class); } - public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement host) { + public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + if (!(context instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost)context).isValidHost()) return; + PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; + for (LanguageInjectionSupport support : mySupports) { + if (!support.isApplicableTo(host)) continue; if (!support.useDefaultInjector(host)) continue; + for (BaseInjection injection : myInjectionConfiguration.getInjections(support.getId())) { - if (injection.acceptsPsiElement(host)) { - final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); - if (language == null) continue; - - final InjectedLanguage injectedLanguage = - InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false); - - List ranges = injection.getInjectedArea(host); - final List> list = - new ArrayList>(ranges.size()); - for (TextRange range : ranges) { - list.add(Trinity.create((PsiLanguageInjectionHost)host, injectedLanguage, range)); - } - //if (host.getChildren().length > 0) { - // host.putUserData(LanguageInjectionSupport.HAS_UNPARSABLE_FRAGMENTS, Boolean.TRUE); - //} - InjectorUtils.registerInjection(language, list, host.getContainingFile(), registrar); - InjectorUtils.registerSupport(support, true, registrar); - break; - } + if (!injection.acceptsPsiElement(host)) continue; + if (!InjectorUtils.registerInjectionSimple(host, injection, support, registrar)) continue; + return; } } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java index 20b6b05b92ab..6ff3d9856996 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java @@ -15,39 +15,66 @@ */ package org.intellij.plugins.intelliLang.inject; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.injected.editor.EditorWindow; +import com.intellij.lang.Language; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.PopupChooserBuilder; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiLanguageInjectionHost; +import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiModificationTrackerImpl; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.ui.ColoredListCellRendererWrapper; +import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.components.JBList; import com.intellij.util.FileContentUtil; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; +import com.intellij.util.containers.ContainerUtil; import org.intellij.plugins.intelliLang.Configuration; -import org.intellij.plugins.intelliLang.references.Injectable; +import com.intellij.psi.injection.Injectable; import org.intellij.plugins.intelliLang.references.InjectedReferencesContributor; +import com.intellij.psi.injection.ReferenceInjector; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; public class InjectLanguageAction implements IntentionAction { @NonNls private static final String INJECT_LANGUAGE_FAMILY = "Inject Language/Reference"; + public static final String LAST_INJECTED_LANGUAGE = "LAST_INJECTED_LANGUAGE"; + + public static List getAllInjectables() { + Language[] languages = InjectedLanguage.getAvailableLanguages(); + List list = new ArrayList(); + for (Language language : languages) { + list.add(Injectable.fromLanguage(language)); + } + list.addAll(Arrays.asList(ReferenceInjector.EXTENSION_POINT_NAME.getExtensions())); + Collections.sort(list); + return list; + } @NotNull public String getText() { @@ -99,18 +126,24 @@ public class InjectLanguageAction implements IntentionAction { if (defaultFunctionalityWorked(host, injectable.getId())) return; try { + Language language = injectable.toLanguage(); for (LanguageInjectionSupport support : InjectorUtils.getActiveInjectionSupports()) { - if (support.addInjectionInPlace(injectable, host)) { - ((PsiModificationTrackerImpl)PsiManager.getInstance(project).getModificationTracker()).incCounter(); + if (support.isApplicableTo(host) && support.addInjectionInPlace(language, host)) { return; } } - TemporaryPlacesRegistry.getInstance(project).getLanguageInjectionSupport().addInjectionInPlace(injectable, host); + if (TemporaryPlacesRegistry.getInstance(project).getLanguageInjectionSupport().addInjectionInPlace(language, host)) { + HintManager.getInstance().showInformationHint(editor, StringUtil.escapeXml(language.getDisplayName()) + " was temporarily injected"); + } } finally { if (injectable.getLanguage() != null) { // no need for reference injection FileContentUtil.reparseFiles(project, Collections.emptyList(), true); } + else { + ((PsiModificationTrackerImpl)PsiManager.getInstance(project).getModificationTracker()).incCounter(); + DaemonCodeAnalyzer.getInstance(project).restart(); + } } } @@ -119,27 +152,43 @@ public class InjectLanguageAction implements IntentionAction { } private static boolean doChooseLanguageToInject(Editor editor, final Processor onChosen) { - final List injectables = Injectable.getAllInjectables(); + final List injectables = getAllInjectables(); final JList list = new JBList(injectables); - list.setCellRenderer(new ListCellRendererWrapper() { + list.setCellRenderer(new ColoredListCellRendererWrapper() { @Override - public void customize(JList list, Injectable language, int index, boolean selected, boolean hasFocus) { + protected void doCustomize(JList list, Injectable language, int index, boolean selected, boolean hasFocus) { setIcon(language.getIcon()); - setText(language.getDisplayName()); + append(language.getDisplayName()); + String description = language.getAdditionalDescription(); + if (description != null) { + append(description, SimpleTextAttributes.GRAYED_ATTRIBUTES); + } } }); - new PopupChooserBuilder(list).setItemChoosenCallback(new Runnable() { + JBPopup popup = new PopupChooserBuilder(list).setItemChoosenCallback(new Runnable() { public void run() { - onChosen.process((Injectable)list.getSelectedValue()); + Injectable value = (Injectable)list.getSelectedValue(); + onChosen.process(value); + PropertiesComponent.getInstance().setValue(LAST_INJECTED_LANGUAGE, value.getId()); } }).setFilteringEnabled(new Function() { @Override public String fun(Object language) { return ((Injectable)language).getDisplayName(); } - }) - .createPopup().showInBestPositionFor(editor); + }).createPopup(); + final String lastInjected = PropertiesComponent.getInstance().getValue(LAST_INJECTED_LANGUAGE); + if (lastInjected != null) { + Injectable injectable = ContainerUtil.find(injectables, new Condition() { + @Override + public boolean value(Injectable injectable) { + return lastInjected.equals(injectable.getId()); + } + }); + list.setSelectedValue(injectable, true); + } + popup.showInBestPositionFor(editor); return true; } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java index 5615e7a396bc..01a76297235d 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectorUtils.java @@ -16,10 +16,8 @@ package org.intellij.plugins.intelliLang.inject; -import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostRegistrar; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; @@ -59,6 +57,32 @@ public class InjectorUtils { } + public static boolean registerInjectionSimple(@NotNull PsiLanguageInjectionHost host, + @NotNull BaseInjection injection, + @Nullable LanguageInjectionSupport support, + @NotNull MultiHostRegistrar registrar) { + Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + if (language == null) return false; + + InjectedLanguage injectedLanguage = + InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false); + + List ranges = injection.getInjectedArea(host); + List> list = ContainerUtil.newArrayListWithExpectedSize(ranges.size()); + + for (TextRange range : ranges) { + list.add(Trinity.create(host, injectedLanguage, range)); + } + //if (host.getChildren().length > 0) { + // host.putUserData(LanguageInjectionSupport.HAS_UNPARSABLE_FRAGMENTS, Boolean.TRUE); + //} + registerInjection(language, list, host.getContainingFile(), registrar); + if (support != null) { + registerSupport(support, true, registrar); + } + return !ranges.isEmpty(); + } + public static void registerInjection(Language language, List> list, PsiFile containingFile, MultiHostRegistrar registrar) { // if language isn't injected when length == 0, subsequent edits will not cause the language to be injected as well. // Maybe IDEA core is caching a bit too aggressively here? @@ -196,12 +220,12 @@ public class InjectorUtils { return true; } - public static BaseInjection findCommentInjection(PsiElement context, final String supportId, final Ref causeRef) { + public static BaseInjection findCommentInjection(PsiElement context, final String supportId, final Ref causeRef) { return findNearestComment(context, new NullableFunction() { @Nullable @Override public BaseInjection fun(PsiComment comment) { - causeRef.set(comment); + if (causeRef != null) causeRef.set(comment); String text = ElementManipulators.getValueText(comment).trim(); return detectInjectionFromText(supportId, text); } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java index 17b704b7521d..77e875359e4c 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionSupport.java @@ -22,16 +22,17 @@ import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Factory; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.ui.SimpleColoredText; import com.intellij.util.Consumer; import org.intellij.plugins.intelliLang.Configuration; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; -import org.intellij.plugins.intelliLang.references.Injectable; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Gregory.Shrago @@ -45,9 +46,6 @@ public abstract class LanguageInjectionSupport { public static Key INJECTOR_SUPPORT = Key.create("INJECTOR_SUPPORT"); public static Key SETTINGS_EDITOR = Key.create("SETTINGS_EDITOR"); - @NonNls public static final String XML_SUPPORT_ID = "xml"; - @NonNls public static final String JAVA_SUPPORT_ID = "java"; - @NonNls @NotNull public abstract String getId(); @@ -55,24 +53,14 @@ public abstract class LanguageInjectionSupport { @NotNull public abstract Class[] getPatternClasses(); - public abstract boolean useDefaultInjector(final PsiElement host); + public abstract boolean isApplicableTo(PsiLanguageInjectionHost host); - public boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement) { - return addInjectionInPlace(language.getID(), psiElement); - } + public abstract boolean useDefaultInjector(PsiLanguageInjectionHost host); - public boolean addInjectionInPlace(final String id, final PsiLanguageInjectionHost psiElement) { - return false; - } + @Nullable + public abstract BaseInjection findCommentInjection(@NotNull PsiElement host, @Nullable Ref commentRef); - public final boolean addInjectionInPlace(final Injectable injectable, final PsiLanguageInjectionHost psiElement) { - if (injectable.getLanguage() == null) { - return addInjectionInPlace(injectable.getId(), psiElement); - } - else { - return addInjectionInPlace(injectable.getLanguage(), psiElement); - } - } + public abstract boolean addInjectionInPlace(final Language language, final PsiLanguageInjectionHost psiElement); public abstract boolean removeInjectionInPlace(final PsiLanguageInjectionHost psiElement); diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java index b725eaa8eb43..5139768499e1 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesInjector.java @@ -47,18 +47,20 @@ public class TemporaryPlacesInjector implements MultiHostInjector { } public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement context) { + if (!(context instanceof PsiLanguageInjectionHost) || !((PsiLanguageInjectionHost)context).isValidHost()) return; PsiLanguageInjectionHost host = (PsiLanguageInjectionHost)context; + PsiFile containingFile = context.getContainingFile(); InjectedLanguage injectedLanguage = myRegistry.getLanguageFor(host, containingFile); Language language = injectedLanguage != null ? injectedLanguage.getLanguage() : null; - if (language != null) { - final ElementManipulator manipulator = ElementManipulators.getManipulator(host); - if (manipulator == null) return; - List> trinities = - Collections.singletonList(Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host))); - InjectorUtils.registerInjection(language, trinities, containingFile, registrar); - InjectorUtils.registerSupport(myRegistry.getLanguageInjectionSupport(), false, registrar); - } + if (language == null) return; + + final ElementManipulator manipulator = ElementManipulators.getManipulator(host); + if (manipulator == null) return; + List> trinities = + Collections.singletonList(Trinity.create(host, injectedLanguage, manipulator.getRangeInElement(host))); + InjectorUtils.registerInjection(language, trinities, containingFile, registrar); + InjectorUtils.registerSupport(myRegistry.getLanguageInjectionSupport(), false, registrar); } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java index eaf14241183e..56d1e9863320 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/TemporaryPlacesRegistry.java @@ -50,6 +50,11 @@ public class TemporaryPlacesRegistry { return "temp"; } + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return true; + } + @NotNull @Override public Class[] getPatternClasses() { diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/FileReferenceInjector.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/FileReferenceInjector.java index 1b28df2208dc..d5d4cc813eab 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/FileReferenceInjector.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/FileReferenceInjector.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; +import com.intellij.psi.injection.ReferenceInjector; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; @@ -44,6 +45,11 @@ public class FileReferenceInjector extends ReferenceInjector { @Override public PsiReference[] getReferences(@NotNull PsiElement element, @NotNull ProcessingContext context, @NotNull TextRange range) { String text = range.substring(element.getText()); - return new FileReferenceSet(text, element, range.getStartOffset(), null, true).getAllReferences(); + return new FileReferenceSet(text, element, range.getStartOffset(), null, true) { + @Override + protected boolean isSoft() { + return true; + } + }.getAllReferences(); } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java index dfcc403378f1..69d781992881 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java @@ -19,11 +19,14 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.*; +import com.intellij.psi.injection.ReferenceInjector; import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; import org.intellij.plugins.intelliLang.Configuration; +import org.intellij.plugins.intelliLang.inject.InjectedLanguage; import org.intellij.plugins.intelliLang.inject.InjectorUtils; import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; +import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,10 +40,15 @@ import java.util.List; */ public class InjectedReferencesContributor extends PsiReferenceContributor { - private static final Key INJECTED_REFERENCE = Key.create("injected reference"); + private static final Key INJECTED_REFERENCES = Key.create("injected references"); public static boolean isInjected(@Nullable PsiReference reference) { - return reference != null && reference.getElement().getUserData(INJECTED_REFERENCE) != null; + return reference != null && reference.getElement().getUserData(INJECTED_REFERENCES) != null; + } + + @Nullable + public static PsiReference[] getInjectedReferences(PsiElement element) { + return element.getUserData(INJECTED_REFERENCES); } @Override @@ -49,24 +57,38 @@ public class InjectedReferencesContributor extends PsiReferenceContributor { @NotNull @Override public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { - element.putUserData(INJECTED_REFERENCE, null); ReferenceInjector[] extensions = ReferenceInjector.EXTENSION_POINT_NAME.getExtensions(); PsiReference[] references = new PsiReference[0]; Configuration configuration = Configuration.getProjectInstance(element.getProject()); - for (ReferenceInjector extension : extensions) { - Collection injections = configuration.getInjectionsByLanguageId(extension.getId()); + boolean injected = false; + for (ReferenceInjector injector : extensions) { + Collection injections = configuration.getInjectionsByLanguageId(injector.getId()); for (BaseInjection injection : injections) { if (injection.acceptForReference(element)) { - element.putUserData(INJECTED_REFERENCE, extension); + injected = true; LanguageInjectionSupport support = InjectorUtils.findInjectionSupport(injection.getSupportId()); element.putUserData(LanguageInjectionSupport.INJECTOR_SUPPORT, support); List area = injection.getInjectedArea(element); for (TextRange range : area) { - references = ArrayUtil.mergeArrays(references, extension.getReferences(element, context, range)); + references = ArrayUtil.mergeArrays(references, injector.getReferences(element, context, range)); } } } } + if (element instanceof PsiLanguageInjectionHost) { + TemporaryPlacesRegistry registry = TemporaryPlacesRegistry.getInstance(element.getProject()); + InjectedLanguage language = registry.getLanguageFor((PsiLanguageInjectionHost)element, element.getContainingFile()); + if (language != null) { + ReferenceInjector injector = ReferenceInjector.findById(language.getID()); + if (injector != null) { + injected = true; + element.putUserData(LanguageInjectionSupport.INJECTOR_SUPPORT, registry.getLanguageInjectionSupport()); + TextRange range = ElementManipulators.getValueTextRange(element); + references = ArrayUtil.mergeArrays(references, injector.getReferences(element, context, range)); + } + } + } + element.putUserData(INJECTED_REFERENCES, injected ? references : null); return references; } }); diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesInspection.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesInspection.java new file mode 100644 index 000000000000..1f8f68249bb5 --- /dev/null +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesInspection.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.plugins.intelliLang.references; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Avdeev + * Date: 05.08.13 + */ +public class InjectedReferencesInspection extends LocalInspectionTool { + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { + return new PsiElementVisitor() { + @Override + public void visitElement(PsiElement element) { + + PsiReference[] injected = InjectedReferencesContributor.getInjectedReferences(element); + if (injected != null) { + for (PsiReference reference : injected) { + if (reference.resolve() == null) { + holder.registerProblem(reference); + } + } + } + + super.visitElement(element); + } + }; + } +} diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java index 71021f5eaa8a..0662837d0574 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java @@ -23,7 +23,7 @@ import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlTag; -import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; +import org.intellij.plugins.intelliLang.inject.xml.XmlLanguageInjectionSupport; import org.intellij.plugins.intelliLang.util.StringMatcher; import org.jaxen.JaxenException; import org.jaxen.XPath; @@ -60,7 +60,7 @@ public class AbstractTagInjection extends BaseInjection { private boolean myApplyToSubTagTexts; public AbstractTagInjection() { - super(LanguageInjectionSupport.XML_SUPPORT_ID); + super(XmlLanguageInjectionSupport.XML_SUPPORT_ID); } @NotNull diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java index 094bcfd2a562..6c84a879b1a6 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java @@ -16,6 +16,7 @@ package org.intellij.plugins.intelliLang.inject.xml; +import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.Configurable; @@ -23,15 +24,13 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.*; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlText; +import com.intellij.psi.xml.*; import com.intellij.util.Consumer; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; @@ -47,6 +46,7 @@ import org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel; import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlAttributeInjectionConfigurable; import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlTagInjectionConfigurable; import org.jdom.Element; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,6 +59,8 @@ import java.util.Collections; */ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSupport { + @NonNls public static final String XML_SUPPORT_ID = "xml"; + private static boolean isMine(final PsiLanguageInjectionHost host) { if (host instanceof XmlAttributeValue) { final PsiElement p = host.getParent(); @@ -84,12 +86,22 @@ public class XmlLanguageInjectionSupport extends AbstractLanguageInjectionSuppor return new Class[] {XmlPatterns.class}; } - public boolean useDefaultInjector(final PsiElement host) { - return false; + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { + return host instanceof XmlElement; } - public boolean addInjectionInPlace(final String id, final PsiLanguageInjectionHost psiElement) { + @Nullable + @Override + public BaseInjection findCommentInjection(@NotNull PsiElement host, @Nullable Ref commentRef) { + if (host instanceof XmlAttributeValue) return null; + return InjectorUtils.findCommentInjection(host instanceof XmlText ? host.getParent() : host, getId(), commentRef); + } + + @Override + public boolean addInjectionInPlace(Language language, final PsiLanguageInjectionHost psiElement) { if (!isMine(psiElement)) return false; + String id = language.getID(); if (psiElement instanceof XmlAttributeValue) { return doInjectInAttributeValue((XmlAttributeValue)psiElement, id); } diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java index a05a24426dc9..f8026edb4f11 100644 --- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java +++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java @@ -63,7 +63,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { public XmlLanguageInjector(Configuration configuration) { myConfiguration = configuration; - mySupport = InjectorUtils.findNotNullInjectionSupport(LanguageInjectionSupport.XML_SUPPORT_ID); + mySupport = InjectorUtils.findNotNullInjectionSupport(XmlLanguageInjectionSupport.XML_SUPPORT_ID); } @NotNull @@ -104,7 +104,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { if (place instanceof XmlTag) { final XmlTag xmlTag = (XmlTag)place; - List injections = myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID); + List injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID); //noinspection ForLoopReplaceableByForEach for (int i = 0, injectionsSize = injections.size(); i < injectionsSize; i++) { final BaseInjection injection = injections.get(i); @@ -168,7 +168,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { return; } - List injections = myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID); + List injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID); //noinspection ForLoopReplaceableByForEach for (int i = 0, size = injections.size(); i < size; i++) { BaseInjection injection = injections.get(i); @@ -236,7 +236,7 @@ public final class XmlLanguageInjector implements MultiHostInjector { Trinity> index = myXmlIndex; if (index == null || myConfiguration.getModificationCount() != index.first.longValue()) { final Map, BaseInjection> map = new THashMap, BaseInjection>(); - for (BaseInjection injection : myConfiguration.getInjections(LanguageInjectionSupport.XML_SUPPORT_ID)) { + for (BaseInjection injection : myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID)) { for (InjectionPlace place : injection.getInjectionPlaces()) { if (!place.isEnabled() || place.getElementPattern() == null) continue; map.put(place.getElementPattern(), injection); diff --git a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java index fadba7dabc25..ba075a6ebe89 100644 --- a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java +++ b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java @@ -19,6 +19,7 @@ import com.intellij.dvcs.DvcsUtil; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -159,8 +160,13 @@ class GitMergeOperation extends GitBranchOperation { switch (myDeleteOnMerge) { case DELETE: super.notifySuccess(message); - GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class); - brancher.deleteBranch(myBranchToMerge, new ArrayList(getRepositories())); + ApplicationManager.getApplication().invokeLater(new Runnable() { // bg process needs to be started from the EDT + @Override + public void run() { + GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class); + brancher.deleteBranch(myBranchToMerge, new ArrayList(getRepositories())); + } + }); break; case PROPOSE: String description = message + "
Delete " + myBranchToMerge + ""; diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java index f7ebeea68768..a7b798c6df2e 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java @@ -26,6 +26,8 @@ import com.intellij.packaging.artifacts.ArtifactPointerManager; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.deployment.*; import com.intellij.remoteServer.runtime.ServerConnector; +import com.intellij.remoteServer.runtime.ServerTaskExecutor; +import com.intellij.remoteServer.runtime.deployment.DeploymentTask; import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; import com.intellij.util.ui.FormBuilder; import icons.GoogleAppEngineIcons; @@ -36,7 +38,6 @@ import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executor; /** * @author nik @@ -74,9 +75,8 @@ public class AppEngineCloudType extends ServerType @NotNull @Override public ServerConnector createConnector(@NotNull AppEngineServerConfiguration configuration, - @NotNull Project project, - @NotNull Executor asyncTasksExecutor) { - return new AppEngineServerConnector(project, configuration); + @NotNull ServerTaskExecutor asyncTasksExecutor) { + return new AppEngineServerConnector(configuration); } @NotNull @@ -153,40 +153,43 @@ public class AppEngineCloudType extends ServerType } private static class AppEngineServerConnector extends ServerConnector { - private final Project myProject; private final AppEngineServerConfiguration myConfiguration; - public AppEngineServerConnector(Project project, AppEngineServerConfiguration configuration) { - myProject = project; + public AppEngineServerConnector(AppEngineServerConfiguration configuration) { myConfiguration = configuration; } @Override - public void connect(@NotNull ConnectionCallback callback) { - callback.connected(new ServerRuntimeInstance() { - @Override - public void deploy(@NotNull DeploymentSource source, - @NotNull DummyDeploymentConfiguration configuration, - @NotNull DeploymentOperationCallback callback) { - Artifact artifact = ((ArtifactDeploymentSource)source).getArtifact(); - if (artifact == null) return; - - AppEngineUploader uploader = AppEngineUploader.createUploader(myProject, artifact, myConfiguration); - if (uploader != null) { - uploader.startUploading(); - } - } - - @Override - public void undeploy(@NotNull DeploymentSource source, - @NotNull DummyDeploymentConfiguration configuration, - @NotNull DeploymentOperationCallback callback) { - } - }); + public void connect(@NotNull final ConnectionCallback callback) { + callback.connected(new AppEngineRuntimeInstance(myConfiguration)); } @Override public void disconnect() { } } + + private static class AppEngineRuntimeInstance extends ServerRuntimeInstance { + private final AppEngineServerConfiguration myConfiguration; + + public AppEngineRuntimeInstance(AppEngineServerConfiguration configuration) { + myConfiguration = configuration; + } + + @Override + public void deploy(@NotNull DeploymentTask task, @NotNull DeploymentOperationCallback callback) { + Artifact artifact = ((ArtifactDeploymentSource)task.getSource()).getArtifact(); + if (artifact == null) return; + + AppEngineUploader uploader = AppEngineUploader.createUploader(task.getProject(), artifact, myConfiguration); + if (uploader != null) { + uploader.startUploading(); + } + } + + @Override + public void undeploy(@NotNull DeploymentTask task, + @NotNull DeploymentOperationCallback callback) { + } + } } diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java index b83f706e9796..9125490442ee 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrConcatenationInjector.java @@ -15,16 +15,14 @@ */ package org.intellij.plugins.intelliLang.inject.groovy; -import com.intellij.lang.Language; import com.intellij.lang.injection.MultiHostInjector; import com.intellij.lang.injection.MultiHostRegistrar; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import org.intellij.plugins.intelliLang.Configuration; -import org.intellij.plugins.intelliLang.inject.InjectedLanguage; import org.intellij.plugins.intelliLang.inject.InjectorUtils; +import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport; import org.intellij.plugins.intelliLang.inject.config.BaseInjection; import org.intellij.plugins.intelliLang.util.AnnotationUtilEx; import org.intellij.plugins.intelliLang.util.PsiUtilEx; @@ -94,23 +92,14 @@ public class GrConcatenationInjector implements MultiHostInjector { final PsiAnnotation[] annotations = getAnnotationFrom(annotationOwner, pair, true, true); if (annotations.length > 0) { - final String id = AnnotationUtilEx.calcAnnotationValue(annotations, "value"); - final String prefix = AnnotationUtilEx.calcAnnotationValue(annotations, "prefix"); - final String suffix = AnnotationUtilEx.calcAnnotationValue(annotations, "suffix"); - final BaseInjection injection = new BaseInjection(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); - if (prefix != null) injection.setPrefix(prefix); - if (suffix != null) injection.setSuffix(suffix); - if (id != null) injection.setInjectedLanguageId(id); + BaseInjection injection = new BaseInjection(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); - //todo suffixes & prefixes are not supported - final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + injection.setPrefix(StringUtil.notNullize(AnnotationUtilEx.calcAnnotationValue(annotations, "prefix"))); + injection.setSuffix(StringUtil.notNullize(AnnotationUtilEx.calcAnnotationValue(annotations, "suffix"))); + injection.setInjectedLanguageId(StringUtil.notNullize(AnnotationUtilEx.calcAnnotationValue(annotations, "value"))); - Trinity info = Trinity.create( - host, - InjectedLanguage.create(injection.getInjectedLanguageId(), prefix, suffix, true), - ElementManipulators.getManipulator(host).getRangeInElement(host) - ); - InjectorUtils.registerInjection(language, Collections.singletonList(info), host.getContainingFile(), registrar); + LanguageInjectionSupport support = InjectorUtils.findInjectionSupport(GroovyLanguageInjectionSupport.GROOVY_SUPPORT_ID); + InjectorUtils.registerInjectionSimple(host, injection, support, registrar); } } diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java index 452bca159bd8..564677a2936f 100644 --- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java +++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GroovyLanguageInjectionSupport.java @@ -62,10 +62,15 @@ public class GroovyLanguageInjectionSupport extends AbstractLanguageInjectionSup return new Class[] {GroovyPatterns.class}; } - public boolean useDefaultInjector(final PsiElement host) { + @Override + public boolean isApplicableTo(PsiLanguageInjectionHost host) { return host instanceof GroovyPsiElement; } + public boolean useDefaultInjector(PsiLanguageInjectionHost host) { + return true; + } + @Override public String getHelpId() { return "reference.settings.language.injection.groovy"; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java index fd819c96978f..814a5f4c0973 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java @@ -53,30 +53,34 @@ public class SpringLoadedPositionManager implements PositionManager { @NotNull @Override public List getAllClasses(final SourcePosition classPosition) throws NoDataException { - AccessToken accessToken = ReadAction.start(); + int line; + String className; + AccessToken accessToken = ReadAction.start(); try { - String className = findEnclosingName(classPosition); + className = findEnclosingName(classPosition); if (className == null) throw new NoDataException(); - List referenceTypes = myDebugProcess.getVirtualMachineProxy().classesByName(className); - if (referenceTypes.isEmpty()) throw new NoDataException(); - - Set res = new HashSet(); - - for (ReferenceType referenceType : referenceTypes) { - findNested(res, referenceType, classPosition); - } - - if (res.isEmpty()) { - throw new NoDataException(); - } - - return new ArrayList(res); + line = classPosition.getLine(); } finally { accessToken.finish(); } + + List referenceTypes = myDebugProcess.getVirtualMachineProxy().classesByName(className); + if (referenceTypes.isEmpty()) throw new NoDataException(); + + Set res = new HashSet(); + + for (ReferenceType referenceType : referenceTypes) { + findNested(res, referenceType, line); + } + + if (res.isEmpty()) { + throw new NoDataException(); + } + + return new ArrayList(res); } @NotNull @@ -87,28 +91,18 @@ public class SpringLoadedPositionManager implements PositionManager { @Nullable private static String findEnclosingName(final SourcePosition position) { - AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock(); - - try { - PsiElement element = findElementAt(position); - while (true) { - element = PsiTreeUtil.getParentOfType(element, GrTypeDefinition.class, PsiClassImpl.class); - if (element == null - || (element instanceof GrTypeDefinition && !((GrTypeDefinition)element).isAnonymous()) - || (element instanceof PsiClassImpl && ((PsiClassImpl)element).getName() != null) - ) { - break; - } + PsiElement element = findElementAt(position); + while (true) { + element = PsiTreeUtil.getParentOfType(element, GrTypeDefinition.class, PsiClassImpl.class); + if (element == null + || (element instanceof GrTypeDefinition && !((GrTypeDefinition)element).isAnonymous()) + || (element instanceof PsiClassImpl && ((PsiClassImpl)element).getName() != null) + ) { + break; } + } - if (element != null) { - return getClassNameForJvm((PsiClass)element); - } - return null; - } - finally { - accessToken.finish(); - } + return null; } @Nullable @@ -167,7 +161,7 @@ public class SpringLoadedPositionManager implements PositionManager { && GENERATED_CLASS_NAME.matcher(name.substring(ownerClassName.length())).matches(); } - private static void findNested(Set res, ReferenceType fromClass, SourcePosition classPosition) { + private static void findNested(Set res, ReferenceType fromClass, int line) { if (!fromClass.isPrepared()) return; List nestedTypes = fromClass.nestedTypes(); @@ -183,12 +177,12 @@ public class SpringLoadedPositionManager implements PositionManager { } } else { - findNested(res, nested, classPosition); + findNested(res, nested, line); } } try { - final int lineNumber = classPosition.getLine() + 1; + final int lineNumber = line + 1; ReferenceType effectiveRef = springLoadedGeneratedClass == null ? fromClass : springLoadedGeneratedClass; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/FilePathUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/FilePathUtil.java index 374ec7f8733c..6a5c3cb0d7ab 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/FilePathUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/FilePathUtil.java @@ -32,7 +32,7 @@ public class FilePathUtil { public static boolean isNested(final Collection roots, final File root) { for (FilePath filePath : roots) { final File ioFile = filePath.getIOFile(); - if (ioFile.equals(root)) continue; + if (FileUtil.isAncestor(ioFile, root, true)) { return true; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateContext.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateContext.java index 033b0deb5b32..3da7e90ad98c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateContext.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateContext.java @@ -54,13 +54,24 @@ public class SvnUpdateContext implements SequentialUpdatesContext { } public boolean shouldRunFor(final File ioRoot) { - if (myUpdatedExternals.contains(ioRoot)) return false; - if (FilePathUtil.isNested(myContentRoots, ioRoot)) { + boolean result = true; + + if (myUpdatedExternals.contains(ioRoot)) { + result = false; + } + else if (FilePathUtil.isNested(myContentRoots, ioRoot)) { final RootUrlInfo info = myVcs.getSvnFileUrlMapping().getWcRootForFilePath(ioRoot); + if (info != null) { - return ! NestedCopyType.switched.equals(info.getType()); + if (NestedCopyType.switched.equals(info.getType())) { + result = false; + } + else if (NestedCopyType.external.equals(info.getType())) { + result = !myVcs.getSvnConfiguration().IGNORE_EXTERNALS; + } } } - return true; + + return result; } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form index 9ba9df6a2107..230271b9354c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form @@ -57,7 +57,7 @@ - + diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java index 906f27c19650..cdc20c5e5625 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java @@ -1,15 +1,18 @@ package com.intellij.tasks.actions; +import com.intellij.codeInsight.documentation.DocumentationManager; import com.intellij.ide.actions.GotoActionBase; import com.intellij.ide.util.gotoByName.ChooseByNameBase; import com.intellij.ide.util.gotoByName.ChooseByNameItemProvider; import com.intellij.ide.util.gotoByName.ChooseByNamePopup; import com.intellij.ide.util.gotoByName.SimpleChooseByNameModel; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiManager; import com.intellij.tasks.LocalTask; @@ -163,8 +166,10 @@ public class GotoTaskAction extends GotoActionBase implements DumbAware { }, null, popup); } - public static void showOpenTaskDialog(final Project project, final Task task) { - SwingUtilities.invokeLater(new Runnable() { + private static void showOpenTaskDialog(final Project project, final Task task) { + JBPopup hint = DocumentationManager.getInstance(project).getDocInfoHint(); + if (hint != null) hint.cancel(); + ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { new OpenTaskDialog(project, task).show(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java index eb1f903f50b7..8a9fd91d04ce 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java @@ -33,7 +33,7 @@ public class JiraRepository extends BaseRepositoryImpl { /** * Default JQL query */ - private String mySearchQuery = "assignee = currentUser() order by duedate"; + private String mySearchQuery = "assignee = currentUser() and resolution = Unresolved order by updated"; private JiraRestApi myRestApiVersion; @@ -69,17 +69,15 @@ public class JiraRepository extends BaseRepositoryImpl { return true; } - public Task[] getIssues(@Nullable String searchQuery, int max, long since) throws Exception { + public Task[] getIssues(@Nullable String query, int max, long since) throws Exception { if (myRestApiVersion == null) { myRestApiVersion = discoverRestApiVersion(); } String jqlQuery = mySearchQuery; - if (!StringUtil.isEmpty(searchQuery)) { - if (JiraUtil.ANY_ISSUE_KEY_REGEX.matcher(searchQuery).matches()) { - jqlQuery += String.format(" and key = \"%s\"", searchQuery); - } - else { - jqlQuery += String.format(" and summary ~ \"%s\"", searchQuery); + if (!StringUtil.isEmpty(query)) { + jqlQuery = String.format("summary ~ '%s'", query); + if (!StringUtil.isEmpty(mySearchQuery)) { + jqlQuery += String.format(" and %s", mySearchQuery); } } List issues = myRestApiVersion.findIssues(jqlQuery, max); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraUtil.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraUtil.java index 8580f716762b..757baaec9ae1 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraUtil.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraUtil.java @@ -18,15 +18,11 @@ package com.intellij.tasks.jira; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import java.util.regex.Pattern; - /** * @author Mikhail Golubev */ public class JiraUtil { public static final Gson GSON = buildGson(); - //public static final Pattern DEFAULT_ISSUE_KEY_REGEX = Pattern.compile("\\p{Upper}{2,}+-\\d+"); - public static final Pattern ANY_ISSUE_KEY_REGEX = Pattern.compile("\\w+-\\d+"); private static Gson buildGson() { GsonBuilder gson = new GsonBuilder(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraComment.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraComment.java index df2e37b30ceb..57d4c87ceb60 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraComment.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraComment.java @@ -15,6 +15,7 @@ */ package com.intellij.tasks.jira.model; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import java.util.Date; @@ -59,4 +60,9 @@ public class JiraComment { public String getBody() { return body; } + + @Override + public String toString() { + return String.format("JiraComment(text='%s')", StringUtil.first(body, 30, true)); + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssue.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssue.java index f987d3526836..96fa520c6638 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssue.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssue.java @@ -11,7 +11,7 @@ import java.util.List; */ public abstract class JiraIssue { public String toString() { - return String.format("JiraIssue(key=%s, summary=%s)", getKey(), getSummary()); + return String.format("JiraIssue(key=%s, summary='%s')", getKey(), getSummary()); } @NotNull diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssueType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssueType.java index 0c4dfb19348a..b47423435193 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssueType.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraIssueType.java @@ -29,7 +29,7 @@ public class JiraIssueType { @Override public String toString() { - return String.format("JiraIssueType(name=%s)", name); + return String.format("JiraIssueType(name='%s')", name); } public String getIssueTypeUrl() { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraStatus.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraStatus.java index 83d049357806..ab3935f9861c 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraStatus.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraStatus.java @@ -32,7 +32,7 @@ public class JiraStatus { @Override public String toString() { - return String.format("JiraStatus(name=%s)", name); + return String.format("JiraStatus(name='%s')", name); } /** diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraUser.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraUser.java index 9046b2a8e39a..0f066554dc70 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraUser.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/JiraUser.java @@ -26,7 +26,7 @@ public class JiraUser { @Override public String toString() { - return String.format("JiraUser(name=%s)", name); + return String.format("JiraUser(name='%s')", name); } @NotNull diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/api2/JiraIssueApi2.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/api2/JiraIssueApi2.java index 12adfdfae1a5..deda4c5d9c9d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/api2/JiraIssueApi2.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/api2/JiraIssueApi2.java @@ -40,11 +40,6 @@ public class JiraIssueApi2 extends JiraIssue { private String self; private Fields fields; - @Override - public String toString() { - return String.format("JiraIssue(id=%s, summary=%s)", id, fields.summary); - } - @NotNull @Override public String getKey() { diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java index 76519590ac0d..5550d8e63faa 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java @@ -51,8 +51,8 @@ public class JiraIntegrationTest extends TaskManagerTestCase { */ public void testVersionDiscovery1() throws Exception { myRepository.setUrl("http://trackers-tests.labs.intellij.net:8015"); - myRepository.setUsername("deva"); - myRepository.setPassword("deva"); + myRepository.setUsername("buildtest"); + myRepository.setPassword("buildtest"); assertEquals("2.0", myRepository.discoverRestApiVersion().getVersionName()); } @@ -61,24 +61,24 @@ public class JiraIntegrationTest extends TaskManagerTestCase { */ public void testVersionDiscovery2() throws Exception { myRepository.setUrl("http://trackers-tests.labs.intellij.net:8014"); - myRepository.setUsername("deva"); - myRepository.setPassword("deva"); + myRepository.setUsername("buildtest"); + myRepository.setPassword("buildtest"); assertEquals("2.0.alpha1", myRepository.discoverRestApiVersion().getVersionName()); } public void testJqlQuery() throws Exception { - myRepository.setUsername("deva"); - myRepository.setPassword("deva"); - myRepository.setSearchQuery("assignee = currentUser() AND summary ~ 'animal'"); - assertEquals(1, myRepository.getIssues("", 50, 0).length); + myRepository.setUsername("buildtest"); + myRepository.setPassword("buildtest"); + myRepository.setSearchQuery("assignee = currentUser() AND (summary ~ 'foo' or resolution = Fixed)"); + assertEquals(2, myRepository.getIssues("", 50, 0).length); } /** * Holds only for JIRA > 5.x.x */ public void testExtractedErrorMessage() throws Exception { - myRepository.setUsername("deva"); - myRepository.setPassword("deva"); + myRepository.setUsername("buildtest"); + myRepository.setPassword("buildtest"); myRepository.setSearchQuery("foo < bar"); try { myRepository.getIssues("", 50, 0); @@ -89,13 +89,6 @@ public class JiraIntegrationTest extends TaskManagerTestCase { } } - public void testEmptyQuerySelectsAllIssues() throws Exception { - myRepository.setUsername("deva"); - myRepository.setPassword("deva"); - myRepository.setSearchQuery(""); - assertEquals(13, myRepository.getIssues("", 50, 0).length); - } - @Override public void setUp() throws Exception { super.setUp(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index f43ceb834a27..9c1d4fc51fe8 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -934,8 +934,6 @@ - - diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java index fb366d7aacf7..2db87f70c7a9 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnusedNamespaceInspection.java @@ -24,6 +24,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.URLReference; import com.intellij.psi.impl.source.xml.SchemaPrefix; @@ -73,21 +74,21 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool XmlAttributeValue value = attribute.getValueElement(); assert value != null; holder.registerProblem(attribute, "Namespace declaration is never used", ProblemHighlightType.LIKE_UNUSED_SYMBOL, - new RemoveNamespaceDeclarationFix(declaredPrefix, false)); + new RemoveNamespaceDeclarationFix(declaredPrefix, false, !refCountHolder.isUsedNamespace(namespace))); XmlTag parent = attribute.getParent(); if (declaredPrefix.length() == 0) { XmlAttribute location = getDefaultLocation(parent); if (location != null) { holder.registerProblem(location, NAMESPACE_LOCATION_IS_NEVER_USED, ProblemHighlightType.LIKE_UNUSED_SYMBOL, - new RemoveNamespaceDeclarationFix(declaredPrefix, true)); + new RemoveNamespaceDeclarationFix(declaredPrefix, true, true)); } } else if (!refCountHolder.isUsedNamespace(namespace)) { for (PsiReference reference : getLocationReferences(namespace, parent)) { if (!XmlHighlightVisitor.hasBadResolve(reference, false)) holder.registerProblemForReference(reference, ProblemHighlightType.LIKE_UNUSED_SYMBOL, NAMESPACE_LOCATION_IS_NEVER_USED, - new RemoveNamespaceDeclarationFix(declaredPrefix, true)); + new RemoveNamespaceDeclarationFix(declaredPrefix, true, true)); } } } @@ -236,10 +237,12 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool protected final String myPrefix; private final boolean myLocationFix; + private final boolean myRemoveLocation; - private RemoveNamespaceDeclarationFix(@Nullable String prefix, boolean locationFix) { + private RemoveNamespaceDeclarationFix(@Nullable String prefix, boolean locationFix, boolean removeLocation) { myPrefix = prefix; myLocationFix = locationFix; + myRemoveLocation = removeLocation; } @NotNull @@ -306,17 +309,19 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool Document document = documentManager.getDocument(attribute.getContainingFile()); assert document != null; attribute.delete(); - if (prefix.length() == 0) { - XmlAttribute locationAttr = getDefaultLocation(parent); - if (locationAttr != null) { - locationAttr.delete(); + if (myRemoveLocation) { + if (prefix.length() == 0) { + XmlAttribute locationAttr = getDefaultLocation(parent); + if (locationAttr != null) { + locationAttr.delete(); + } + } + else { + documentManager.doPostponedOperationsAndUnblockDocument(document); + PsiReference[] references = getLocationReferences(namespace, parent); + removeReferencesOrAttribute(references); + documentManager.commitDocument(document); } - } - else { - documentManager.doPostponedOperationsAndUnblockDocument(document); - PsiReference[] references = getLocationReferences(namespace, parent); - removeReferencesOrAttribute(references); - documentManager.commitDocument(document); } } @@ -349,7 +354,7 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool public static final String NAME = "Remove unused namespace location"; private RemoveNamespaceLocationFix(String namespace) { - super(namespace, true); + super(namespace, true, true); } @NotNull @@ -360,7 +365,7 @@ public class XmlUnusedNamespaceInspection extends XmlSuppressableInspectionTool @Override protected void doRemove(Project project, XmlAttribute attribute, XmlTag parent) { - if (myPrefix.length() == 0) { + if (StringUtil.isEmpty(myPrefix)) { attribute.delete(); } else { diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java index c3556448ecfd..acd047a26d1f 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java @@ -16,8 +16,10 @@ package com.intellij.codeInsight.template.emmet.filters; import com.intellij.codeInsight.template.emmet.nodes.GenerationNode; +import com.intellij.codeInsight.template.emmet.tokens.TemplateToken; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.lang.xml.XMLLanguage; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -32,6 +34,12 @@ public class SingleLineEmmetFilter extends ZenCodingFilter { return "s"; } + @NotNull + @Override + public String filterText(@NotNull String text, @NotNull TemplateToken token) { + return StringUtil.replace(text, "\n", ""); + } + @NotNull @Override public GenerationNode filterNode(@NotNull GenerationNode node) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java index e31b36ccb00b..c7ff99fac640 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/GenerationNode.java @@ -26,8 +26,11 @@ import com.intellij.codeInsight.template.emmet.generators.XmlZenCodingGeneratorI import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator; import com.intellij.codeInsight.template.emmet.tokens.TemplateToken; import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.injected.editor.DocumentWindowImpl; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -135,23 +138,48 @@ public class GenerationNode extends UserDataHolderBase { boolean insertSurroundedText) { myContainsSurroundedTextMarker = !(insertSurroundedText && myInsertSurroundedTextAtTheEnd); - boolean singleLineFilterEnabled = false; - GenerationNode generationNode = this; + if (generationNode != this) { + return generationNode.generate(callback, generator, Collections.emptyList(), insertSurroundedText); + } + + boolean shouldNotReformatTemplate = false; + boolean oneLineTemplateExpanding = false; for (ZenCodingFilter filter : filters) { generationNode = filter.filterNode(generationNode); if(filter instanceof SingleLineEmmetFilter) { - singleLineFilterEnabled = true; + shouldNotReformatTemplate = true; + oneLineTemplateExpanding = true; } } - if (generationNode != this) { - return generationNode.generate(callback, generator, Collections.emptyList(), insertSurroundedText); + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(callback.getProject()); + String indentStr; + if (callback.isInInjectedFragment()) { + Editor editor = callback.getEditor(); + Document document = editor.getDocument(); + if(document instanceof DocumentWindowImpl && ((DocumentWindowImpl)document).isOneLine()) { + /* + * If document is one-line that in the moment of inserting text, + * new line chars will be filtered (see DocumentWindowImpl#insertString). + * So in this case we should filter text by SingleLineAvoid in order to avoid + * inconsistency of template segments. + */ + oneLineTemplateExpanding = true; + filters.add(new SingleLineEmmetFilter()); + } + indentStr = ""; + } + else if (settings.useTabCharacter(callback.getFileType())) { + indentStr = "\t"; + } + else { + int tabSize = settings.getTabSize(callback.getFileType()); + indentStr = StringUtil.repeatSymbol(' ', tabSize); } LiveTemplateBuilder builder = new LiveTemplateBuilder(); int end = -1; - boolean hasChildren = myChildren.size() > 0; TemplateImpl parentTemplate; @@ -188,26 +216,14 @@ public class GenerationNode extends UserDataHolderBase { } LiveTemplateBuilder.Marker marker = offset < builder.length() ? builder.createMarker(offset) : null; - CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(callback.getProject()); - String indentStr; - if (callback.isInInjectedFragment()) { - indentStr = ""; - } - else if (settings.useTabCharacter(callback.getFileType())) { - indentStr = "\t"; - } - else { - int tabSize = settings.getTabSize(callback.getFileType()); - indentStr = StringUtil.repeatSymbol(' ', tabSize); - } - + //noinspection ForLoopReplaceableByForEach for (int i = 0, myChildrenSize = myChildren.size(); i < myChildrenSize; i++) { GenerationNode child = myChildren.get(i); TemplateImpl childTemplate = child.generate(callback, generator, filters, !myContainsSurroundedTextMarker); boolean blockTag = child.isBlockTag(); - if (!singleLineFilterEnabled && blockTag && !isNewLineBefore(builder.getText(), offset)) { + if (!oneLineTemplateExpanding && blockTag && !isNewLineBefore(builder.getText(), offset)) { builder.insertText(offset, "\n" + indentStr, false); offset += indentStr.length() + 1; } @@ -215,7 +231,7 @@ public class GenerationNode extends UserDataHolderBase { int e = builder.insertTemplate(offset, childTemplate, null); offset = marker != null ? marker.getEndOffset() : builder.length(); - if (!singleLineFilterEnabled && ((blockTag && !isNewLineAfter(builder.getText(), offset)) || myInsertNewLineBetweenNodes)) { + if (!oneLineTemplateExpanding && ((blockTag && !isNewLineAfter(builder.getText(), offset)) || myInsertNewLineBetweenNodes)) { builder.insertText(offset, "\n" + indentStr, false); offset += indentStr.length() + 1; } @@ -224,7 +240,7 @@ public class GenerationNode extends UserDataHolderBase { end = e; } } - if(singleLineFilterEnabled) { + if(shouldNotReformatTemplate) { builder.setIsToReformat(false); } return builder.buildTemplate(); diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java index bee53af627be..b35748c4d196 100644 --- a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java +++ b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java @@ -31,9 +31,6 @@ import com.intellij.xml.util.HtmlUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.List; - public class WebBrowserServiceImpl extends WebBrowserService { @Override public boolean canOpenInBrowser(@NotNull PsiElement psiElement) { @@ -100,9 +97,9 @@ public class WebBrowserServiceImpl extends WebBrowserService { private static Pair getProvider(PsiElement element, PsiFile psiFile) { Ref result = Ref.create(); - List allProviders = Arrays.asList(WebBrowserUrlProvider.EP_NAME.getExtensions()); - for (WebBrowserUrlProvider urlProvider : DumbService.getInstance(element.getProject()).filterByDumbAwareness(allProviders)) { - if (urlProvider.canHandleElement(element, psiFile, result)) { + DumbService dumbService = DumbService.getInstance(element.getProject()); + for (WebBrowserUrlProvider urlProvider : WebBrowserUrlProvider.EP_NAME.getExtensions()) { + if ((!dumbService.isDumb() || DumbService.isDumbAware(urlProvider)) && urlProvider.canHandleElement(element, psiFile, result)) { return Pair.create(urlProvider, result.get()); } } diff --git a/xml/impl/src/com/intellij/lang/xml/XmlLiteralEscaper.java b/xml/impl/src/com/intellij/lang/xml/XmlLiteralEscaper.java deleted file mode 100644 index 74df4c229d54..000000000000 --- a/xml/impl/src/com/intellij/lang/xml/XmlLiteralEscaper.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.lang.xml; - -import com.intellij.lang.ASTNode; -import com.intellij.lang.LiteralEscaper; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; -import com.intellij.psi.xml.XmlElementType; -import com.intellij.psi.xml.XmlToken; - -/** - * @author Gregory.Shrago - */ -public class XmlLiteralEscaper implements LiteralEscaper { - public String getEscapedText(PsiElement context, String originalText) { - if (context instanceof XmlToken) { - context = context.getParent(); - } - - ASTNode contextNode = context != null ? context.getNode():null; - if (contextNode != null && contextNode.getElementType() == XmlElementType.XML_CDATA) { - return originalText; - } - return escapeText(originalText); - } - - public String escapeText(String originalText) { - return StringUtil.escapeXml(originalText); - } - - public String unescapeText(String originalText) { - return StringUtil.unescapeXml(originalText); - } -} diff --git a/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java b/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java index 688191fcef19..2bdf78c50732 100644 --- a/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java +++ b/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java @@ -35,26 +35,23 @@ public abstract class WebBrowserUrlProvider { } } - public boolean canHandleElement(@NotNull PsiElement element, @NotNull PsiFile psiFile, Ref result) { + public boolean canHandleElement(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull Ref result) { VirtualFile file = psiFile.getVirtualFile(); if (file == null) { return false; } - Url url; try { - url = getUrl(element, psiFile, file); + Url url = getUrl(element, psiFile, file); + if (url != null) { + result.set(url); + return true; + } } catch (BrowserException ignored) { - return false; } - if (url == null) { - return false; - } - - result.set(url); - return true; + return false; } @Nullable diff --git a/xml/tests/src/com/intellij/xml/XmlNamespacesTest.java b/xml/tests/src/com/intellij/xml/XmlNamespacesTest.java index 03d221ce29d3..e457bdc1cfb9 100644 --- a/xml/tests/src/com/intellij/xml/XmlNamespacesTest.java +++ b/xml/tests/src/com/intellij/xml/XmlNamespacesTest.java @@ -4,7 +4,7 @@ import com.intellij.codeInsight.actions.OptimizeImportsProcessor; import com.intellij.codeInsight.daemon.impl.analysis.XmlUnusedNamespaceInspection; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.htmlInspections.XmlInspectionToolProvider; -import com.intellij.javaee.ExternalResourceManagerImpl; +import com.intellij.javaee.ExternalResourceManagerExImpl; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.testFramework.IdeaTestCase; @@ -208,6 +208,14 @@ public class XmlNamespacesTest extends CodeInsightFixtureTestCase { doOptimizeImportsTest(text); } + public void testUsedInXmlns() throws Exception { + myFixture.testHighlighting("spring.xml", "spring-beans-2.5.xsd", "spring-batch-2.1.xsd"); + IntentionAction action = myFixture.getAvailableIntention(XmlUnusedNamespaceInspection.RemoveNamespaceDeclarationFix.NAME); + assertNotNull(action); + myFixture.launchAction(action); + myFixture.checkResultByFile("spring_after.xml"); + } + private void doUnusedDeclarationTest(String text, String after, String name) throws Exception { doUnusedDeclarationTest(text, after, name, true); } @@ -241,12 +249,12 @@ public class XmlNamespacesTest extends CodeInsightFixtureTestCase { protected void setUp() throws Exception { super.setUp(); myFixture.enableInspections(new XmlInspectionToolProvider()); - ExternalResourceManagerImpl.registerResourceTemporarily("http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd", - getTestDataPath() + "/web-app_2_5.xsd", getTestRootDisposable()); - ExternalResourceManagerImpl.registerResourceTemporarily("http://xml.apache.org/axis/wsdd/", - getTestDataPath() + "/wsdd.dtd", getTestRootDisposable()); - ExternalResourceManagerImpl.registerResourceTemporarily("http://xml.apache.org/axis/wsdd/providers/java", - getTestDataPath() + "/wsdd_provider_java.xsd", getTestRootDisposable()); + ExternalResourceManagerExImpl.registerResourceTemporarily("http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd", + getTestDataPath() + "/web-app_2_5.xsd", getTestRootDisposable()); + ExternalResourceManagerExImpl.registerResourceTemporarily("http://xml.apache.org/axis/wsdd/", + getTestDataPath() + "/wsdd.dtd", getTestRootDisposable()); + ExternalResourceManagerExImpl.registerResourceTemporarily("http://xml.apache.org/axis/wsdd/providers/java", + getTestDataPath() + "/wsdd_provider_java.xsd", getTestRootDisposable()); } @Override diff --git a/xml/tests/testData/unusedNs/spring-batch-2.1.xsd b/xml/tests/testData/unusedNs/spring-batch-2.1.xsd new file mode 100644 index 000000000000..a4cadf5108e9 --- /dev/null +++ b/xml/tests/testData/unusedNs/spring-batch-2.1.xsd @@ -0,0 +1,1291 @@ + + + + + + + + + + + + + + Defines a job composed of a set of steps and + transitions between steps. The job will be exposed in + the enclosing + bean factory as a component of type Job + that can be launched using a + JobLauncher. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines a stage in job processing backed by a + Step. The id attribute must be specified since this + step definition + will be referred to from other elements + to form a Job flow. + + + + + + + + + + + + + + + + + Defines a flow composed of a set of steps and + transitions between steps. + + + + + + + + + + + + + + + + + + A reference to a JobExecutionListener (or a POJO + if using before-job-method / after-job-method or + source level + annotations). + + + + + + + + + + + + + + + A bean definition for a step listener (or POJO if + using *-method attributes or source level + annotations) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines a stage in job processing backed by a + Step. The id attribute must be specified. The + step + requires either + a chunk definition, + a tasklet reference, or a reference to a + (possibly abstract) parent step. + + + + + + + + + + + + + + + Declares job should split here into two or more + subflows. + + + + + + + + A subflow within a job, having the same + format as a job, but without a separate identity. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares job should include an externalized flow + here. + + + + + + + + + + + + + + + + + + + + + + Declares job should query a decider to determine + where execution should go next. + + + + + + + + + The decider is a reference to a + JobExecutionDecider that can produce a status to base + the next + transition on. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The tasklet is a reference to another bean + definition that implements + the Tasklet interface. + + + + + + + + + + If the tasklet is specified as a bean definition, then a method can be specified and a POJO + will + be adapted to the Tasklet interface. The method suggested should have the same arguments + as Tasklet.execute (or a subset), and have a compatible return type (boolean, void or RepeatStatus). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + An exception class name. + + + + + + + + + + + + + + + + + Classify an exception as "included" in the set. Exceptions of this type or a subclass are + included. + + + + + + + + + + + + + + + + Classify an exception as "excluded" from the + set. Exceptions of this type or a subclass are + excluded + + + + + + + + + + + + + + + A reference to a listener, a POJO with a + listener-annotated method, or a POJO with + a method + referenced by a + *-method attribute. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Defines a transition from this step to the + next + one depending on the value of the exit + status. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. When a + step finishes + the most + specific match will be chosen to select the next step. + Hint: + always include a default + transition with on="*". + + + + + + + The name of the step to go to next. Must + resolve to one of the other steps in this job. + + + + + + + + + Declares job should be stop at this point and + provides pointer where execution should continue + when + the job is + restarted. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. + When a step + finishes + the most specific match will be chosen to + select the next step. + + + + + + The name of the step to start on when the + stopped job is restarted. + Must resolve to one of the + other steps + in this job. + + + + + + + + + Declares job should end at this point, without + the possibility of restart. + BatchStatus will be + COMPLETED. + ExitStatus is configurable. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. + When a step + finishes + the most specific match will be chosen to + select the next step. + + + + + + The exit code value to end on, defaults to + COMPLETED. + + + + + + + + Declares job should fail at this point. + BatchStatus will be FAILED. ExitStatus is configurable. + + + + + + A pattern to match against the exit status + code. Use * and ? as wildcard characters. + When a step + finishes + the most specific match will be chosen to + select the next step. + + + + + + The exit code value to end on, defaults to + FAILED. + + + + + + + + + + + + + + + + + + + + + + + + + The name of the parent bean from which the + configuration should inherit. + + + + + + + + + + + + + Is this bean "abstract", that is, not meant to be + instantiated itself + but rather just serving as + parent for concrete + child bean definitions? + The default is "false". Specify "true" to + tell the bean factory to not + try + to instantiate that particular bean + in any case. + + Note: This attribute will not be inherited by child + bean definitions. + Hence, it needs to be specified per abstract bean + definition. + + + + + + + + + + Should this list be merged with the corresponding + list provided + by the parent? If not, it will + overwrite the parent + list. + + + + + + + + + + This attribute indicates the method from the + class that should + be used to dynamically create a + proxy. + + + + + + + + + + + + + diff --git a/xml/tests/testData/unusedNs/spring-beans-2.5.xsd b/xml/tests/testData/unusedNs/spring-beans-2.5.xsd new file mode 100644 index 000000000000..170660a6a46c --- /dev/null +++ b/xml/tests/testData/unusedNs/spring-beans-2.5.xsd @@ -0,0 +1,1164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ' element. + ]]> + + + + + + + + + + ' element. + ]]> + + + + + + + + + + + + + + ' element. + ]]> + + + + + + + + + + + + + ' element for the semantic details of autowire candidate beans. + ]]> + + + + + ' element. + ]]> + + + + + ' element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + element (or "ref" + attribute). We recommend this in most cases as it makes documentation + more explicit. + + 2. "byName" + Autowiring by property name. If a bean of class Cat exposes a "dog" + property, Spring will try to set this to the value of the bean "dog" + in the current container. If there is no matching bean by name, nothing + special happens; use dependency-check="objects" to raise an error in + that case. + + 3. "byType" + Autowiring if there is exactly one bean of the property type in the + container. If there is more than one, a fatal error is raised, and + you cannot use byType autowiring for that bean. If there is none, + nothing special happens; use dependency-check="objects" to raise an + error in that case. + + 4. "constructor" + Analogous to "byType" for constructor arguments. If there is not exactly + one bean of the constructor argument type in the bean factory, a fatal + error is raised. + + 5. "autodetect" + Chooses "constructor" or "byType" through introspection of the bean + class. If a default constructor is found, "byType" gets applied. + + Note that explicit dependencies, i.e. "property" and "constructor-arg" + elements, always override autowiring. Autowire behavior can be combined + with dependency checking, which will be performed after all autowiring + has been completed. + + Note: This attribute will not be inherited by child bean definitions. + Hence, it needs to be specified per concrete bean definition. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + " element. + ]]> + + + + + ..." element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ". + ]]> + + + + + ..." element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ". + ]]> + + + + + ..." + element. + ]]> + + + + + ". + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml/tests/testData/unusedNs/spring.xml b/xml/tests/testData/unusedNs/spring.xml new file mode 100644 index 000000000000..6579845e8244 --- /dev/null +++ b/xml/tests/testData/unusedNs/spring.xml @@ -0,0 +1,9 @@ + +xmlns:batch="http://www.springframework.org/schema/batch" + xsi:schemaLocation="http://www.springframework.org/schema/beans spring-beans-2.5.xsd + http://www.springframework.org/schema/batch spring-batch-2.1.xsd"> + + + diff --git a/xml/tests/testData/unusedNs/spring_after.xml b/xml/tests/testData/unusedNs/spring_after.xml new file mode 100644 index 000000000000..f1262d937f4c --- /dev/null +++ b/xml/tests/testData/unusedNs/spring_after.xml @@ -0,0 +1,8 @@ + + + + +