diff --git a/.idea/inspectionProfiles/idea_default_no_spellchecker.xml b/.idea/inspectionProfiles/idea_default_no_spellchecker.xml index c2533ca21484..31ad0333a60c 100644 --- a/.idea/inspectionProfiles/idea_default_no_spellchecker.xml +++ b/.idea/inspectionProfiles/idea_default_no_spellchecker.xml @@ -854,4 +854,4 @@ - \ No newline at end of file + diff --git a/.idea/modules.xml b/.idea/modules.xml index ac849c617625..e2376f6341b3 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -79,7 +79,6 @@ - diff --git a/.idea/runConfigurations/JPS_tests.xml b/.idea/runConfigurations/JPS_tests.xml deleted file mode 100644 index c60f67c434ce..000000000000 --- a/.idea/runConfigurations/JPS_tests.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index aa5997bccf56..434defdb6e8b 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -99,7 +99,9 @@ def layoutAll(Map args, String home, String out, Paths _paths = null) { def layouts = includeFile("$home/build/scripts/layouts.gant") layouts.layoutFull(home, paths.distAll) layouts.layout_core(home, paths.artifacts_core) + notifyArtifactBuilt(paths.artifacts_core) layouts.layout_core_upsource(home, paths.artifacts_core_upsource) + notifyArtifactBuilt(paths.artifacts_core_upsource) layout(paths.distAll) { dir("bin") { diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index bb07cb370547..70f93938d7e0 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -161,6 +161,13 @@ binding.setVariable("notifyArtifactBuilt", { String artifactPath -> projectBuilder.error("Artifact path $artifactPath should start with $home") } def relativePath = artifactPath.substring(home.length()) + if (relativePath.startsWith("/")) { + relativePath = relativePath.substring(1) + } + def file = new File(artifactPath) + if (file.isDirectory()) { + relativePath += "=>" + file.name + } projectBuilder.info("##teamcity[publishArtifacts '$relativePath']") }) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index bfd2f6e5cf79..1e5416cdc798 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -48,11 +48,11 @@ public class HighlightControlFlowUtil { private HighlightControlFlowUtil() { } @Nullable - public static HighlightInfo checkMissingReturnStatement(PsiMethod method) { - PsiCodeBlock body = method.getBody(); + public static HighlightInfo checkMissingReturnStatement(PsiCodeBlock body, PsiType returnType) { + if (body == null - || method.getReturnType() == null - || PsiType.VOID.equals(method.getReturnType())) { + || returnType == null + || PsiType.VOID.equals(returnType)) { return null; } // do not compute constant expressions for if() statement condition @@ -68,9 +68,13 @@ public class HighlightControlFlowUtil { HighlightInfoType.ERROR, context, JavaErrorMessages.message("missing.return.statement")); - QuickFixAction.registerQuickFixAction(highlightInfo, new AddReturnFix(method)); - IntentionAction fix = QUICK_FIX_FACTORY.createMethodReturnFix(method, PsiType.VOID, true); - QuickFixAction.registerQuickFixAction(highlightInfo, fix); + final PsiElement parent = body.getParent(); + if (parent instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)parent; + QuickFixAction.registerQuickFixAction(highlightInfo, new AddReturnFix(method)); + IntentionAction fix = QUICK_FIX_FACTORY.createMethodReturnFix(method, PsiType.VOID, true); + QuickFixAction.registerQuickFixAction(highlightInfo, fix); + } return highlightInfo; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index a11968f67cbd..3dc1cb631d88 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -282,6 +282,12 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } else { myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, "Lambda expression not expected here")); } + if (!myHolder.hasErrorResults()) { + final PsiElement body = expression.getBody(); + if (body instanceof PsiCodeBlock) { + myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement((PsiCodeBlock)body)); + } + } } } @@ -333,10 +339,24 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh super.visitJavaToken(token); if (!myHolder.hasErrorResults() && token.getTokenType() == JavaTokenType.RBRACE - && token.getParent() instanceof PsiCodeBlock - && token.getParent().getParent() instanceof PsiMethod) { - PsiMethod method = (PsiMethod)token.getParent().getParent(); - myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(method)); + && token.getParent() instanceof PsiCodeBlock) { + + final PsiElement gParent = token.getParent().getParent(); + final PsiCodeBlock codeBlock; + final PsiType returnType; + if (gParent instanceof PsiMethod) { + PsiMethod method = (PsiMethod)gParent; + codeBlock = method.getBody(); + returnType = method.getReturnType(); + } else if (gParent instanceof PsiLambdaExpression) { + final PsiElement body = ((PsiLambdaExpression)gParent).getBody(); + if (!(body instanceof PsiCodeBlock)) return; + codeBlock = (PsiCodeBlock)body; + returnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)gParent); + } else { + return; + } + myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(codeBlock, returnType)); } } diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java index e190687f430e..04d6533f8ea4 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java @@ -97,7 +97,12 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaLocalInspectionT return returnStatement.getReturnValue(); } else { - return ((PsiExpressionStatement)statements[0]).getExpression(); + final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); + final PsiType psiType = expression.getType(); + if (psiType != PsiType.VOID) { + return null; + } + return expression; } } } 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 20f87a9b2841..64d5b1246585 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -92,12 +92,25 @@ public class LambdaUtil { public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) { if (expression.getParameterList().getParametersCount() > 0 || getFunctionalInterfaceReturnType(functionalInterfaceType) != PsiType.VOID) { //todo check that void lambdas without params check - if (functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()) return false; + if (!checkRawAcceptable(expression, functionalInterfaceType)) { + return false; + } return !dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression, null); } return true; } + private static boolean checkRawAcceptable(PsiLambdaExpression expression, PsiType functionalInterfaceType) { + PsiElement parent = expression.getParent(); + while (parent instanceof PsiParenthesizedExpression) { + parent = parent.getParent(); + } + if (parent instanceof PsiExpressionList && functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){ + return false; + } + return true; + } + @Nullable public static String checkInterfaceFunctional(PsiType functionalInterfaceType) { final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(functionalInterfaceType); 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 ac9a3ed686eb..21b208db2aac 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 @@ -850,9 +850,17 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } } else if (parent instanceof PsiReturnStatement) { - PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); - if (method != null) { - expectedType = method.getReturnType(); + final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(parent, PsiLambdaExpression.class); + if (lambdaExpression != null) { + expectedType = LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression.getFunctionalInterfaceType()); + if (expectedType == null) { + return getFailedInferenceConstraint(typeParameter); + } + } else { + PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); + if (method != null) { + expectedType = method.getReturnType(); + } } } else if (parent instanceof PsiExpressionList) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java index a083d9ec1b6f..e44f0de64815 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConditionalExpr.java @@ -25,7 +25,7 @@ class Test { { boolean flag = true; I i = flag ? (() -> 123) : (() -> 222); - I i1 = flag ? (() -> {}) : (() -> 222); + I i1 = flag ? (() -> {}) : (() -> 222); Object i2 = flag ? (() -> 42) : (() -> 222); I i3 = flag ? ((x) -> 42) : (() -> 222); I i4 = flag ? (() -> 42) : new I() { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java index 61b13e5c0e04..7c16a8b75723 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/IncompatibleReturnTypes.java @@ -18,7 +18,7 @@ class Test2 { } { IntReturnType aI = () -> System.out.println(); - IntReturnType aI1 = () -> {System.out.println();}; + IntReturnType aI1 = () -> {System.out.println();}; IntReturnType aI2 = () -> {return 1;}; IntReturnType aI3 = () -> 1; } @@ -32,10 +32,10 @@ class Test3 { } { XReturnType aI = () -> System.out.println(); - XReturnType aI1 = () -> {System.out.println();}; + XReturnType aI1 = () -> {System.out.println();}; XReturnType aI2 = () -> {return 1;}; XReturnType aI3 = () -> 1; - XReturnType aI4 = () -> {}; + XReturnType aI4 = () -> {}; } } @@ -48,7 +48,7 @@ class Test4 { { YXReturnType aI = () -> System.out.println(); - YXReturnType aI1 = () -> {System.out.println();}; + YXReturnType aI1 = () -> {System.out.println();}; YXReturnType aI2 = () -> {return 1;}; YXReturnType aI3 = () -> 1; YXReturnType aI4 = () -> new Y(){}; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java index cfece56e219b..4b9b085ce780 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java @@ -58,3 +58,15 @@ class Test4 { public interface TerminalOp1 extends IntermediateOp1 {} } + +class Test5 { + { + Block empty = x -> {}; + Block empty1 = x -> {}; + System.out.println((Block) x -> {}); + } + + interface Block { + void apply(T t); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java new file mode 100644 index 000000000000..5bfdab7f6cbe --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnValue.java @@ -0,0 +1,43 @@ +class Test1 { + interface Extractor { + Option unapply(T t); + } + + public static abstract class Option { + private static class None extends Option {} + + private static final Option NONE = new None(); + + public static Option none() { + return NONE; + } + + public static Option option(T value) { + if (value == null) { + return NONE; + } else { + return null; + } + } + } + + + + public static void main(String[] args) { + Extractor e = s -> { + if (s.equals("1")) { + return Option.option(1); + } else { + return Option.none(); + } + }; + + Extractor e1 = s -> { + if (s.equals("1")) { + return Option.option(1); + } else { + return Option.option("2"); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/UnreachableStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/UnreachableStatement.java new file mode 100644 index 000000000000..8ce86440acad --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/UnreachableStatement.java @@ -0,0 +1,9 @@ +class Test1 { + { + Comparable c = o -> { + if (o == null) return 1; + return -1; + System.out.println("Hello"); + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java new file mode 100644 index 000000000000..cd86ba278aff --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr/beforeReturnTypeInExpressionStatement.java @@ -0,0 +1,8 @@ +// "Replace with one line expression" "false" +class Test { + { + Runnable c = () -> {foo();}; + } + + int foo() {return 1;} +} \ No newline at end of file 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 5b654b928770..2aba17f529eb 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 @@ -132,6 +132,14 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testVariableInitialization() throws Exception { doTest(); } + + public void testUnreachableStatement() throws Exception { + doTest(); + } + + public void testReturnValue() throws Exception { + doTest(); + } private void doTest() throws Exception { doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false); diff --git a/jps/.idea/ant.xml b/jps/.idea/ant.xml deleted file mode 100644 index 2581ca3fe84c..000000000000 --- a/jps/.idea/ant.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/jps/.idea/artifacts/jps.xml b/jps/.idea/artifacts/jps.xml deleted file mode 100644 index 02a6a49605fd..000000000000 --- a/jps/.idea/artifacts/jps.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_appLauncher.xml b/jps/.idea/artifacts/jps_appLauncher.xml deleted file mode 100644 index 9757aa31580c..000000000000 --- a/jps/.idea/artifacts/jps_appLauncher.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_facade.xml b/jps/.idea/artifacts/jps_facade.xml deleted file mode 100644 index 10b7050582ff..000000000000 --- a/jps/.idea/artifacts/jps_facade.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts/ - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_scala.xml b/jps/.idea/artifacts/jps_scala.xml deleted file mode 100644 index c29aa330f344..000000000000 --- a/jps/.idea/artifacts/jps_scala.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - \ No newline at end of file diff --git a/jps/.idea/artifacts/jps_sources.xml b/jps/.idea/artifacts/jps_sources.xml deleted file mode 100644 index 2f527656df83..000000000000 --- a/jps/.idea/artifacts/jps_sources.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - $PROJECT_DIR$/out/artifacts - - - - - - - \ No newline at end of file diff --git a/jps/.idea/codeStyleSettings.xml b/jps/.idea/codeStyleSettings.xml deleted file mode 100644 index e093d5640185..000000000000 --- a/jps/.idea/codeStyleSettings.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/jps/.idea/compiler.xml b/jps/.idea/compiler.xml deleted file mode 100644 index 1bfc11ed8da8..000000000000 --- a/jps/.idea/compiler.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - diff --git a/jps/.idea/copyright/profiles_settings.xml b/jps/.idea/copyright/profiles_settings.xml deleted file mode 100644 index 3572571ad83c..000000000000 --- a/jps/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/jps/.idea/dataSources.xml b/jps/.idea/dataSources.xml deleted file mode 100644 index f6e673adc243..000000000000 --- a/jps/.idea/dataSources.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/jps/.idea/dictionaries/max.xml b/jps/.idea/dictionaries/max.xml deleted file mode 100644 index d02243d14c6a..000000000000 --- a/jps/.idea/dictionaries/max.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - Classpath - Expando - Groovyc - Instrumentations - Javac - Runtime - args - chunkey - depdends - dest - initalizer - initializer - - - \ No newline at end of file diff --git a/jps/.idea/dynamic.xml b/jps/.idea/dynamic.xml deleted file mode 100644 index ac6fa956dfb5..000000000000 --- a/jps/.idea/dynamic.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/jps/.idea/encodings.xml b/jps/.idea/encodings.xml deleted file mode 100644 index e206d70d8595..000000000000 --- a/jps/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/jps/.idea/fileColors.xml b/jps/.idea/fileColors.xml deleted file mode 100644 index f6e673adc243..000000000000 --- a/jps/.idea/fileColors.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/jps/.idea/inspectionProfiles/profiles_settings.xml b/jps/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 24c0574ce220..000000000000 --- a/jps/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/Ant.xml b/jps/.idea/libraries/Ant.xml deleted file mode 100644 index e8b34ff3157c..000000000000 --- a/jps/.idea/libraries/Ant.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/Groovy.xml b/jps/.idea/libraries/Groovy.xml deleted file mode 100644 index fac61de38d0a..000000000000 --- a/jps/.idea/libraries/Groovy.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/JUnit.xml b/jps/.idea/libraries/JUnit.xml deleted file mode 100644 index 9fa39b787cb9..000000000000 --- a/jps/.idea/libraries/JUnit.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/Javac2.xml b/jps/.idea/libraries/Javac2.xml deleted file mode 100644 index d478577bdeea..000000000000 --- a/jps/.idea/libraries/Javac2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/annotations.xml b/jps/.idea/libraries/annotations.xml deleted file mode 100644 index 9375c6d1d493..000000000000 --- a/jps/.idea/libraries/annotations.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/asm.xml b/jps/.idea/libraries/asm.xml deleted file mode 100644 index 6129eec40075..000000000000 --- a/jps/.idea/libraries/asm.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/libraries/idea_util.xml b/jps/.idea/libraries/idea_util.xml deleted file mode 100644 index 138cc88b687e..000000000000 --- a/jps/.idea/libraries/idea_util.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/misc.xml b/jps/.idea/misc.xml deleted file mode 100644 index 601befb5a18b..000000000000 --- a/jps/.idea/misc.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - http://www.w3.org/1999/xhtml - - - - - - - - diff --git a/jps/.idea/modules.xml b/jps/.idea/modules.xml deleted file mode 100644 index cf8734940324..000000000000 --- a/jps/.idea/modules.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/jps/.idea/projectCodeStyle.xml b/jps/.idea/projectCodeStyle.xml deleted file mode 100644 index f6e673adc243..000000000000 --- a/jps/.idea/projectCodeStyle.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/jps/.idea/runConfigurations/all_tests.xml b/jps/.idea/runConfigurations/all_tests.xml deleted file mode 100644 index c22b2875923e..000000000000 --- a/jps/.idea/runConfigurations/all_tests.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/runConfigurations/incremental_tests.xml b/jps/.idea/runConfigurations/incremental_tests.xml deleted file mode 100644 index 71567817b634..000000000000 --- a/jps/.idea/runConfigurations/incremental_tests.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/jps/.idea/scopes/scope_settings.xml b/jps/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b8433b..000000000000 --- a/jps/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/jps/.idea/spellchecker.xml b/jps/.idea/spellchecker.xml deleted file mode 100644 index 05a3cf1ec6fa..000000000000 --- a/jps/.idea/spellchecker.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/jps/.idea/templateLanguages.xml b/jps/.idea/templateLanguages.xml deleted file mode 100644 index f6e673adc243..000000000000 --- a/jps/.idea/templateLanguages.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/jps/.idea/uiDesigner.xml b/jps/.idea/uiDesigner.xml deleted file mode 100644 index 313d05eed962..000000000000 --- a/jps/.idea/uiDesigner.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jps/.idea/vcs.xml b/jps/.idea/vcs.xml deleted file mode 100644 index cbc984988338..000000000000 --- a/jps/.idea/vcs.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy index fa8db0a9f5a7..18b496494f94 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/rebuild/JpsRebuildTestCase.groovy @@ -72,7 +72,7 @@ abstract class JpsRebuildTestCase extends JpsBuildTestCase { @Override protected String getTestDataRootPath() { - return PathManagerEx.getCommunityHomePath() + "/jps/jps-builders/testData/output" + return PathManagerEx.findFileUnderCommunityHome("jps/jps-builders/testData/output").absolutePath } def initFileSystemItem(TestFileSystemBuilder item, Closure initializer) { diff --git a/jps/jps-tests.iml b/jps/jps-tests.iml deleted file mode 100644 index 38b2f30cb1e4..000000000000 --- a/jps/jps-tests.iml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/platform/core-api/src/com/intellij/openapi/application/AccessToken.java b/platform/core-api/src/com/intellij/openapi/application/AccessToken.java index ad25bd65962a..9e1e028c83ae 100644 --- a/platform/core-api/src/com/intellij/openapi/application/AccessToken.java +++ b/platform/core-api/src/com/intellij/openapi/application/AccessToken.java @@ -1,48 +1,16 @@ -package com.intellij.openapi.application; - -import com.intellij.openapi.util.text.StringUtil; - -public abstract class AccessToken { - protected void acquired() { - String id = id(); - - if (id != null) { - final Thread thread = Thread.currentThread(); - thread.setName(thread.getName() + id); - } - } - - protected void released() { - String id = id(); - - if (id != null) { - final Thread thread = Thread.currentThread(); - String name = thread.getName(); - name = StringUtil.replace(name, id, ""); - thread.setName(name); - } - } - - private String id() { - Class aClass = getClass(); - String name = aClass.getName(); - while (name == null) { - aClass = aClass.getSuperclass(); - name = aClass.getName(); - } - - name = name.substring(name.lastIndexOf('.') + 1); - name = name.substring(name.lastIndexOf('$') + 1); - if (!name.equals("AccessToken")) { - return " [" + name+"]"; - } - return null; - } - - public abstract void finish(); - - public static final AccessToken EMPTY_ACCESS_TOKEN = new AccessToken() { - @Override - public void finish() {} - }; -} +package com.intellij.openapi.application; + +public abstract class AccessToken { + protected void acquired() { + } + + protected void released() { + } + + public abstract void finish(); + + public static final AccessToken EMPTY_ACCESS_TOKEN = new AccessToken() { + @Override + public void finish() {} + }; +} diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java index 65ed2d47e14a..8207fcc5a430 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.find.impl.livePreview; @@ -293,7 +308,7 @@ public class SearchResults implements DocumentListener { FindResult result; try { StringUtil.BombedCharSequence - bombedCharSequence = new StringUtil.BombedCharSequence(editor.getDocument().getCharsSequence(), System.currentTimeMillis() + 3000); + bombedCharSequence = new StringUtil.BombedCharSequence(editor.getDocument().getCharsSequence(), 3000); result = findManager.findString(bombedCharSequence, offset, findModel, virtualFile); } catch(PatternSyntaxException e) { result = null; diff --git a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java index a810d1c9b238..26efa42a20cf 100644 --- a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java +++ b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java @@ -53,7 +53,7 @@ public class DataLanguageBlockWrapper implements ASTBlock, BlockEx, BlockWithPar if (node != null) { final PsiElement psi = node.getPsi(); if (psi != null) { - language = psi.getLanguage(); + language = psi.getContainingFile().getLanguage(); } } myLanguage = language; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index ab63636d4c94..f2a18b9d2f36 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -51,6 +51,7 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; @@ -99,7 +100,6 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application private final String myName; private final ReentrantWriterPreferenceReadWriteLock myActionsLock = new ReentrantWriterPreferenceReadWriteLock(); - //private final AppLock myActionsLock = new AppLockImpl(); private final Stack myWriteActionsStack = new Stack(); // accessed from EDT only, no need to sync @@ -914,21 +914,13 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application @Override public void runReadAction(@NotNull final Runnable action) { - if (isReadAccessAllowed()) { + final AccessToken token = acquireReadActionLock(); + + try { action.run(); } - else { - assertReadActionAllowed(); - try { - myActionsLock.readLock().acquire(); - action.run(); - } - catch (InterruptedException e) { - throw new RuntimeInterruptedException(e); - } - finally { - myActionsLock.readLock().release(); - } + finally { + token.finish(); } } @@ -951,21 +943,13 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application @Override public T runReadAction(@NotNull final Computable computation) { - if (isReadAccessAllowed()) { + final AccessToken token = acquireReadActionLock(); + + try { return computation.compute(); } - else { - assertReadActionAllowed(); - try { - myActionsLock.readLock().acquire(); - return computation.compute(); - } - catch (InterruptedException e) { - throw new RuntimeInterruptedException(e); - } - finally { - myActionsLock.readLock().release(); - } + finally { + token.finish(); } } @@ -1248,6 +1232,44 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application released(); } } + + @Override + protected void acquired() { + String id = id(); + + if (id != null) { + final Thread thread = Thread.currentThread(); + thread.setName(thread.getName() + id); + } + } + + @Override + protected void released() { + String id = id(); + + if (id != null) { + final Thread thread = Thread.currentThread(); + String name = thread.getName(); + name = StringUtil.replace(name, id, ""); + thread.setName(name); + } + } + + private String id() { + Class aClass = getClass(); + String name = aClass.getName(); + while (name == null) { + aClass = aClass.getSuperclass(); + name = aClass.getName(); + } + + name = name.substring(name.lastIndexOf('.') + 1); + name = name.substring(name.lastIndexOf('$') + 1); + if (!name.equals("AccessToken")) { + return " [" + name+"]"; + } + return null; + } } private class ReadAccessToken extends AccessToken { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java index 13951ec6d812..86b979f949fd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java @@ -142,6 +142,10 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo @Override public void setNoCopyJarForPath(String pathInJar) { + if (myNoCopyJarPaths == null) { + return; + } + int index = pathInJar.indexOf(JAR_SEPARATOR); if (index < 0) return; String path = pathInJar.substring(0, index); diff --git a/platform/platform-impl/src/org/jetbrains/io/WebServer.java b/platform/platform-impl/src/org/jetbrains/io/WebServer.java index 64508c5e2200..002be85d8e0c 100644 --- a/platform/platform-impl/src/org/jetbrains/io/WebServer.java +++ b/platform/platform-impl/src/org/jetbrains/io/WebServer.java @@ -57,8 +57,8 @@ public class WebServer { bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setPipelineFactory(new ChannelPipelineFactoryImpl(pipelineConsumers, new DefaultHandler(openChannels))); - for (int i = 0, n = tryAnyPort ? portsCount : portsCount + 1; i < n; i++) { - int port = i == portsCount ? 0 : firstPort + i; + for (int i = 0; i < portsCount; i++) { + int port = firstPort + i; try { openChannels.add(bootstrap.bind(new InetSocketAddress(port))); return port; @@ -67,12 +67,23 @@ public class WebServer { if (portsCount == 1) { throw e; } - else if (i == (n - 1)) { + else if (!tryAnyPort && i == (portsCount - 1)) { LOG.error(e); } } } + if (tryAnyPort) { + try { + Channel channel = bootstrap.bind(new InetSocketAddress(0)); + openChannels.add(channel); + return ((InetSocketAddress)channel.getLocalAddress()).getPort(); + } + catch (ChannelException e) { + LOG.error(e); + } + } + return -1; } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index 2083b2e6a80f..26f8d3562304 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -245,11 +245,11 @@ public class DirectoryIndexImpl extends DirectoryIndex { } protected class IndexState { - final THashMap> myExcludeRootsMap = new THashMap>(); - final Set myProjectExcludeRoots = new THashSet(); - final Map myDirToInfoMap = new THashMap(); - final THashMap> myPackageNameToDirsMap = new THashMap>(); - final Map myDirToPackageName = new THashMap(); + protected final THashMap> myExcludeRootsMap = new THashMap>(); + protected final Set myProjectExcludeRoots = new THashSet(); + protected final Map myDirToInfoMap = new THashMap(); + protected final THashMap> myPackageNameToDirsMap = new THashMap>(); + protected final Map myDirToPackageName = new THashMap(); public IndexState() { } diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 161290672450..7287600249de 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -2357,14 +2357,18 @@ public class StringUtil extends StringUtilRt { return StringUtilRt.getShortName(fqName, separator); } + /** + * Expirable CharSequence. Very useful to control external libary execution time, + * i.e. when java.util.regex.Pattern match goes out of control. + */ public static class BombedCharSequence implements CharSequence { private CharSequence delegate; private long myTime; private int i = 0; - public BombedCharSequence(CharSequence sequence, long time) { + public BombedCharSequence(CharSequence sequence, long delay) { delegate = sequence; - myTime = time; + myTime = System.currentTimeMillis() + delay; } @Override diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java index 88a486200089..f5eee75567b6 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java @@ -27,6 +27,7 @@ import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.ParenthesesUtils; import com.siyeh.ig.psiutils.TypeUtils; import com.siyeh.ig.psiutils.VariableAccessUtils; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -109,11 +110,11 @@ public class StringBufferReplaceableByStringInspection extends BaseInspection { } @Nullable - private static StringBuilder buildStringExpression(PsiExpression expression, StringBuilder result) { + private static StringBuilder buildStringExpression(PsiExpression expression, @NonNls StringBuilder result) { if (expression instanceof PsiNewExpression) { final PsiNewExpression newExpression = (PsiNewExpression)expression; final PsiExpressionList argumentList = newExpression.getArgumentList(); - if (argumentList == null) { + if (argumentList == null) { return null; } final PsiExpression[] arguments = argumentList.getExpressions(); @@ -166,7 +167,13 @@ public class StringBufferReplaceableByStringInspection extends BaseInspection { } else { if (type instanceof PsiPrimitiveType) { - result.append("String.valueOf(").append(argument.getText()).append(")"); + if (argument instanceof PsiLiteralExpression) { + final PsiLiteralExpression literalExpression = (PsiLiteralExpression)argument; + result.append('"').append(literalExpression.getValue()).append('"'); + } + else { + result.append("String.valueOf(").append(argument.getText()).append(")"); + } } else { if (ParenthesesUtils.getPrecedence(argument) >= ParenthesesUtils.ADDITIVE_PRECEDENCE) { diff --git a/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/after.groovy.template new file mode 100644 index 000000000000..e04a2d7f7f71 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/after.groovy.template @@ -0,0 +1 @@ +int abc = 5 \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/before.groovy.template new file mode 100644 index 000000000000..69c4e1f1029f --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/before.groovy.template @@ -0,0 +1 @@ +def abc = 5 \ No newline at end of file diff --git a/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/description.html b/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/description.html new file mode 100644 index 000000000000..9cef258aee57 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/GrSetStrongTypeIntention/description.html @@ -0,0 +1,5 @@ + + +This intention inserts type declaration to the selected variable. + + \ No newline at end of file diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 190922a76023..c47140ec7ac0 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -1215,6 +1215,11 @@ intention.category.groovy/intention.category.groovy.declaration org.jetbrains.plugins.groovy.intentions.declaration.GrCreateFieldForParameterIntention + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.groovy.declaration + org.jetbrains.plugins.groovy.intentions.declaration.GrSetStrongTypeIntention + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java index 2804baa992a4..9fd4752e824d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java @@ -118,7 +118,8 @@ public abstract class CreateClassFix { if (argType == null) argType = TypesUtil.getJavaLangObject(refElement); paramTypes[i] = "Object"; paramNames[i] = "o" + i; - paramTypesExpressions[i] = new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, refElement.getManager()); + TypeConstraint[] constraints = {SupertypeConstraint.create(argType)}; + paramTypesExpressions[i] = new ChooseTypeExpression(constraints, refElement.getManager(), targetClass.getResolveScope()); } GrMethod method = GroovyPsiElementFactory.getInstance(project).createConstructorFromText(name, paramTypes, paramNames, "{\n}"); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateLocalVariableFromUsageFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateLocalVariableFromUsageFix.java index bae260ab4252..64443d412d2e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateLocalVariableFromUsageFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateLocalVariableFromUsageFix.java @@ -96,7 +96,7 @@ public class CreateLocalVariableFromUsageFix implements IntentionAction { } GrTypeElement typeElement = decl.getTypeElementGroovy(); assert typeElement != null; - ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project)); + ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project), typeElement.getResolveScope()); TemplateBuilderImpl builder = new TemplateBuilderImpl(decl); builder.replaceElement(typeElement, expr); decl = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(decl); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java index d1059bebf676..550217c9aaec 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java @@ -107,8 +107,9 @@ public class CreateMethodFromUsageFix implements IntentionAction { if (argType == null || argType == PsiType.NULL) argType = TypesUtil.getJavaLangObject(myRefExpression); final PsiParameter p = factory.createParameter("o", argType); parameterList.add(p); - paramTypesExpressions[i] = - new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, myRefExpression.getManager(), method.getLanguage() == GroovyFileType.GROOVY_LANGUAGE); + TypeConstraint[] constraints = {SupertypeConstraint.create(argType)}; + boolean isGroovy = method.getLanguage() == GroovyFileType.GROOVY_LANGUAGE; + paramTypesExpressions[i] = new ChooseTypeExpression(constraints, myRefExpression.getManager(), isGroovy, method.getResolveScope()); } return paramTypesExpressions; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java index 0777f785ffc5..80551faef83b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java @@ -57,7 +57,8 @@ public class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper if (expectedTypes instanceof TypeConstraint[]) { GrTypeElement typeElement = fieldDecl.getTypeElementGroovy(); assert typeElement != null; - ChooseTypeExpression expr = new ChooseTypeExpression((TypeConstraint[])expectedTypes, PsiManager.getInstance(project)); + ChooseTypeExpression expr = new ChooseTypeExpression((TypeConstraint[])expectedTypes, PsiManager.getInstance(project), + typeElement.getResolveScope()); builder.replaceElement(typeElement, expr); } else if (expectedTypes instanceof ExpectedTypeInfo[]) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index 4c81f7c81e33..3f7457df039e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -166,6 +166,8 @@ gr.convert.string.to.char.intention.name=Cast to char gr.convert.string.to.char.intention.family.name=Cast to char create.field.for.parameter.0 = Create Field for Parameter {0} create.field.for.parameter=Create Field for Parameter +gr.set.strong.type.intention.name=Declare explicit type +gr.set.strong.type.intention.family.name=Declare explicit type remove.unnecessary.escape.characters.intention.name=Remove unnecessary escape characters remove.unnecessary.escape.characters.intention.family.name=Remove unnecessary escape characters gr.break.string.on.line.breaks.intention.name=Break string on '\\n' diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java index 863d73082ce0..dd2a35da49d1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/base/IntentionUtils.java @@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; @@ -69,7 +70,8 @@ public class IntentionUtils { final Project project = owner.getProject(); PsiTypeElement typeElement = method.getReturnTypeElement(); - ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project), method.getLanguage()== GroovyFileType.GROOVY_LANGUAGE); + ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project), method.getLanguage()== GroovyFileType.GROOVY_LANGUAGE, + context.getResolveScope()); TemplateBuilderImpl builder = new TemplateBuilderImpl(method); if (!isConstructor) { assert typeElement != null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrSetStrongTypeIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrSetStrongTypeIntention.java new file mode 100644 index 000000000000..3125f875b467 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrSetStrongTypeIntention.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.intentions.declaration; + +import com.intellij.codeInsight.CodeInsightUtilBase; +import com.intellij.codeInsight.template.Template; +import com.intellij.codeInsight.template.TemplateBuilderImpl; +import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiType; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; +import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint; +import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression; + +import java.util.ArrayList; + +/** + * @author Max Medvedev + */ +public class GrSetStrongTypeIntention extends Intention { + + + @Override + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { + if (element instanceof GrVariableDeclaration) { + GrVariable[] variables = ((GrVariableDeclaration)element).getVariables(); + ArrayList types = new ArrayList(); + for (GrVariable variable : variables) { + if (variable.getInitializerGroovy() != null) { + PsiType type = variable.getInitializerGroovy().getType(); + types.add(SupertypeConstraint.create(type)); + } + } + + TemplateBuilderImpl builder = new TemplateBuilderImpl(element); + + + PsiManager manager = element.getManager(); + + GrModifierList modifierList = ((GrVariableDeclaration)element).getModifierList(); + + PsiElement replaceElement; + if (modifierList.hasModifierProperty(GrModifier.DEF) && modifierList.getModifiers().length == 1) { + replaceElement = PsiUtil.findModifierInList(modifierList, GrModifier.DEF); + } + else { + ((GrVariableDeclaration)element).setType(TypesUtil.createType("Abc", element)); + replaceElement = ((GrVariableDeclaration)element).getTypeElementGroovy(); + } + assert replaceElement != null; + TypeConstraint[] constraints = types.toArray(new TypeConstraint[types.size()]); + ChooseTypeExpression chooseTypeExpression = new ChooseTypeExpression(constraints, manager, replaceElement.getResolveScope()); + builder.replaceElement(replaceElement, chooseTypeExpression); + + + final PsiElement afterPostprocess = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element); + final Template template = builder.buildTemplate(); + TextRange range = afterPostprocess.getTextRange(); + Document document = editor.getDocument(); + document.deleteString(range.getStartOffset(), range.getEndOffset()); + + TemplateManager templateManager = TemplateManager.getInstance(project); + templateManager.startTemplate(editor, template); + } + } + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new PsiElementPredicate() { + @Override + public boolean satisfiedBy(PsiElement element) { + if (element instanceof GrVariableDeclaration && ((GrVariableDeclaration)element).getTypeElementGroovy() == null) { + GrVariable[] variables = ((GrVariableDeclaration)element).getVariables(); + for (GrVariable variable : variables) { + if (variable.getInitializerGroovy() != null) return true; + } + } + + return false; + } + }; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureTemplateBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureTemplateBuilder.java index e79540d4f939..d9edac5a40e2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureTemplateBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/closureParameters/ClosureTemplateBuilder.java @@ -84,11 +84,12 @@ public class ClosureTemplateBuilder { if (typeElement != null) { final TypeConstraint[] typeConstraints = {SupertypeConstraint.create(typeElement.getType())}; - final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project)); + final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project), nameIdentifier.getResolveScope()); builder.replaceElement(typeElement, expression); } else { - final ChooseTypeExpression expression = new ChooseTypeExpression(TypeConstraint.EMPTY_ARRAY, PsiManager.getInstance(project)); + final ChooseTypeExpression expression = + new ChooseTypeExpression(TypeConstraint.EMPTY_ARRAY, PsiManager.getInstance(project), nameIdentifier.getResolveScope()); builder.replaceElement(p.getModifierList(), expression); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java index ce67c5b0dde9..1d20a30d961e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrMethodCallImpl.java @@ -48,7 +48,7 @@ public abstract class GrMethodCallImpl extends GrCallExpressionImpl implements G } for (GrCallExpressionTypeCalculator typeCalculator : GrCallExpressionTypeCalculator.EP_NAME.getExtensions()) { - PsiType res = typeCalculator.calculateReturnType(callExpression, resolveResults); + PsiType res = typeCalculator.calculateReturnType(callExpression, resolveResults); if (res != null) { return res; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java index 8fa0fa099864..495603bccbb3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java @@ -144,6 +144,10 @@ public class GrAnonymousClassDefinitionImpl extends GrTypeDefinitionImpl impleme @Nullable PsiElement lastParent, @NotNull PsiElement place) { if (lastParent instanceof GrArgumentList) return true; + + GrCodeReferenceElement refElement = getBaseClassReferenceGroovy(); + if (refElement == place || refElement == lastParent) return true; + return super.processDeclarations(processor, state, lastParent, place); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java index f997d7b20004..203c65659867 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrTypeDefinitionImpl.java @@ -135,7 +135,7 @@ public abstract class GrTypeDefinitionImpl extends GrStubElementBase() { + public void handleInsert(InsertionContext context, LookupItem item) { + GroovyCompletionUtil.addImportForItem(context.getFile(), context.getStartOffset(), item); + } + }); + } + private static void processSuperTypes(PsiType type, Set result) { String text = type.getCanonicalText(); String unboxed = PsiTypesUtil.unboxIfPossible(text); @@ -78,7 +96,9 @@ public class ChooseTypeExpression extends Expression { result.add(LookupElementBuilder.create(unboxed).bold()); } else { - result.add(PsiTypeLookupItem.createLookupItem(type, null)); + PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(type, null); + setupLookup(item); + result.add(item); } PsiType[] superTypes = type.getSuperTypes(); for (PsiType superType : superTypes) { @@ -86,10 +106,9 @@ public class ChooseTypeExpression extends Expression { } } - private PsiType chooseType(TypeConstraint[] constraints) { + private PsiType chooseType(TypeConstraint[] constraints, GlobalSearchScope scope) { if (constraints.length > 0) return constraints[0].getDefaultType(); - return JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory() - .createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(myManager.getProject())); + return PsiType.getJavaLangObject(myManager, scope); } public Result calculateResult(ExpressionContext context) { @@ -100,6 +119,9 @@ public class ChooseTypeExpression extends Expression { return new TextResult(GrModifier.DEF); } + type = TypesUtil.unboxPrimitiveTypeWrapper(type); + if (type == null) return null; + return new PsiTypeResult(type, context.getProject()) { @Override public void handleRecalc(PsiFile psiFile, Document document, int segmentStart, int segmentEnd) {