diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java index 0b31eedf8be0..41fcf11be5c0 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java @@ -45,6 +45,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import static com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR; @@ -202,6 +203,7 @@ public abstract class LocalToFieldHandler { } else { assignment = (PsiStatement)body.add(assignment); } + appendComments(local, assignment); local.delete(); return assignment; } @@ -227,14 +229,18 @@ public abstract class LocalToFieldHandler { continue; } if ("super".equals(text) && enclosingConstructor == null && PsiTreeUtil.isAncestor(constructor, local, false)) { + final PsiStatement statement = (PsiStatement)body.addAfter(assignment, first); + appendComments(local, statement); local.delete(); - return (PsiStatement)body.addAfter(assignment, first); + return statement; } } } if (enclosingConstructor == null && PsiTreeUtil.isAncestor(constructor, local, false)) { + final PsiStatement statement = (PsiStatement)body.addBefore(assignment, first); + appendComments(local, statement); local.delete(); - return (PsiStatement)body.addBefore(assignment, first); + return statement; } } @@ -251,7 +257,10 @@ public abstract class LocalToFieldHandler { } } - if (enclosingConstructor == null) local.delete(); + if (enclosingConstructor == null) { + appendComments(assignment, local); + local.delete(); + } return assignment; } @@ -318,11 +327,13 @@ public abstract class LocalToFieldHandler { switch (finalInitializerPlace) { case IN_FIELD_DECLARATION: + appendComments(declarationStatement, myField); declarationStatement.delete(); break; case IN_CURRENT_METHOD: PsiExpressionStatement statement = createAssignment(myLocal, myFieldName, factory); + appendComments(declarationStatement, declarationStatement); if (declarationStatement instanceof PsiDeclarationStatement) { declarationStatement.replace(statement); } else { @@ -363,4 +374,12 @@ public abstract class LocalToFieldHandler { return myField; } } + + private static void appendComments(PsiElement declarationStatement, PsiElement element) { + final Collection comments = PsiTreeUtil.findChildrenOfType(declarationStatement, PsiComment.class); + final PsiElement parent = element.getParent(); + for (PsiComment comment : comments) { + parent.addBefore(comment, element); + } + } } diff --git a/java/java-tests/testData/refactoring/introduceConstant/Comments.java b/java/java-tests/testData/refactoring/introduceConstant/Comments.java new file mode 100644 index 000000000000..987dc45555ff --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceConstant/Comments.java @@ -0,0 +1,5 @@ +class Test { + { + String foo = /*and comment here*/"";//comment + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceConstant/Comments_after.java b/java/java-tests/testData/refactoring/introduceConstant/Comments_after.java new file mode 100644 index 000000000000..8a3430822e10 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceConstant/Comments_after.java @@ -0,0 +1,7 @@ +class Test { + /*and comment here*///comment + public static final String xxx = ""; + + { + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java index 3308baa4c78b..4e261d397f68 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java @@ -115,6 +115,11 @@ public class IntroduceConstantTest extends LightCodeInsightTestCase { checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); } + public void testComments() throws Exception { + configureByFile(BASE_PATH + getTestName(false) + ".java"); + checkDefaultType(CommonClassNames.JAVA_LANG_STRING); + checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); + } public void testEscalateVisibility() throws Exception { configureByFile(BASE_PATH + getTestName(false) + ".java"); diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java index afab27b3d6d2..a0ca95579138 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java @@ -61,7 +61,7 @@ public class ConvertFieldToThreadLocalIntention extends PsiElementBaseIntentionA if (psiField.getTypeElement() == null) return false; final PsiType fieldType = psiField.getType(); final PsiClass fieldTypeClass = PsiUtil.resolveClassInType(fieldType); - if (fieldType instanceof PsiPrimitiveType || fieldType instanceof PsiArrayType) return true; + if (fieldType instanceof PsiPrimitiveType && fieldType != PsiType.VOID || fieldType instanceof PsiArrayType) return true; return fieldTypeClass != null && !Comparing.strEqual(fieldTypeClass.getQualifiedName(), ThreadLocal.class.getName()) && AllowedApiFilterExtension.isClassAllowed(ThreadLocal.class.getName(), element); } @@ -118,6 +118,20 @@ public class ConvertFieldToThreadLocalIntention extends PsiElementBaseIntentionA } PsiExpression initializer = psiField.getInitializer(); + if (initializer == null) { + final PsiType type = psiField.getType(); + String initializerText = null; + if (type == PsiType.BOOLEAN) { + initializerText = "false"; + } + else if (type instanceof PsiPrimitiveType) { + initializerText = "0"; + } + if (initializerText != null) { + psiField.setInitializer(factory.createExpressionFromText(initializerText, psiField)); + initializer = psiField.getInitializer(); + } + } if (initializer != null) { if (initializer instanceof PsiArrayInitializerExpression) { PsiExpression normalizedExpr = diff --git a/java/typeMigration/testData/intentions/threadLocal/afterPrimitiveNoInitializer.java b/java/typeMigration/testData/intentions/threadLocal/afterPrimitiveNoInitializer.java new file mode 100644 index 000000000000..b922e385cde7 --- /dev/null +++ b/java/typeMigration/testData/intentions/threadLocal/afterPrimitiveNoInitializer.java @@ -0,0 +1,9 @@ +// "Convert to ThreadLocal" "true" +class Test { + final ThreadLocal field = new ThreadLocal() { + @Override + protected Integer initialValue() { + return 0; + } + }; +} \ No newline at end of file diff --git a/java/typeMigration/testData/intentions/threadLocal/beforePrimitiveNoInitializer.java b/java/typeMigration/testData/intentions/threadLocal/beforePrimitiveNoInitializer.java new file mode 100644 index 000000000000..4c12da0ff1a6 --- /dev/null +++ b/java/typeMigration/testData/intentions/threadLocal/beforePrimitiveNoInitializer.java @@ -0,0 +1,4 @@ +// "Convert to ThreadLocal" "true" +class Test { + int field; +} \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java index 683369896164..33e46b11afe0 100644 --- a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java +++ b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java @@ -25,7 +25,9 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; @@ -39,6 +41,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.search.SearchScope; import com.intellij.psi.tree.IElementType; +import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.IncorrectOperationException; import com.intellij.util.TimeoutUtil; import org.jetbrains.annotations.Contract; @@ -501,6 +504,10 @@ public class PsiUtilCore { FileType fileType = file.getFileType(); FileViewProvider viewProvider = psiManager.findViewProvider(file); Document document = FileDocumentManager.getInstance().getDocument(file); + boolean ignored = !(file instanceof LightVirtualFile) && FileTypeRegistry.getInstance().isFileIgnored(file); + VirtualFile vDir = file.getParent(); + PsiDirectory psiDir = vDir == null ? null : PsiManager.getInstance(project).findDirectory(vDir); + FileIndexFacade indexFacade = FileIndexFacade.getInstance(project); StringBuilder sb = new StringBuilder(); sb.append("valid=").append(file.isValid()). append(" isDirectory=").append(file.isDirectory()). @@ -510,6 +517,9 @@ public class PsiUtilCore { append(" default=").append(project.isDefault()). append(" open=").append(project.isOpen());; sb.append("\nfileType=").append(fileType.getName()).append("/").append(fileType.getClass().getName()); + sb.append("\nisIgnored=").append(ignored); + sb.append(" inLibrary=").append(indexFacade.isInLibrarySource(file) || indexFacade.isInLibraryClasses(file)); + sb.append(" parentDir=").append(vDir != null ? "has-vfs" : "no-vfs").append("/").append(psiDir != null ? "has-psi" : "no-psi"); sb.append("\nviewProvider=").append(viewProvider == null ? "null" : viewProvider.getClass().getName()); if (viewProvider != null) { List files = viewProvider.getAllFiles(); diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java index f0452412a59f..dbc74c167467 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/TestsLocationProviderUtil.java @@ -81,7 +81,8 @@ public class TestsLocationProviderUtil { if (fileName == null) { return Collections.emptyList(); } - return findFilesClosestToTarget(folders, collectCandidates(project, fileName, true), MIN_PROXIMITY_THRESHOLD); + final List target = findFilesClosestToTarget(folders, collectCandidates(project, fileName, true), MIN_PROXIMITY_THRESHOLD); + return target.isEmpty() && file != null ? Collections.singletonList(file) : target; } /** diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java index b89434a5df4f..e9060819f7b5 100644 --- a/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java +++ b/plugins/testng/testSources/com/theoryinpractice/testng/configuration/TestNGTreeHierarchyTest.java @@ -32,6 +32,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; public class TestNGTreeHierarchyTest { @@ -388,6 +389,16 @@ public class TestNGTreeHierarchyTest { return Collections.singletonList(myClassName); } + @Override + public String getFileName() { + return null; + } + + @Override + public String getXmlTestName() { + return null; + } + @Override public Throwable getThrowable() { return myThrowable; diff --git a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java index 6ce51491d450..aec42c8bc4ca 100644 --- a/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java +++ b/plugins/testng_rt/src/org/testng/IDEATestNGRemoteListener.java @@ -30,6 +30,9 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener public synchronized void onStart(final ISuite suite) { myPrintStream.println("##teamcity[enteredTheMatrix]"); + if (suite != null) { + myPrintStream.println("##teamcity[rootName name = '" + suite.getName() + "' location = 'file://" + suite.getXmlSuite().getFileName() + "']"); + } } public synchronized void onFinish(ISuite suite) { @@ -101,10 +104,10 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener } public boolean onSuiteStart(String classFQName, boolean provideLocation) { - return onSuiteStart(Collections.singletonList(classFQName), provideLocation); + return onSuiteStart(Collections.singletonList(classFQName), null, provideLocation); } - public boolean onSuiteStart(List parentsHierarchy, boolean provideLocation) { + public boolean onSuiteStart(List parentsHierarchy, ExposedTestResult result, boolean provideLocation) { int idx = 0; String currentClass; String currentParent; @@ -123,8 +126,18 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener for (int i = idx; i < parentsHierarchy.size(); i++) { String fqName = parentsHierarchy.get(parentsHierarchy.size() - 1 - i); String currentClassName = getShortName(fqName); + String location = "java:suite://" + escapeName(fqName); + if (result != null) { + final String testName = result.getXmlTestName(); + if (fqName.equals(testName)) { + final String fileName = result.getFileName(); + if (fileName != null) { + location = "file://" + fileName; + } + } + } myPrintStream.println("\n##teamcity[testSuiteStarted name =\'" + escapeName(currentClassName) + - (provideLocation ? "\' locationHint = \'java:suite://" + escapeName(fqName) : "") + "\']"); + (provideLocation ? "\' locationHint = \'" + location : "") + "\']"); myCurrentSuites.add(currentClassName); } return false; @@ -137,8 +150,7 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener private void onTestStart(ExposedTestResult result, String paramString, Integer invocationCount) { myPrintStream.println("##teamcity[testCount count=\'1\']"); myParamsMap.put(result, paramString); - final List fqns = result.getTestHierarchy(); - onSuiteStart(fqns, true); + onSuiteStart(result.getTestHierarchy(), result, true); final String className = result.getClassName(); final String methodName = result.getMethodName(); final String location = className + "." + methodName + (invocationCount >= 0 ? "[" + invocationCount + "]" : ""); @@ -236,6 +248,8 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener String getClassName(); long getDuration(); List getTestHierarchy(); + String getFileName(); + String getXmlTestName(); Throwable getThrowable(); } @@ -273,6 +287,17 @@ public class IDEATestNGRemoteListener implements ISuiteListener, IResultListener return hierarchy; } + public String getFileName() { + final XmlTest xmlTest = myResult.getTestClass().getXmlTest(); + return xmlTest != null ? xmlTest.getSuite().getFileName() : null; + } + + public String getXmlTestName() { + final XmlTest xmlTest = myResult.getTestClass().getXmlTest(); + return xmlTest != null ? xmlTest.getName() : null; + } + + public Throwable getThrowable() { return myResult.getThrowable(); }