diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java index 5e45940a6e00..50794c80684d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java @@ -137,6 +137,10 @@ public class CompileContextExProxy implements CompileContextEx { return myDelegate.isMake(); } + public boolean isAnnotationProcessorsEnabled() { + return myDelegate.isAnnotationProcessorsEnabled(); + } + public boolean isRebuild() { return myDelegate.isRebuild(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java index 7dfd94a63ed1..7fc2bb45ccfb 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java @@ -21,6 +21,7 @@ */ package com.intellij.compiler.impl; +import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerMessageImpl; import com.intellij.compiler.make.DependencyCache; import com.intellij.compiler.progress.CompilerTask; @@ -61,6 +62,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon private final DependencyCache myDependencyCache; private final boolean myMake; private final boolean myIsRebuild; + private final boolean myIsAnnotationProcessorsEnabled; private boolean myRebuildRequested = false; private String myRebuildReason; private final Map myRootToModuleMap = new HashMap(); @@ -86,6 +88,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon myStartCompilationStamp = System.currentTimeMillis(); myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); myProjectCompileScope = new ProjectCompileScope(myProject); + myIsAnnotationProcessorsEnabled = CompilerConfiguration.getInstance(project).isAnnotationProcessorsEnabled(); if (compilerSession != null) { compilerSession.setContentIdKey(compileScope.getUserData(CompilerManager.CONTENT_ID_KEY)); @@ -418,6 +421,10 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon return myIsRebuild; } + public boolean isAnnotationProcessorsEnabled() { + return myIsAnnotationProcessorsEnabled; + } + public void addScope(final CompileScope additionalScope) { myCompileScope = new CompositeScope(myCompileScope, additionalScope); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 436df551bc6d..dd503c74277e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -221,7 +221,7 @@ public class CompileDriver { task.start(new Runnable() { public void run() { try { - myAllOutputDirectories = getAllOutputDirectories(); + myAllOutputDirectories = getAllOutputDirectories(compileContext); // need this for updating zip archives experiment, uncomment if the feature is turned on //myOutputFinder = new OutputPathFinder(myAllOutputDirectories); status.set(doCompile(compileContext, false, false, false, true)); @@ -500,7 +500,7 @@ public class CompileDriver { return; } - myAllOutputDirectories = getAllOutputDirectories(); + myAllOutputDirectories = getAllOutputDirectories(compileContext); // need this for updating zip archives experiment, uncomment if the feature is turned on //myOutputFinder = new OutputPathFinder(myAllOutputDirectories); status = doCompile(compileContext, isRebuild, forceCompile, trackDependencies, false); @@ -1388,7 +1388,7 @@ public class CompileDriver { return isEmpty; } - private Set getAllOutputDirectories() { + private Set getAllOutputDirectories(CompileContext context) { final Set outputDirs = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL); final Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (final String path : CompilerPathsEx.getOutputPaths(modules)) { @@ -1399,7 +1399,7 @@ public class CompileDriver { outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true))); } final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject); - if (config.isAnnotationProcessorsEnabled()) { + if (context.isAnnotationProcessorsEnabled()) { for (Module module : modules) { if (config.isAnnotationProcessingEnabled(module)) { final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java index 0ac18f4deccb..77d2a7653f80 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java @@ -60,14 +60,14 @@ public class AnnotationProcessingCompiler implements TranslatingCompiler{ } public boolean isCompilableFile(VirtualFile file, CompileContext context) { - if (!myConfig.isAnnotationProcessorsEnabled()) { + if (!context.isAnnotationProcessorsEnabled()) { return false; } return file.getFileType() == StdFileTypes.JAVA && !isExcludedFromAnnotationProcessing(file, context); } public void compile(final CompileContext context, final Chunk moduleChunk, final VirtualFile[] files, OutputSink sink) { - if (!myConfig.isAnnotationProcessorsEnabled()) { + if (!context.isAnnotationProcessorsEnabled()) { return; } final LocalFileSystem lfs = LocalFileSystem.getInstance(); @@ -117,7 +117,7 @@ public class AnnotationProcessingCompiler implements TranslatingCompiler{ private boolean isExcludedFromAnnotationProcessing(VirtualFile file, CompileContext context) { final Module module = context.getModuleByFile(file); if (module != null) { - if (!myConfig.isAnnotationProcessingEnabled(module)) { + if (!context.isAnnotationProcessorsEnabled()) { return true; } final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java index 110b05a05edc..3bc297e6da7e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java @@ -108,7 +108,7 @@ public class CompilerAPICompiler implements BackendCompiler { List commandLine = new ArrayList(); JavacSettings javacSettings = CompilerAPIConfiguration.getSettings(myProject, CompilerAPIConfiguration.class); final List additionalOptions = - JavacCompiler.addAdditionalSettings(commandLine, javacSettings, false, 6, myProject); + JavacCompiler.addAdditionalSettings(commandLine, javacSettings, false, 6, myProject, compileContext.isAnnotationProcessorsEnabled()); JavacCompiler.addCommandLineOptions(chunk, commandLine, outputDir, chunk.getJdk(), false,false, null, false, false, false); commandLine.addAll(additionalOptions); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java index 19734c66f323..70876a533fa3 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java @@ -167,7 +167,7 @@ public class JavacCompiler extends ExternalCompiler { public String[] compute() { try { final List commandLine = new ArrayList(); - createStartupCommand(chunk, commandLine, outputPath, JavacSettings.getInstance(myProject)); + createStartupCommand(chunk, commandLine, outputPath, JavacSettings.getInstance(myProject), context.isAnnotationProcessorsEnabled()); return ArrayUtil.toStringArray(commandLine); } catch (IOException e) { @@ -186,7 +186,7 @@ public class JavacCompiler extends ExternalCompiler { } private void createStartupCommand(final ModuleChunk chunk, @NonNls final List commandLine, final String outputPath, - JavacSettings javacSettings) throws IOException { + JavacSettings javacSettings, final boolean annotationProcessorsEnabled) throws IOException { final Sdk jdk = getJdkForStartupCommand(chunk); final String versionString = jdk.getVersionString(); if (versionString == null || "".equals(versionString) || !(jdk.getSdkType() instanceof JavaSdkType)) { @@ -220,7 +220,7 @@ public class JavacCompiler extends ExternalCompiler { } final List additionalOptions = - addAdditionalSettings(commandLine, javacSettings, myAnnotationProcessorMode, versionIndex, myProject); + addAdditionalSettings(commandLine, javacSettings, myAnnotationProcessorMode, versionIndex, myProject, annotationProcessorsEnabled); CompilerUtil.addLocaleOptions(commandLine, false); @@ -281,7 +281,7 @@ public class JavacCompiler extends ExternalCompiler { } public static List addAdditionalSettings(List commandLine, JavacSettings javacSettings, boolean isAnnotationProcessing, - int versionIndex, Project project) { + int versionIndex, Project project, final boolean annotationProcessorsEnabled) { final List additionalOptions = new ArrayList(); StringTokenizer tokenizer = new StringTokenizer(javacSettings.getOptionsString(project), " "); if (versionIndex < 6) { @@ -319,9 +319,11 @@ public class JavacCompiler extends ExternalCompiler { } else { if (versionIndex > 5) { - // Unless explicitly specified by user, disable annotation processing by default for 'java compilation' mode - // This is needed to suppress unwanted side-effects from auto-discovered processors from compilation classpath - additionalOptions.add("-proc:none"); + if (annotationProcessorsEnabled) { + // Unless explicitly specified by user, disable annotation processing by default for 'java compilation' mode + // This is needed to suppress unwanted side-effects from auto-discovered processors from compilation classpath + additionalOptions.add("-proc:none"); + } } } diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java index bb56dbfd59c8..8bfa1c073b2a 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java @@ -150,4 +150,6 @@ public interface CompileContext extends UserDataHolder { boolean isRebuild(); Project getProject(); + + boolean isAnnotationProcessorsEnabled(); } diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java index 4a42a17d2966..85b01560cd31 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java @@ -80,6 +80,10 @@ public class DummyCompileContext implements CompileContext { return null; } + public boolean isAnnotationProcessorsEnabled() { + return false; + } + public VirtualFile[] getSourceRoots(Module module) { return VirtualFile.EMPTY_ARRAY; } diff --git a/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/Util.java b/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/Util.java deleted file mode 100644 index c7b829999e5e..000000000000 --- a/java/idea-ui/src/com/intellij/openapi/projectRoots/ui/Util.java +++ /dev/null @@ -1,43 +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.projectRoots.ui; - -import com.intellij.openapi.roots.libraries.doc.DocUrlChooser; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -/** - * Note: for languages other than Java use com.intellij.openapi.roots.libraries.doc.DocUrlChooser. - * @author MYakovlev - * Date: Oct 29, 2002 - * Time: 8:47:43 PM - */ -public class Util{ - - @Nullable - public static VirtualFile showSpecifyJavadocUrlDialog(JComponent parent) { - return showSpecifyJavadocUrlDialog(parent, ""); - } - - @Nullable - public static VirtualFile showSpecifyJavadocUrlDialog(JComponent parent, String initialValue){ - return DocUrlChooser.showSpecifyDocUrlDialog(parent, initialValue); - } - - -} diff --git a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java index cf2d48e0e084..feb111e02e38 100644 --- a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java +++ b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java @@ -16,6 +16,7 @@ package com.intellij.psi; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; @@ -35,6 +36,7 @@ import java.util.*; * @author peter */ public abstract class NonClasspathClassFinder extends PsiElementFinder { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.NonClasspathClassFinder"); protected final Project myProject; public NonClasspathClassFinder(Project project) { @@ -53,7 +55,8 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder { final VirtualFile classFile = classRoot.findFileByRelativePath(qualifiedName.replace('.', '/') + ".class"); if (classFile != null) { if (!classFile.isValid()) { - throw new AssertionError("Invalid child of valid parent: " + classFile.getPath() + "; " + classRoot.isValid() + " path=" + classRoot.getPath()); + LOG.error("Invalid child of valid parent: " + classFile.getPath() + "; " + classRoot.isValid() + " path=" + classRoot.getPath()); + return null; } final PsiFile file = PsiManager.getInstance(myProject).findFile(classFile); if (file instanceof PsiClassOwner) { diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 585eee3ab9c2..217cfa449d54 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -1233,7 +1233,12 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo varDeclarationAlignmentStrategy = AlignmentStrategy.createAlignmentPerTypeStrategy(VAR_DECLARATION_ELEMENT_TYPES_TO_ALIGN, true); } final boolean rBrace = isRBrace(child); - final Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent); + Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent); + if (!rBrace && child.getElementType() == JavaElementType.CODE_BLOCK + && (getBraceStyle() == CodeStyleSettings.NEXT_LINE_SHIFTED || getBraceStyle() == CodeStyleSettings.NEXT_LINE_SHIFTED2)) + { + childIndent = Indent.getNormalIndent(); + } AlignmentStrategy alignmentStrategyToUse = ALIGN_IN_COLUMNS_ELEMENT_TYPES.contains(child.getElementType()) ? varDeclarationAlignmentStrategy : AlignmentStrategy.getNullStrategy(); child = processChild(localResult, child, alignmentStrategyToUse, childWrap, childIndent); @@ -1270,7 +1275,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS); } - private SyntheticCodeBlock createCodeBlockBlock(final ArrayList localResult, final Indent indent, final int childrenIndent) { + public SyntheticCodeBlock createCodeBlockBlock(final ArrayList localResult, final Indent indent, final int childrenIndent) { final SyntheticCodeBlock result = new SyntheticCodeBlock(localResult, null, getSettings(), indent, null); result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(childrenIndent), null)); return result; diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java index 511450a9f617..ed8935ccb887 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java @@ -17,6 +17,7 @@ package com.intellij.psi.formatter.java; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.util.IncorrectOperationException; /** @@ -272,4 +273,38 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { "}" ); } + + public void testBracesShiftedOnNextLineOnMethodWithJavadoc() throws Exception { + // Inspired by IDEA-62997 + getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; + + String precededByJavadoc = + "/**\n" + + " * test\n" + + " */\n" + + "public int getFoo()\n" + + " {\n" + + " return foo;\n" + + " }"; + + String precededBySingleLineComment = + "// test\n" + + "public int getFoo()\n" + + " {\n" + + " return foo;\n" + + " }"; + + String precededByMultiLineComment = + "/*\n" + + "test\n" + + "*/\n" + + "public int getFoo()\n" + + " {\n" + + " return foo;\n" + + " }"; + + doClassTest(precededByJavadoc, precededByJavadoc); + doClassTest(precededBySingleLineComment, precededBySingleLineComment); + doClassTest(precededByMultiLineComment, precededByMultiLineComment); + } } diff --git a/java/openapi/src/com/intellij/psi/PsiNameValuePair.java b/java/openapi/src/com/intellij/psi/PsiNameValuePair.java index 213c4c7ac1fb..e7198c61ac72 100644 --- a/java/openapi/src/com/intellij/psi/PsiNameValuePair.java +++ b/java/openapi/src/com/intellij/psi/PsiNameValuePair.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -17,6 +17,7 @@ package com.intellij.psi; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Represents a single element-value pair of an annotation parameter list. @@ -36,6 +37,7 @@ public interface PsiNameValuePair extends PsiElement { * * @return the name identifier, or null if the annotation declaration is incomplete. */ + @Nullable PsiIdentifier getNameIdentifier(); /** @@ -43,7 +45,7 @@ public interface PsiNameValuePair extends PsiElement { * * @return the name, or null if the annotation declaration is incomplete. */ - @NonNls + @Nullable @NonNls String getName(); /** @@ -51,6 +53,7 @@ public interface PsiNameValuePair extends PsiElement { * * @return the value for the element. */ + @Nullable PsiAnnotationMemberValue getValue(); @NotNull PsiAnnotationMemberValue setValue(@NotNull PsiAnnotationMemberValue newValue); diff --git a/platform/lang-api/src/com/intellij/lang/annotation/AnnotationSession.java b/platform/lang-api/src/com/intellij/lang/annotation/AnnotationSession.java index 90262f0f6c09..b33ab13a6d2d 100644 --- a/platform/lang-api/src/com/intellij/lang/annotation/AnnotationSession.java +++ b/platform/lang-api/src/com/intellij/lang/annotation/AnnotationSession.java @@ -21,14 +21,16 @@ package com.intellij.lang.annotation; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; public class AnnotationSession extends UserDataHolderBase { private final PsiFile myFile; - public AnnotationSession(PsiFile file) { + public AnnotationSession(@NotNull PsiFile file) { myFile = file; } + @NotNull public PsiFile getFile() { return myFile; } diff --git a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java index d6e03d5aa872..3986ac086a0b 100644 --- a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java @@ -306,7 +306,10 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel { } else { FileType type = entry.getKey(); - editor.reset(settings, settings.getAdditionalIndentOptions(type)); + CodeStyleSettings.IndentOptions additionalIndentOptions = settings.getAdditionalIndentOptions(type); + if (additionalIndentOptions != null) { + editor.reset(settings, additionalIndentOptions); + } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java index 2c3e9fa0f14b..4de47c456f96 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightUtilBase.java @@ -22,7 +22,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.editor.ex.RangeMarkerEx; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; @@ -46,7 +45,7 @@ public class CodeInsightUtilBase { private CodeInsightUtilBase() { } - static T findElementInRange(final PsiFile file, + public static T findElementInRange(final PsiFile file, int startOffset, int endOffset, final Class klass, diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java index a1589e2364df..20a2caa48233 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java @@ -21,8 +21,11 @@ import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.AnnotationSession; import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.util.SmartList; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NonNls; @@ -32,13 +35,22 @@ import org.jetbrains.annotations.NotNull; * @author max */ public class AnnotationHolderImpl extends SmartList implements AnnotationHolder { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl"); private AnnotationSession myAnnotationSession; + AnnotationHolderImpl() { + } + public AnnotationHolderImpl(@NotNull AnnotationSession session) { + myAnnotationSession = session; + } + public Annotation createErrorAnnotation(@NotNull PsiElement elt, String message) { + assertMyFile(elt); return createAnnotation(elt.getTextRange(), HighlightSeverity.ERROR, message); } public Annotation createErrorAnnotation(@NotNull ASTNode node, String message) { + assertMyFile(node.getPsi()); return createAnnotation(node.getTextRange(), HighlightSeverity.ERROR, message); } @@ -47,10 +59,12 @@ public class AnnotationHolderImpl extends SmartList implements Annot } public Annotation createWarningAnnotation(@NotNull PsiElement elt, String message) { + assertMyFile(elt); return createAnnotation(elt.getTextRange(), HighlightSeverity.WARNING, message); } public Annotation createWarningAnnotation(@NotNull ASTNode node, String message) { + assertMyFile(node.getPsi()); return createAnnotation(node.getTextRange(), HighlightSeverity.WARNING, message); } @@ -59,10 +73,12 @@ public class AnnotationHolderImpl extends SmartList implements Annot } public Annotation createInformationAnnotation(@NotNull PsiElement elt, String message) { + assertMyFile(elt); return createAnnotation(elt.getTextRange(), HighlightSeverity.INFO, message); } public Annotation createInformationAnnotation(@NotNull ASTNode node, String message) { + assertMyFile(node.getPsi()); return createAnnotation(node.getTextRange(), HighlightSeverity.INFO, message); } @@ -71,13 +87,29 @@ public class AnnotationHolderImpl extends SmartList implements Annot } public Annotation createInfoAnnotation(@NotNull PsiElement elt, String message) { + assertMyFile(elt); return createAnnotation(elt.getTextRange(), HighlightSeverity.INFORMATION, message); } public Annotation createInfoAnnotation(@NotNull ASTNode node, String message) { + assertMyFile(node.getPsi()); return createAnnotation(node.getTextRange(), HighlightSeverity.INFORMATION, message); } + private void assertMyFile(PsiElement node) { + if (node == null) return; + PsiFile myFile = myAnnotationSession.getFile(); + PsiFile containingFile = node.getContainingFile(); + LOG.assertTrue(containingFile != null, node); + VirtualFile containingVFile = containingFile.getVirtualFile(); + VirtualFile myVFile = myFile.getVirtualFile(); + if (containingVFile != myVFile) { + LOG.error( + "Annotation must be registered for an element inside '" + myFile + "' which is in '" + myVFile + "'.\n" + + "Element passed: '" + node + "' is inside the '" + containingFile + "' which is in '" + containingVFile + "'"); + } + } + public Annotation createInfoAnnotation(@NotNull TextRange range, String message) { return createAnnotation(range, HighlightSeverity.INFORMATION, message); } @@ -96,12 +128,19 @@ public class AnnotationHolderImpl extends SmartList implements Annot return !isEmpty(); } - public void setSession(AnnotationSession annotationSession) { + void setSession(@NotNull AnnotationSession annotationSession) { myAnnotationSession = annotationSession; } @Override + @NotNull("it's not null during highlighting") public AnnotationSession getCurrentAnnotationSession() { return myAnnotationSession; } + + @Override + public void clear() { + super.clear(); + myAnnotationSession = null; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index dbe80edbfb88..f47c0f942784 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -276,7 +276,7 @@ class DaemonListeners implements Disposable { if (document == null) return true; if (project != null && project != myProject) return false; // cached is essential here since we do not want to create PSI file in alien project - PsiFile psiFile = PsiDocumentManager.getInstance(project == null ? myProject : project).getPsiFile(document); + PsiFile psiFile = PsiDocumentManager.getInstance(project == null ? myProject : project).getCachedPsiFile(document); return psiFile != null; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java similarity index 94% rename from platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java rename to platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java index 8b3f93c51071..1d2f5e256b31 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/DefaultHighlightVisitor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightVisitor.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.intellij.codeInsight.daemon.impl.analysis; +package com.intellij.codeInsight.daemon.impl; -import com.intellij.codeInsight.daemon.impl.*; +import com.intellij.codeInsight.daemon.impl.analysis.ErrorQuickFixProvider; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder; import com.intellij.codeInsight.highlighting.HighlightErrorFilter; import com.intellij.lang.Language; import com.intellij.lang.LanguageAnnotators; @@ -109,7 +110,7 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware { }); } - private void runAnnotators(final PsiElement element, final HighlightInfoHolder holder, final AnnotationHolderImpl annotationHolder) { + private void runAnnotators(PsiElement element, HighlightInfoHolder holder, AnnotationHolderImpl annotationHolder) { List annotators = cachedAnnotators.get(element.getLanguage()); if (annotators.isEmpty()) return; final boolean dumb = myDumbService.isDumb(); @@ -129,9 +130,8 @@ public class DefaultHighlightVisitor implements HighlightVisitor, DumbAware { for (Annotation annotation : annotationHolder) { holder.add(HighlightInfo.fromAnnotation(annotation)); } - annotationHolder.clear(); } - annotationHolder.setSession(null); + annotationHolder.clear(); } private void visitErrorElement(final PsiErrorElement element, HighlightInfoHolder myHolder) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java index 2903c74a3cdb..77241e53a278 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java @@ -22,6 +22,7 @@ import com.intellij.codeInsight.daemon.impl.analysis.HighlightLevelUtil; import com.intellij.lang.ExternalLanguageAnnotators; import com.intellij.lang.Language; import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationSession; import com.intellij.lang.annotation.ExternalAnnotator; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressIndicator; @@ -50,7 +51,7 @@ public class ExternalToolPass extends TextEditorHighlightingPass { myFile = file; myStartOffset = startOffset; myEndOffset = endOffset; - myAnnotationHolder = new AnnotationHolderImpl(); + myAnnotationHolder = new AnnotationHolderImpl(new AnnotationSession(file)); } public void doCollectInformation(ProgressIndicator progress) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightInfoHolder.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightInfoHolder.java index 519586f65d49..84df3efe441f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightInfoHolder.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightInfoHolder.java @@ -58,6 +58,7 @@ public class HighlightInfoHolder { myAnnotationSession = new AnnotationSession(contextFile); } + @NotNull public AnnotationSession getAnnotationSession() { return myAnnotationSession; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java index fd51dfb8adf2..439458ac256e 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/AnnotatorBasedInspection.java @@ -23,10 +23,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInspection.ex.JobDescriptor; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageAnnotators; -import com.intellij.lang.annotation.Annotation; -import com.intellij.lang.annotation.AnnotationHolder; -import com.intellij.lang.annotation.Annotator; -import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.lang.annotation.*; import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; @@ -87,18 +84,30 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool { return "Annotator"; } - private static class MyPsiRecursiveElementVisitor extends PsiRecursiveElementVisitor - implements PsiLanguageInjectionHost.InjectedPsiVisitor { - private final AnnotationHolder myHolder; + private static class MyPsiRecursiveElementVisitor extends PsiRecursiveElementVisitor implements PsiLanguageInjectionHost.InjectedPsiVisitor { + private AnnotationHolderImpl myHolder; private List annotators; private PsiFile myFile; + private final InspectionManager myManager; private final GlobalInspectionContext myGlobalContext; + private final ProblemDescriptionsProcessor myProblemDescriptionsProcessor; public MyPsiRecursiveElementVisitor(final InspectionManager manager, final GlobalInspectionContext globalContext, final ProblemDescriptionsProcessor problemDescriptionsProcessor) { + myManager = manager; myGlobalContext = globalContext; - myHolder = new AnnotationHolderImpl() { + myProblemDescriptionsProcessor = problemDescriptionsProcessor; + } + + @Override + public void visitFile(PsiFile file) { + myFile = file; + final VirtualFile virtualFile = myFile.getVirtualFile(); + if (virtualFile != null) { + myGlobalContext.incrementJobDoneAmount(ANNOTATOR, ProjectUtil.calcRelativeToProjectPath(virtualFile, myFile.getProject())); + } + myHolder = new AnnotationHolderImpl(new AnnotationSession(file)) { @Override public Annotation createErrorAnnotation(@NotNull PsiElement elt, String message) { return createProblem(elt, message, ProblemHighlightType.ERROR, HighlightSeverity.ERROR, null); @@ -125,7 +134,7 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool { HighlightSeverity severity, TextRange range) { GlobalInspectionUtil - .createProblem(elt, message, problemHighlightType, range, manager, problemDescriptionsProcessor, globalContext); + .createProblem(elt, message, problemHighlightType, range, myManager, myProblemDescriptionsProcessor, myGlobalContext); return super.createAnnotation(elt.getTextRange(), severity, message); } @@ -152,21 +161,12 @@ public class AnnotatorBasedInspection extends GlobalInspectionTool { @Override protected Annotation createAnnotation(TextRange range, HighlightSeverity severity, String message) { if (severity != HighlightSeverity.INFORMATION) { - GlobalInspectionUtil.createProblem(myFile, message, HighlightInfo.convertSeverityToProblemHighlight(severity), range, manager, - problemDescriptionsProcessor, globalContext); + GlobalInspectionUtil.createProblem(myFile, message, HighlightInfo.convertSeverityToProblemHighlight(severity), range, myManager, + myProblemDescriptionsProcessor, myGlobalContext); } return super.createAnnotation(range, severity, message); } }; - } - - @Override - public void visitFile(PsiFile file) { - myFile = file; - final VirtualFile virtualFile = myFile.getVirtualFile(); - if (virtualFile != null) { - myGlobalContext.incrementJobDoneAmount(ANNOTATOR, ProjectUtil.calcRelativeToProjectPath(virtualFile, myFile.getProject())); - } super.visitFile(file); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java index a39140be981d..a94619bc2f9f 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/SyntaxErrorInspection.java @@ -18,7 +18,7 @@ package com.intellij.codeInspection; import com.intellij.analysis.AnalysisScope; import com.intellij.codeHighlighting.HighlightDisplayLevel; -import com.intellij.codeInsight.daemon.impl.analysis.DefaultHighlightVisitor; +import com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor; import com.intellij.codeInsight.highlighting.HighlightErrorFilter; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.TextRange; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java index 8d5501ca6622..e1948a1711f1 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixWrapper.java @@ -44,9 +44,10 @@ public class QuickFixWrapper implements IntentionAction { public static IntentionAction wrap(@NotNull ProblemDescriptor descriptor, int fixNumber) { LOG.assertTrue(fixNumber > -1); - LOG.assertTrue(descriptor.getFixes() != null && descriptor.getFixes().length > fixNumber); + QuickFix[] fixes = descriptor.getFixes(); + LOG.assertTrue(fixes != null && fixes.length > fixNumber); - final QuickFix fix = descriptor.getFixes()[fixNumber]; + final QuickFix fix = fixes[fixNumber]; return fix instanceof IntentionAction ? (IntentionAction)fix : new QuickFixWrapper(descriptor, fixNumber); } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 3d7ad9371fa0..7b7f2513907a 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -252,9 +252,6 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public void showRunContent(@NotNull final Executor executor, final RunContentDescriptor descriptor) { if(ApplicationManager.getApplication().isUnitTestMode()) return; - final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(executor.getToolWindowId()); - final boolean wasInActiveWindow = toolWindow != null && toolWindow.isActive(); - final ContentManager contentManager = getContentManagerForRunner(executor); RunContentDescriptor oldDescriptor = chooseReuseContentForDescriptor(contentManager, descriptor); @@ -311,17 +308,13 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(executor.getToolWindowId()); - if (wasInActiveWindow) { - window.activate(null, true, false); - } else { - // let's activate tool window, but don't move focus - // - // window.show() isn't valid here, because it will not - // mark the window as "last activated" windows and thus - // some action like navigation up/down in stactrace wont - // work correctly - window.activate(null, false, false); - } + // let's activate tool window, but don't move focus + // + // window.show() isn't valid here, because it will not + // mark the window as "last activated" windows and thus + // some action like navigation up/down in stactrace wont + // work correctly + window.activate(null, false, false); } }); } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocUrlChooser.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/ui/Util.java similarity index 57% rename from platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocUrlChooser.java rename to platform/lang-impl/src/com/intellij/openapi/projectRoots/ui/Util.java index 25558069392e..ff23ce84c6cd 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocUrlChooser.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/ui/Util.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * 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. @@ -13,55 +13,51 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.roots.libraries.doc; +package com.intellij.openapi.projectRoots.ui; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.net.MalformedURLException; import java.net.URL; /** - * @author Rustam Vishnyakov + * @author MYakovlev + * Date: Oct 29, 2002 + * Time: 8:47:43 PM */ -public class DocUrlChooser { +public class Util{ - private DocUrlChooser() { + public static VirtualFile showSpecifyJavadocUrlDialog(JComponent parent) { + return showSpecifyJavadocUrlDialog(parent, ""); } - @Nullable - public static VirtualFile showSpecifyDocUrlDialog(JComponent parent) { - return showSpecifyDocUrlDialog(parent, ""); - } - - @Nullable - public static VirtualFile showSpecifyDocUrlDialog(JComponent parent, String initialValue) { + public static VirtualFile showSpecifyJavadocUrlDialog(JComponent parent, String initialValue){ final String url = Messages.showInputDialog(parent, ProjectBundle.message("sdk.configure.javadoc.url.prompt"), - ProjectBundle.message("sdk.configure.javadoc.url.title"), Messages.getQuestionIcon(), - initialValue, new InputValidator() { - public boolean checkInput(String inputString) { + ProjectBundle.message("sdk.configure.javadoc.url.title"), Messages.getQuestionIcon(), initialValue, new InputValidator() { + public boolean checkInput(String inputString) { + return true; + } + public boolean canClose(String inputString) { + try { + new URL(inputString); return true; } - - public boolean canClose(String inputString) { - try { - new URL(inputString); - return true; - } - catch (MalformedURLException e1) { - Messages.showErrorDialog(e1.getMessage(), ProjectBundle.message("sdk.configure.javadoc.url.title")); - } - return false; + catch (MalformedURLException e1) { + Messages.showErrorDialog(e1.getMessage(), ProjectBundle.message("sdk.configure.javadoc.url.title")); } - }); + return false; + } + }); if (url == null) { return null; } return VirtualFileManager.getInstance().findFileByUrl(url); } + + } diff --git a/java/openapi/src/com/intellij/openapi/roots/JavadocOrderRootType.java b/platform/lang-impl/src/com/intellij/openapi/roots/JavadocOrderRootType.java similarity index 100% rename from java/openapi/src/com/intellij/openapi/roots/JavadocOrderRootType.java rename to platform/lang-impl/src/com/intellij/openapi/roots/JavadocOrderRootType.java diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocOrderRootType.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocOrderRootType.java deleted file mode 100644 index f35dfe2d3c07..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocOrderRootType.java +++ /dev/null @@ -1,34 +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.openapi.roots.libraries.doc; - -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.PersistentOrderRootType; - -public class DocOrderRootType extends PersistentOrderRootType { - - private DocOrderRootType() { - super("DOCUMENTATION", "docPath", "doc-paths", "docPathEntry"); - } - - public static OrderRootType getInstance() { - return getOrderRootType(DocOrderRootType.class); - } - - public boolean collectFromDependentModules() { - return true; - } -} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocOrderRootTypeUIFactory.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocOrderRootTypeUIFactory.java deleted file mode 100644 index 9ba6a01c047d..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/doc/DocOrderRootTypeUIFactory.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.openapi.roots.libraries.doc; - -import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.ui.PathEditor; -import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory; -import com.intellij.openapi.util.IconLoader; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -/** - * @author Rustam Vishnyakov - */ -public class DocOrderRootTypeUIFactory implements OrderRootTypeUIFactory { - private static final Icon ICON = IconLoader.getIcon("/nodes/javaDocFolder.png"); - - @Nullable - public PathEditor createPathEditor(Sdk sdk) { - return null; - } - - @Override - public Icon getIcon() { - return ICON; - } - - @Override - public String getNodeText() { - return ProjectBundle.message("library.docs.node"); - } - -} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryManager.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryManager.java index 21f87d865d8e..394ee97ae426 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryManager.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryManager.java @@ -18,6 +18,7 @@ package com.intellij.openapi.roots.libraries.scripting; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.roots.JavadocOrderRootType; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; @@ -25,7 +26,6 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; import com.intellij.openapi.roots.libraries.LibraryType; -//import com.intellij.openapi.roots.libraries.doc.DocOrderRootType; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; @@ -81,7 +81,7 @@ public class ScriptingLibraryManager { } private void updateLibraries(LibraryTable.ModifiableModel libTableModel) { - //final OrderRootType docRootType = DocOrderRootType.getInstance(); + final OrderRootType docRootType = JavadocOrderRootType.getInstance(); for (Library library : libTableModel.getLibraries()) { ScriptingLibraryTable.LibraryModel scriptingLibModel = myLibTable.getLibraryByName(library.getName()); if (scriptingLibModel == null) { @@ -91,11 +91,9 @@ public class ScriptingLibraryManager { Library.ModifiableModel libModel = library.getModifiableModel(); removeRoots(libModel, OrderRootType.CLASSES); removeRoots(libModel, OrderRootType.SOURCES); - /* - for (String docUrl : libModel.getUrls(DocOrderRootType.getInstance())) { + for (String docUrl : libModel.getUrls(JavadocOrderRootType.getInstance())) { libModel.removeRoot(docUrl, docRootType); } - */ addAllRoots(libModel, scriptingLibModel); libModel.commit(); } @@ -118,14 +116,12 @@ public class ScriptingLibraryManager { } private static void addAllRoots(Library.ModifiableModel libModel, ScriptingLibraryTable.LibraryModel srcModel) { - //final OrderRootType docRootType = DocOrderRootType.getInstance(); + final OrderRootType docRootType = JavadocOrderRootType.getInstance(); addRoots(libModel, srcModel, OrderRootType.CLASSES); addRoots(libModel, srcModel, OrderRootType.SOURCES); - /* for (String docUrl : srcModel.getDocUrls()) { libModel.addRoot(docUrl, docRootType); } - */ } private static void addRoots(Library.ModifiableModel libModel, diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java index bb03f0f9e727..202f11bbf7eb 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/scripting/ScriptingLibraryTable.java @@ -15,12 +15,12 @@ */ package com.intellij.openapi.roots.libraries.scripting; +import com.intellij.openapi.roots.JavadocOrderRootType; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryType; -import com.intellij.openapi.roots.libraries.doc.DocOrderRootType; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashSet; @@ -52,7 +52,7 @@ public class ScriptingLibraryTable { LibraryModel libModel = new LibraryModel(library.getName()); libModel.setSourceFiles(library.getFiles(SOURCE_ROOT_TYPE)); libModel.setCompactFiles(library.getFiles(COMPACT_ROOT_TYPE)); - //libModel.setDocUrls(library.getUrls(DocOrderRootType.getInstance())); // TODO: Rustam, write tests first! + libModel.setDocUrls(library.getUrls(JavadocOrderRootType.getInstance())); myLibraryModels.add(libModel); } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index d597b53c006a..6ea3c5b79d57 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -464,6 +464,10 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec if (file.getTextLength() != document.getTextLength()) { if (ApplicationManagerEx.getApplicationEx().isInternal()) { + boolean x = false; + if (x) { + myBlockSupport.reparseRange(file, startOffset, endOffset, lengthShift, chars); + } throw new AssertionError("commitDocument left PSI inconsistent; file len=" + file.getTextLength() + "; doc len=" + document.getTextLength() + "; file text=" + file.getText() + diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java index 3d381bc62953..0d908bc140c3 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/LightPsiFileImpl.java @@ -49,7 +49,7 @@ public abstract class LightPsiFileImpl extends PsiElementBase implements PsiFile private final PsiManagerImpl myManager; private final Language myLanguage; - public LightPsiFileImpl(final FileViewProvider provider, final Language language) { + public LightPsiFileImpl(@NotNull FileViewProvider provider, @NotNull Language language) { myViewProvider = provider; myManager = (PsiManagerImpl)provider.getManager(); myLanguage = language; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java index 5d3a7f9af145..4765185d4220 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java @@ -20,6 +20,7 @@ import com.intellij.diagnostic.PerformanceWatcher; import com.intellij.extapi.psi.ASTDelegatePsiElement; import com.intellij.lang.*; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.pom.tree.events.ChangeInfo; @@ -54,6 +55,7 @@ public class CompositeElement extends TreeElement { private volatile int myCachedLength = NOT_CACHED; private volatile int myHC = -1; private volatile PsiElement myWrapper = null; + private static final boolean ASSERT_THREADING = DebugUtil.CHECK || ApplicationManagerEx.getApplicationEx().isInternal() || ApplicationManagerEx.getApplicationEx().isUnitTestMode(); public CompositeElement(@NotNull IElementType type) { super(type); @@ -66,13 +68,15 @@ public class CompositeElement extends TreeElement { public Object clone() { CompositeElement clone = (CompositeElement)super.clone(); - clone.clearCaches(); - clone.firstChild = null; - clone.lastChild = null; - clone.myModificationsCount = 0; - clone.myWrapper = null; - for (ASTNode child = rawFirstChild(); child != null; child = child.getTreeNext()) { - clone.rawAddChildren((TreeElement)child.clone()); + synchronized (PsiLock.LOCK) { + clone.clearCaches(); + clone.firstChild = null; + clone.lastChild = null; + clone.myModificationsCount = 0; + clone.myWrapper = null; + for (ASTNode child = rawFirstChild(); child != null; child = child.getTreeNext()) { + clone.rawAddChildren((TreeElement)child.clone()); + } } return clone; } @@ -98,7 +102,7 @@ public class CompositeElement extends TreeElement { } public void clearCaches() { - if (DebugUtil.CHECK) { + if (ASSERT_THREADING) { PsiElement wrapper = myWrapper; LOG.assertTrue(ApplicationManager.getApplication().isWriteAccessAllowed() || Thread.holdsLock(PsiLock.LOCK) || @@ -120,20 +124,28 @@ public class CompositeElement extends TreeElement { } public LeafElement findLeafElementAt(int offset) { - TreeElement child = getFirstChildNode(); - while (child != null) { - final int textLength = child.getTextLength(); - if (textLength > offset) { - if (child instanceof ForeignLeafPsiElement) { - child = child.getTreeNext(); - continue; + TreeElement element = this; + startFind: + while (true) { + TreeElement child = element.getFirstChildNode(); + while (child != null) { + final int textLength = child.getTextLength(); + if (textLength > offset) { + if (child instanceof LeafElement) { + if (child instanceof ForeignLeafPsiElement) { + child = child.getTreeNext(); + continue; + } + return (LeafElement)child; + } + element = child; + continue startFind; } - return child.findLeafElementAt(offset); + offset -= textLength; + child = child.getTreeNext(); } - offset -= textLength; - child = child.getTreeNext(); + return null; } - return null; } public ASTNode findChildByType(IElementType type) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java index 8b1193bc797e..6e6166010d65 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/TreeElement.java @@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLock; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.ElementBase; import com.intellij.psi.impl.PsiManagerEx; @@ -44,12 +45,14 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea public Object clone() { TreeElement clone = (TreeElement)super.clone(); - clone.clearCaches(); + synchronized (PsiLock.LOCK) { + clone.clearCaches(); - clone.myNextSibling = null; - clone.myPrevSibling = null; - clone.myParent = null; - clone.myStartOffsetInParent = -1; + clone.myNextSibling = null; + clone.myPrevSibling = null; + clone.myParent = null; + clone.myStartOffsetInParent = -1; + } return clone; } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileContent.java b/platform/lang-impl/src/com/intellij/util/indexing/FileContent.java index 55908f4429a0..994a51ff0a02 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileContent.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileContent.java @@ -42,9 +42,9 @@ public final class FileContent extends UserDataHolderBase { private final VirtualFile myFile; private final String fileName; private final FileType myFileType; - private Charset myCharset; + private final Charset myCharset; private byte[] myContent; - private CharSequence myContentAsText = null; + private CharSequence myContentAsText; public Project getProject() { return getUserData(FileBasedIndex.PROJECT); @@ -81,26 +81,25 @@ public final class FileContent extends UserDataHolderBase { public IllegalDataException(final String message) { super(message); } - - public IllegalDataException(final String message, final Throwable cause) { - super(message, cause); - } } public FileContent(@NotNull final VirtualFile file, @NotNull final CharSequence contentAsText, final Charset charset) { - this(file); - myContentAsText = contentAsText; - myCharset = charset; + this(file, contentAsText, null, charset); } public FileContent(@NotNull final VirtualFile file, @NotNull final byte[] content) { - this(file); - myContent = content; - myCharset = LoadTextUtil.detectCharsetAndSetBOM(file, content); + this(file, null, content, LoadTextUtil.detectCharsetAndSetBOM(file, content)); } public FileContent(@NotNull final VirtualFile file) { + this(file, null, null, null); + } + + private FileContent(@NotNull VirtualFile file, CharSequence contentAsText, byte[] content, Charset charset) { myFile = file; + myContentAsText = contentAsText; + myContent = content; + myCharset = charset; myFileType = FileTypeManager.getInstance().getFileTypeByFile(file); // remember name explicitly because the file could be renamed afterwards fileName = file.getName(); diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java index fce09d52ee38..7d3d2e5a46b7 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java @@ -16,7 +16,6 @@ package com.intellij.history.integration; -import com.intellij.history.core.Content; import com.intellij.history.core.LocalHistoryFacade; import com.intellij.history.core.Paths; import com.intellij.history.core.StoredContent; @@ -53,7 +52,7 @@ import java.util.Collections; import java.util.List; public class IdeaGateway { - private static final Key> SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY + private static final Key SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY = Key.create("LocalHistory.SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY"); public boolean isVersioned(VirtualFile f) { @@ -170,17 +169,17 @@ public class IdeaGateway { if (!file.isDirectory()) { if (!isVersioned(file)) return null; - Content c; + Pair contentAndStamps; if (forDeletion) { FileDocumentManager m = FileDocumentManager.getInstance(); Document d = m.getCachedDocument(file); // should not try to load document if (d != null && !m.isDocumentUnsaved(d)) d = null; - c = acquireAndClearCurrentContent(file, d); + contentAndStamps = acquireAndClearCurrentContent(file, d); } else { - c = getActualContentNoAcquire(file); + contentAndStamps = getActualContentNoAcquire(file); } - return new FileEntry(file.getName(), c, file.getTimeStamp(), !file.isWritable()); + return new FileEntry(file.getName(), contentAndStamps.first, contentAndStamps.second, !file.isWritable()); } DirectoryEntry newDir = new DirectoryEntry(file.getName()); doCreateChildren(newDir, iterateDBChildren(file), forDeletion); @@ -203,7 +202,6 @@ public class IdeaGateway { VirtualFile f = getFile(d); if (!shouldRegisterDocument(f)) continue; registerDocumentContents(vcs, f, d); - registerDocumentContents(vcs, f, d); } vcs.endChangeSet(null); } @@ -216,70 +214,74 @@ public class IdeaGateway { } private void registerDocumentContents(LocalHistoryFacade vcs, VirtualFile f, Document d) { - Content content = acquireAndUpdateActualContent(f, d); - if (content != null) { - vcs.contentChanged(f.getPath(), content, Clock.getTime()); + Pair contentAndStamp = acquireAndUpdateActualContent(f, d); + if (contentAndStamp != null) { + vcs.contentChanged(f.getPath(), contentAndStamp.first, contentAndStamp.second); } } // returns null is content has not been changes since last time @Nullable - public Content acquireAndUpdateActualContent(VirtualFile f, @Nullable Document d) { - Pair contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); + public Pair acquireAndUpdateActualContent(VirtualFile f, @Nullable Document d) { + ContentAndTimestamps contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); if (contentAndStamp == null) { if (d != null) saveDocumentContent(f, d); - return StoredContent.acquireContent(f); + return Pair.create(StoredContent.acquireContent(f), f.getTimeStamp()); } - StoredContent content = contentAndStamp.first; - // if no need to save current document content when simply return and clear stored one if (d == null) { f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY, null); - return content; + return Pair.create(contentAndStamp.content, contentAndStamp.registeredTimestamp); } // if the stored content equals the current one, do not store it and return null - if (d.getModificationStamp() == contentAndStamp.second) return null; + if (d.getModificationStamp() == contentAndStamp.documentModificationStamp) return null; // is current content has been changed, store it and return the previous one saveDocumentContent(f, d); - return content; + return Pair.create(contentAndStamp.content, contentAndStamp.registeredTimestamp); } private void saveDocumentContent(VirtualFile f, Document d) { f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY, - Pair.create(StoredContent.acquireContent(bytesFromDocument(d)), d.getModificationStamp())); + new ContentAndTimestamps(Clock.getTime(), + StoredContent.acquireContent(bytesFromDocument(d)), + d.getModificationStamp())); } - public Content acquireAndClearCurrentContent(VirtualFile f, @Nullable Document d) { - Pair contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); + @NotNull + public Pair acquireAndClearCurrentContent(VirtualFile f, @Nullable Document d) { + ContentAndTimestamps contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY, null); if (d != null && contentAndStamp != null) { // if previously stored content was not changed, return it - if (d.getModificationStamp() == contentAndStamp.second) return contentAndStamp.first; + if (d.getModificationStamp() == contentAndStamp.documentModificationStamp) { + return Pair.create(contentAndStamp.content, contentAndStamp.registeredTimestamp); + } } // release previously stored if (contentAndStamp != null) { - contentAndStamp.first.release(); + contentAndStamp.content.release(); } // take document's content if any if (d != null) { - return StoredContent.acquireContent(bytesFromDocument(d)); + return Pair.create(StoredContent.acquireContent(bytesFromDocument(d)), Clock.getTime()); } - return StoredContent.acquireContent(f); + return Pair.create(StoredContent.acquireContent(f), f.getTimeStamp()); } - private Content getActualContentNoAcquire(VirtualFile f) { - Pair result = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); + @NotNull + private Pair getActualContentNoAcquire(VirtualFile f) { + ContentAndTimestamps result = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY); if (result == null) { - return StoredContent.transientContent(f); + return Pair.create(StoredContent.transientContent(f), f.getTimeStamp()); } - return result.first; + return Pair.create(result.content, result.registeredTimestamp); } private byte[] bytesFromDocument(Document d) { @@ -319,4 +321,16 @@ public class IdeaGateway { public FileType getFileType(String fileName) { return FileTypeManager.getInstance().getFileTypeByFileName(fileName); } + + private static class ContentAndTimestamps { + long registeredTimestamp; + StoredContent content; + long documentModificationStamp; + + private ContentAndTimestamps(long registeredTimestamp, StoredContent content, long documentModificationStamp) { + this.registeredTimestamp = registeredTimestamp; + this.content = content; + this.documentModificationStamp = documentModificationStamp; + } + } } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryEventDispatcher.java b/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryEventDispatcher.java index 00180edb042b..55dedc6a0334 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryEventDispatcher.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryEventDispatcher.java @@ -16,12 +16,13 @@ package com.intellij.history.integration; -import com.intellij.history.core.Content; import com.intellij.history.core.LocalHistoryFacade; +import com.intellij.history.core.StoredContent; import com.intellij.history.core.tree.Entry; import com.intellij.openapi.command.CommandEvent; import com.intellij.openapi.command.CommandListener; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.*; public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements VirtualFileManagerListener, CommandListener { @@ -102,9 +103,9 @@ public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements V if (!areContentChangesVersioned(e)) return; VirtualFile f = e.getFile(); - Content content = myGateway.acquireAndUpdateActualContent(f, null); + Pair content = myGateway.acquireAndUpdateActualContent(f, null); if (content != null) { - myVcs.contentChanged(f.getPath(), content, f.getTimeStamp()); + myVcs.contentChanged(f.getPath(), content.first, content.second); } } diff --git a/platform/lvcs-impl/testSrc/com/intellij/history/integration/GettingContentAtDateTest.java b/platform/lvcs-impl/testSrc/com/intellij/history/integration/GettingContentAtDateTest.java index 5369a4cedc60..8ba94f744223 100644 --- a/platform/lvcs-impl/testSrc/com/intellij/history/integration/GettingContentAtDateTest.java +++ b/platform/lvcs-impl/testSrc/com/intellij/history/integration/GettingContentAtDateTest.java @@ -19,6 +19,8 @@ package com.intellij.history.integration; import com.intellij.history.FileRevisionTimestampComparator; import com.intellij.history.LocalHistory; +import com.intellij.history.LocalHistoryAction; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.util.Clock; import com.intellij.openapi.vfs.VirtualFile; @@ -37,7 +39,7 @@ public class GettingContentAtDateTest extends IntegrationTestCase { assertContentAt(0, null); assertContentAt(TIMESTAMP_INCREMENT, "1"); - assertContentAt(TIMESTAMP_INCREMENT + TIMESTAMP_INCREMENT/ 2, null); + assertContentAt(TIMESTAMP_INCREMENT + TIMESTAMP_INCREMENT / 2, null); assertContentAt(TIMESTAMP_INCREMENT * 2, "2"); assertContentAt(TIMESTAMP_INCREMENT * 3, null); } @@ -77,6 +79,51 @@ public class GettingContentAtDateTest extends IntegrationTestCase { assertContentAt(c, "2"); } + public void testWithUnsavedDocuments() throws Exception { + setContent(f, "FILE1", TIMESTAMP_INCREMENT); + + Clock.setTime(TIMESTAMP_INCREMENT * 2); + LocalHistoryAction a = LocalHistory.getInstance().startAction(null); + setDocumentTextFor(f, "DOC1"); + a.finish(); + + Clock.setTime(TIMESTAMP_INCREMENT * 3); + a = LocalHistory.getInstance().startAction(null); + setDocumentTextFor(f, "DOC2"); + a.finish(); + + FileDocumentManager.getInstance().saveAllDocuments(); + setContent(f, "FILE2", TIMESTAMP_INCREMENT * 4); + + assertContentAt(new FileRevisionTimestampComparator() { + @Override + public boolean isSuitable(long revisionTimestamp) { + return revisionTimestamp == TIMESTAMP_INCREMENT * 4; + } + }, "FILE2"); + + assertContentAt(new FileRevisionTimestampComparator() { + @Override + public boolean isSuitable(long revisionTimestamp) { + return revisionTimestamp == TIMESTAMP_INCREMENT * 3; + } + }, "DOC2"); + + assertContentAt(new FileRevisionTimestampComparator() { + @Override + public boolean isSuitable(long revisionTimestamp) { + return revisionTimestamp == TIMESTAMP_INCREMENT * 2; + } + }, "DOC1"); + + assertContentAt(new FileRevisionTimestampComparator() { + @Override + public boolean isSuitable(long revisionTimestamp) { + return revisionTimestamp == TIMESTAMP_INCREMENT; + } + }, "FILE1"); + } + private void assertContentAt(long timestamp, String expected) { assertContentAt(comparator(timestamp), expected); } diff --git a/platform/platform-api/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java b/platform/platform-api/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java index 292374f251aa..9dd680be9ab5 100644 --- a/platform/platform-api/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java +++ b/platform/platform-api/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java @@ -134,10 +134,10 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor { String internalVersionString = pluginBean.formatVersion; if (internalVersionString != null) { try { - final int formatVersion = Integer.parseInt(internalVersionString); + Integer.parseInt(internalVersionString); } catch (NumberFormatException e) { - LOG.error(new PluginException("Invalid value in plugin.xml format version: " + internalVersionString, e, myId)); + LOG.error(new PluginException("Invalid value in plugin.xml format version: '" + internalVersionString+"'", e, myId)); } } myUseIdeaClassLoader = pluginBean.useIdeaClassLoader; @@ -189,7 +189,7 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor { hsPathes.add(hsPath); } } - myHelpSets = hsPathes.size()>0 ? hsPathes.toArray(new HelpSetPath[hsPathes.size()]) : HelpSetPath.EMPTY; + myHelpSets = !hsPathes.isEmpty() ? hsPathes.toArray(new HelpSetPath[hsPathes.size()]) : HelpSetPath.EMPTY; myAppComponents = pluginBean.applicationComponents; myProjectComponents = pluginBean.projectComponents; @@ -203,15 +203,6 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor { myExtensionsPoints = copyElements(pluginBean.extensionPoints); myActionsElements = copyElements(pluginBean.actions); - if (pluginBean.extensionPoints != null) { - myExtensionsPoints = new ArrayList(); - for (Element root : pluginBean.extensionPoints) { - for (Object o : root.getChildren()) { - myExtensionsPoints.add((Element)o); - } - } - } - if (pluginBean.modules != null && !pluginBean.modules.isEmpty()) { myModules = pluginBean.modules; } @@ -393,9 +384,7 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor { final IdeaPluginDescriptorImpl pluginDescriptor = (IdeaPluginDescriptorImpl)o; - if (myName != null ? !myName.equals(pluginDescriptor.myName) : pluginDescriptor.myName != null) return false; - - return true; + return myName == null ? pluginDescriptor.myName == null : myName.equals(pluginDescriptor.myName); } public int hashCode() { diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/AnActionListener.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/AnActionListener.java index 879080c80312..4196cb979931 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/AnActionListener.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/AnActionListener.java @@ -28,9 +28,25 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.AnActionEvent; +/** + * @author Kirill Kalishev + * @author Konstantin Bulenkov + */ public interface AnActionListener { void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event); + void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event); - + void beforeEditorTyping(char c, DataContext dataContext); + + class Adapter implements AnActionListener { + @Override + public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {} + + @Override + public void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {} + + @Override + public void beforeEditorTyping(char c, DataContext dataContext) {} + } } 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 73c9c83df603..a4e841865565 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java @@ -368,9 +368,13 @@ public class HintManagerImpl extends HintManager implements Disposable { Dimension size = hint.getComponent().getPreferredSize(); if (hint.isRealPopup()) { + final Point editorCorner = editor.getContentComponent().getLocation(); + SwingUtilities.convertPointToScreen(editorCorner, layeredPane); + final Rectangle editorScreen = ScreenUtil.getScreenRectangle(editorCorner.x, editorCorner.y); + SwingUtilities.convertPointToScreen(p, layeredPane); final Rectangle rectangle = new Rectangle(p, size); - ScreenUtil.moveRectangleToFitTheScreen(rectangle); + ScreenUtil.moveToFit(rectangle, editorScreen, null); p = rectangle.getLocation(); SwingUtilities.convertPointFromScreen(p, layeredPane); } diff --git a/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java b/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java index 567e0ab7b217..3c5b8277af29 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java +++ b/platform/platform-impl/src/com/intellij/execution/process/RunnerMediator.java @@ -121,8 +121,7 @@ public class RunnerMediator { return true; } else if (isUnix()) { - UnixProcessManager.sendSigKillToProcessTree(process); - return true; + return UnixProcessManager.sendSigKillToProcessTree(process); } else { return false; diff --git a/platform/platform-impl/src/com/intellij/execution/process/UnixProcessManager.java b/platform/platform-impl/src/com/intellij/execution/process/UnixProcessManager.java index c37a9c77a2ff..74a90971617a 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/UnixProcessManager.java +++ b/platform/platform-impl/src/com/intellij/execution/process/UnixProcessManager.java @@ -71,20 +71,20 @@ public class UnixProcessManager { } } - public static void sendSigIntToProcessTree(Process process) { - sendSignalToProcessTree(process, SIGINT); + public static boolean sendSigIntToProcessTree(Process process) { + return sendSignalToProcessTree(process, SIGINT); } - public static void sendSigKillToProcessTree(Process process) { - sendSignalToProcessTree(process, SIGKILL); + public static boolean sendSigKillToProcessTree(Process process) { + return sendSignalToProcessTree(process, SIGKILL); } /** * Sends signal to every child process of a tree root process - * @param process tree root process * + * @param process tree root process */ - public static void sendSignalToProcessTree(Process process, int signal) { + public static boolean sendSignalToProcessTree(Process process, int signal) { checkCLib(); int our_pid = C_LIB.getpid(); @@ -101,6 +101,10 @@ public class UnixProcessManager { InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); + + List childrenPids = Lists.newArrayList(); + + boolean result; try { String s; stdInput.readLine(); //ps output header @@ -113,6 +117,10 @@ public class UnixProcessManager { processInfo.register(pid, parent_pid); + if (parent_pid == process_pid) { + childrenPids.add(pid); + } + if (pid == process_pid) { if (parent_pid == our_pid) { foundPid = pid; @@ -125,9 +133,13 @@ public class UnixProcessManager { if (foundPid != 0) { processInfo.killProcTree(foundPid, signal); + result = true; } else { - throw new IllegalStateException("process not found: " + process_pid + ", idea pid =" + our_pid); + for (Integer pid : childrenPids) { + processInfo.killProcTree(pid, signal); + } + result = false; } StringBuffer errorStr = new StringBuffer(); @@ -142,6 +154,7 @@ public class UnixProcessManager { stdInput.close(); stdError.close(); } + return result; } catch (IOException e) { throw new IllegalStateException(e); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index db6c59b2358a..afac6bc7359a 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -246,9 +246,10 @@ public class InstalledPluginsTableModel extends PluginTableModel { public void setValue(final IdeaPluginDescriptorImpl ideaPluginDescriptor, Boolean value) { final PluginId currentPluginId = ideaPluginDescriptor.getPluginId(); - myEnabled.put(currentPluginId, myEnabled.get(currentPluginId) == null ? Boolean.FALSE : value); + final Boolean enabled = myEnabled.get(currentPluginId) == null ? Boolean.FALSE : value; + myEnabled.put(currentPluginId, enabled); updatePluginDependencies(); - if (value.booleanValue()) { + if (enabled.booleanValue()) { final Set deps = new HashSet(); PluginManager.checkDependants(ideaPluginDescriptor, new Function() { @Nullable 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 6ee2170e3097..97c7f27a0238 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 @@ -2300,8 +2300,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi private int drawStringWithSoftWraps(Graphics g, final char[] text, - int start, - int end, + final int start, + final int end, Point position, Rectangle clip, Color effectColor, @@ -2403,7 +2403,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } // Draw remaining soft wrap symbols from its last line if any. - if (softWrapSegmentStartIndex < softWrapChars.length - 1) { + if (softWrapSegmentStartIndex < softWrapChars.length) { position.x += drawString( g, softWrapChars, softWrapSegmentStartIndex, softWrapChars.length, position, clip, effectColor, effectType, fontType, fontColor diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java index b53444981631..52d7ef908387 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java @@ -19,6 +19,7 @@ import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.RangeMarker; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.CollectionFactory; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -29,6 +30,9 @@ import java.util.Comparator; * User: cdr */ abstract class FoldRegionsTree { + + public static final boolean DEBUG = Boolean.getBoolean("idea.editor.debug.folding"); + private FoldRegion[] myCachedVisible; private FoldRegion[] myCachedTopLevelRegions; private int[] myCachedEndOffsets; @@ -189,6 +193,7 @@ abstract class FoldRegionsTree { return true; } + @Nullable FoldRegion fetchOutermost(int offset) { if (!isFoldingEnabledAndUpToDate()) return null; @@ -206,6 +211,19 @@ abstract class FoldRegionsTree { start = i + 1; } else { + // We encountered situation when cached data is inconsistent. It's not clear what produced that, so, the following was done: + // 1. Corresponding check was added and cached data is rebuilt in case of inconsistency; + // 2. Debug asserts are activated if dedicated flag is on (it's off by default); + if (myCachedStartOffsets[i] != myCachedTopLevelRegions[i].getStartOffset()) { + if (DEBUG) { + assert false : + "inconsistent cached fold data detected. Start offsets: " + Arrays.toString(myCachedStartOffsets) + + ", end offsets: " + Arrays.toString(myCachedEndOffsets) + ", top regions: " + Arrays.toString(myCachedTopLevelRegions) + + ", visible regions: " + Arrays.toString(myCachedVisible); + } + rebuild(); + return fetchOutermost(offset); + } return myCachedTopLevelRegions[i]; } } @@ -218,6 +236,7 @@ abstract class FoldRegionsTree { return myCachedVisible; } + @Nullable FoldRegion[] fetchTopLevel() { if (!isFoldingEnabledAndUpToDate()) return null; return myCachedTopLevelRegions; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index 7799c6888ebe..af88b5231bd8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -446,11 +446,14 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi if (!isInsideSoftWrap(visualCaretPosition)) { return; } - //TODO den implement - //if (myDocumentChangeManager.makeHardWrap(caretModel.getOffset())) { - // // Restore caret position. - // caretModel.moveToVisualPosition(visualCaretPosition); - //} + + SoftWrap softWrap = myStorage.getSoftWrap(caretModel.getOffset()); + if (softWrap == null) { + return; + } + + myEditor.getDocument().replaceString(softWrap.getStart(), softWrap.getEnd(), softWrap.getText()); + caretModel.moveToVisualPosition(visualCaretPosition); } @Override diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 3a31799492af..f0b0d5d7fca5 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -16,6 +16,11 @@ package com.intellij.ui; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupListener; @@ -367,6 +372,12 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi Toolkit.getDefaultToolkit().addAWTEventListener(myAwtActivityListener, MouseEvent.MOUSE_EVENT_MASK | MouseEvent.MOUSE_MOTION_EVENT_MASK | KeyEvent.KEY_EVENT_MASK); + ActionManager.getInstance().addAnActionListener(new AnActionListener.Adapter() { + @Override + public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) { + hide(); + } + }, this); } private Rectangle getRecForPosition(Position position, boolean adjust) { diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java index f051b7849536..d7d990ba6573 100644 --- a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java +++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java @@ -538,6 +538,36 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP assertEquals(expectedVisualLine, caretModel.getVisualPosition().line); } + public void testSoftWrapToHardWrapConversion() throws IOException { + String text = + "this is line 1\n" + + "this is line 2\n" + + "this is line 3\n" + + "this is line 4\n" + + "this is line 5"; + + init(50, text); + VisualPosition changePosition = new VisualPosition(1, 0); + myEditor.getCaretModel().moveToVisualPosition(changePosition); + + int logicalLinesBefore = myEditor.offsetToLogicalPosition(text.length()).line; + int offsetBefore = myEditor.getCaretModel().getOffset(); + + LogicalPosition logicalPositionBefore = myEditor.visualToLogicalPosition(changePosition); + assertEquals(1, logicalPositionBefore.softWrapLinesOnCurrentLogicalLine); + assertTrue(logicalPositionBefore.column > 0); + + SoftWrap softWrap = getSoftWrapModel().getSoftWrap(offsetBefore); + assertNotNull(softWrap); + + type('a'); + + LogicalPosition logicalPositionAfter = myEditor.visualToLogicalPosition(changePosition); + assertEquals(new LogicalPosition(1, 0, 0, 0, 0, 0, 0), logicalPositionAfter); + assertEquals(offsetBefore + softWrap.getText().length() + 1, myEditor.getCaretModel().getOffset()); + assertEquals(logicalLinesBefore + 1, myEditor.offsetToLogicalPosition(text.length()).line); + } + //public void testPastingInsideSelection() throws IOException { // String text = // "this is line number 0\n" + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 29c7db525740..108f7b5677a2 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -318,7 +318,7 @@ - + diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java index fec6a86ca164..be782f3f3d0d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java @@ -174,10 +174,17 @@ public class TestsPresentationUtil { SimpleTextAttributes.REGULAR_ATTRIBUTES); } else { - renderer.setIcon(PoolOfTestIcons.NOT_RAN); - renderer.append(SMTestsRunnerBundle.message( + if (!testProxy.getChildren().isEmpty()) { + // some times test proxy may be updated faster than tests tree + // so let's process such situation correctly + formatRootNodeWithChildren(testProxy, renderer); + } + else { + renderer.setIcon(PoolOfTestIcons.NOT_RAN); + renderer.append(SMTestsRunnerBundle.message( "sm.test.runner.ui.tests.tree.presentation.labels.no.tests.were.found"), - SimpleTextAttributes.ERROR_ATTRIBUTES); + SimpleTextAttributes.ERROR_ATTRIBUTES); + } } } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java index a03233a91efd..4d8593646f1b 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtilTest.java @@ -536,6 +536,23 @@ public class TestsPresentationUtilTest extends BaseSMTRunnerTestCase { } + public void testFormatRootNodeWithoutChildren_PY_2434() { + // See [PY-2434] Unittest: Do not show "No test were found" notification before completing test suite + mySuite.addChild(mySimpleTest); + mySuite.setStarted(); + mySimpleTest.setStarted(); + mySimpleTest.setTestFailed("msg", "stacktrace", false); + mySimpleTest.setFinished(); + mySuite.setFinished(); + TestsPresentationUtil.formatRootNodeWithoutChildren(mySuite, myRenderer); + + assertEquals(PoolOfTestIcons.FAILED_ICON, myRenderer.getIcon()); + assertOneElement(myFragContainer.getFragments()); + assertEquals("Test Results:", myFragContainer.getTextAt(0)); + assertEquals(SimpleTextAttributes.REGULAR_ATTRIBUTES, myFragContainer.getAttribsAt(0)); + } + + public void testGetPresentableName() { //Test unit examples assertProxyPresentation("testFirst", "MyRubyTest1", "MyRubyTest1.testFirst"); 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 5750eb21ad51..34b301878989 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -1148,6 +1148,10 @@ public class StringUtil { } if (name.endsWith("ies")) { + if (name.endsWith("cookies") || name.endsWith("Cookies")) { + return name.substring(0, name.length() - "ookies".length()) + "ookie"; + } + return name.substring(0, name.length() - 3) + "y"; } diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java index a3954c1b16ce..43b0045c6b5c 100644 --- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java +++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java @@ -219,7 +219,11 @@ public class PagedFileStorage implements Forceable { buffer.position(page_offset); } catch (IllegalArgumentException iae) { - throw new IllegalArgumentException("can't position buffer to offset " + page_offset); + throw new IllegalArgumentException("can't position buffer to offset " + page_offset + ", " + + "buffer.limit=" + buffer.limit() + ", " + + "page=" + page + ", " + + "file=" + myFile.getName() + ", "+ + "file.length=" + mySize); } buffer.get(dst, o, page_len); diff --git a/platform/util/src/com/intellij/util/messages/MessageBus.java b/platform/util/src/com/intellij/util/messages/MessageBus.java index 5357be7c17c4..1503eb29677d 100644 --- a/platform/util/src/com/intellij/util/messages/MessageBus.java +++ b/platform/util/src/com/intellij/util/messages/MessageBus.java @@ -23,16 +23,21 @@ package com.intellij.util.messages; import com.intellij.openapi.Disposable; +import org.jetbrains.annotations.NotNull; /** * Use ComponentManager.getMessageBus() to obtain one. */ public interface MessageBus { + @NotNull MessageBusConnection connect(); - MessageBusConnection connect(Disposable parentDisposable); + @NotNull + MessageBusConnection connect(@NotNull Disposable parentDisposable); - L syncPublisher(Topic topic); - L asyncPublisher(Topic topic); + @NotNull + L syncPublisher(@NotNull Topic topic); + @NotNull + L asyncPublisher(@NotNull Topic topic); void dispose(); } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java b/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java index b1d8884e67e3..f0ad663f76b2 100644 --- a/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java +++ b/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java @@ -73,6 +73,11 @@ public class MessageBusConnectionImpl implements MessageBusConnection { } public void disconnect() { + Queue jobs = myPendingMessages.get(); + if (!jobs.isEmpty()) { + LOG.error("Not delivered events in the queue: "+jobs); + } + myPendingMessages.remove(); myBus.notifyConnectionTerminated(this); } diff --git a/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java b/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java index 1da8698b4db7..98a732c49eaa 100644 --- a/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java +++ b/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java @@ -20,12 +20,14 @@ package com.intellij.util.messages.impl; import com.intellij.openapi.Disposable; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Disposer; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.messages.Topic; +import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -38,6 +40,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; public class MessageBusImpl implements MessageBus { + private static final Logger LOG = Logger.getInstance("#com.intellij.util.messages.impl.MessageBusImpl"); private final ThreadLocal> myMessageQueue = new ThreadLocal>() { @Override protected Queue initialValue() { @@ -84,20 +87,28 @@ public class MessageBusImpl implements MessageBus { public final MessageBusConnectionImpl connection; public final Message message; + + @Override + public String toString() { + return "{ DJob connection:" + connection.toString() + "; message: " + message + " }"; + } } + @NotNull public MessageBusConnection connect() { return new MessageBusConnectionImpl(this); } - public MessageBusConnection connect(Disposable parentDisposable) { + @NotNull + public MessageBusConnection connect(@NotNull Disposable parentDisposable) { final MessageBusConnection connection = connect(); Disposer.register(parentDisposable, connection); return connection; } + @NotNull @SuppressWarnings({"unchecked"}) - public L syncPublisher(final Topic topic) { + public L syncPublisher(@NotNull final Topic topic) { L publisher = (L)mySyncPublishers.get(topic); if (publisher == null) { final Class listenerClass = topic.getListenerClass(); @@ -113,8 +124,9 @@ public class MessageBusImpl implements MessageBus { return publisher; } + @NotNull @SuppressWarnings({"unchecked"}) - public L asyncPublisher(final Topic topic) { + public L asyncPublisher(@NotNull final Topic topic) { L publisher = (L)myAsyncPublishers.get(topic); if (publisher == null) { final Class listenerClass = topic.getListenerClass(); @@ -131,7 +143,10 @@ public class MessageBusImpl implements MessageBus { } public void dispose() { - myMessageQueue.get().clear(); + Queue jobs = myMessageQueue.get(); + if (!jobs.isEmpty()) { + LOG.error("Not delivered events in the queue: "+jobs); + } myMessageQueue.remove(); if (myParentBus != null) { myParentBus.notifyChildBusDisposed(this); @@ -218,4 +233,4 @@ public class MessageBusImpl implements MessageBus { if (job == null) return; job.connection.deliverMessage(job.message); } -} \ No newline at end of file +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 620b77996263..9858ae25140c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -378,6 +378,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec myUpdateException = null; composite.cleanAll(); } + if (LOG.isDebugEnabled()) { + LOG.debug("refresh procedure started, everything = " + wasEverythingDirty); + } } if (wasEverythingDirty) { changeListWorker.notifyStartProcessingChanges(null); @@ -450,6 +453,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } if (takeChanges) { + if (LOG.isDebugEnabled()) { + LOG.debug("refresh procedure finished, size: " + composite.getVFHolder(FileHolder.HolderType.UNVERSIONED).getSize()); + } final boolean statusChanged = ! myComposite.equals(composite); myComposite = composite; if (statusChanged) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java index bd2f5eeaf533..f462a5744e5e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java @@ -31,6 +31,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.SimpleToolWindowPanel; @@ -81,6 +82,7 @@ public class ChangesViewManager implements ChangesViewI, JDOMExternalizable, Pro @NonNls private static final String ATT_FLATTENED_VIEW = "flattened_view"; @NonNls private static final String ATT_SHOW_IGNORED = "show_ignored"; + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.ChangesViewManager"); public static ChangesViewI getInstance(Project project) { return PeriodicalTasksCloser.getInstance().safeGetComponent(project, ChangesViewI.class); @@ -208,7 +210,10 @@ public class ChangesViewManager implements ChangesViewI, JDOMExternalizable, Pro @Override public void scheduleRefresh() { if (ApplicationManager.getApplication().isHeadlessEnvironment()) return; - myRepaintAlarm.cancelAllRequests(); + int was = myRepaintAlarm.cancelAllRequests(); + if (LOG.isDebugEnabled()) { + LOG.debug("schedule refresh, was " + was); + } myRepaintAlarm.addRequest(new Runnable() { public void run() { refreshView(); @@ -228,6 +233,10 @@ public class ChangesViewManager implements ChangesViewI, JDOMExternalizable, Pro new Trinity, Integer, Integer>(manyUnversioned ? Collections.emptyList() : changeListManager.getUnversionedFiles(), unv.getFirst(), unv.getSecond()); + if (LOG.isDebugEnabled()) { + LOG.debug("refresh view, unversioned collections size: " + unversionedPair.getFirst().size() + " unv size passed: " + + unversionedPair.getSecond() + " dirs: " + unversionedPair.getThird()); + } myView.updateModel(changeListManager.getChangeListsCopy(), unversionedPair, changeListManager.getDeletedFiles(), changeListManager.getModifiedWithoutEditing(), diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java index 54de6e72daa9..5c4ea14bb1de 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java @@ -95,13 +95,19 @@ public class ApplyPatchAction extends DumbAwareAction { } }; FileDocumentManager.getInstance().saveAllDocuments(); - final FileChooserDialog fileChooserDialog = FileChooserFactory.getInstance().createFileChooser( - ApplyPatchDifferentiatedDialog.createSelectPatchDescriptor(), project); - final VirtualFile[] files = fileChooserDialog.choose(null, project); - if (files.length != 1) { - return; + final VirtualFile toUse; + if (file != null) { + toUse = file; + } else { + final FileChooserDialog fileChooserDialog = FileChooserFactory.getInstance().createFileChooser( + ApplyPatchDifferentiatedDialog.createSelectPatchDescriptor(), project); + final VirtualFile[] files = fileChooserDialog.choose(null, project); + if (files.length != 1) { + return; + } + toUse = files[0]; } - final ApplyPatchDifferentiatedDialog dialog = new ApplyPatchDifferentiatedDialog(project, callback, files[0]); + final ApplyPatchDifferentiatedDialog dialog = new ApplyPatchDifferentiatedDialog(project, callback, toUse); dialog.show(); } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java index 0bdb0a9c08ba..4f606dedd7a0 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java @@ -130,5 +130,5 @@ public interface XDebugSession extends AbstractDebuggerSession { void smartStepInto(XSmartStepIntoHandler handler, V variant); - void updateExecutionPosition(); + void updateExecutionPosition(boolean updateBreakpoints); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index fdb673cf755f..633ad0165fb7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -60,7 +60,8 @@ import java.util.*; public class XDebugSessionImpl implements XDebugSession { private static final Logger LOG = Logger.getInstance("#com.intellij.xdebugger.impl.XDebugSessionImpl"); private XDebugProcess myDebugProcess; - private final Map, CustomizedBreakpointPresentation> myRegisteredBreakpoints = new HashMap, CustomizedBreakpointPresentation>(); + private final Map, CustomizedBreakpointPresentation> myRegisteredBreakpoints = + new HashMap, CustomizedBreakpointPresentation>(); private final Set> myDisabledSlaveBreakpoints = new HashSet>(); private boolean myBreakpointsMuted; private boolean myBreakpointsDisabled; @@ -80,11 +81,15 @@ public class XDebugSessionImpl implements XDebugSession { private boolean myStopped; private boolean myPauseActionSupported; - public XDebugSessionImpl(final @NotNull ExecutionEnvironment env, final @NotNull ProgramRunner runner, XDebuggerManagerImpl debuggerManager) { + public XDebugSessionImpl(final @NotNull ExecutionEnvironment env, + final @NotNull ProgramRunner runner, + XDebuggerManagerImpl debuggerManager) { this(env, runner, debuggerManager, env.getRunProfile().getName()); } - public XDebugSessionImpl(final @Nullable ExecutionEnvironment env, final @Nullable ProgramRunner runner, XDebuggerManagerImpl debuggerManager, + public XDebugSessionImpl(final @Nullable ExecutionEnvironment env, + final @Nullable ProgramRunner runner, + XDebuggerManagerImpl debuggerManager, final @NotNull String sessionName) { myEnvironment = env; myRunner = runner; @@ -189,7 +194,7 @@ public class XDebugSessionImpl implements XDebugSession { private void disableSlaveBreakpoints(final XDependentBreakpointManager dependentBreakpointManager) { Set> slaveBreakpoints = dependentBreakpointManager.getAllSlaveBreakpoints(); - Set> breakpointTypes = new HashSet>(); + Set> breakpointTypes = new HashSet>(); for (XBreakpointHandler handler : myDebugProcess.getBreakpointHandlers()) { breakpointTypes.add(getBreakpointTypeClass(handler)); } @@ -204,8 +209,10 @@ public class XDebugSessionImpl implements XDebugSession { return XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass()); } - private > void processBreakpoints(final XBreakpointHandler handler, boolean register, final boolean temporary) { - XBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass()); + private > void processBreakpoints(final XBreakpointHandler handler, + boolean register, + final boolean temporary) { + XBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass()); Collection breakpoints = myDebuggerManager.getBreakpointManager().getBreakpoints(type); for (B b : breakpoints) { handleBreakpoint(handler, b, register, temporary); @@ -247,7 +254,9 @@ public class XDebugSessionImpl implements XDebugSession { } } - private > void processBreakpoint(final XBreakpoint breakpoint, final XBreakpointHandler handler, boolean register) { + private > void processBreakpoint(final XBreakpoint breakpoint, + final XBreakpointHandler handler, + boolean register) { XBreakpointType type = breakpoint.getType(); if (handler.getBreakpointTypeClass().equals(type.getClass())) { //noinspection unchecked @@ -349,16 +358,19 @@ public class XDebugSessionImpl implements XDebugSession { * Causes the same effect as #positionReached, but without changing context, * only updating position highlighting and re-enabling exceptions */ - public void updateExecutionPosition() { + public void updateExecutionPosition(boolean updateBreakpoints) { XExecutionStack activeExecutionStack = mySuspendContext.getActiveExecutionStack(); boolean isTopFrame = activeExecutionStack != null && activeExecutionStack.getTopFrame() == myCurrentStackFrame; myDebuggerManager.updateExecutionPoint(myCurrentStackFrame.getSourcePosition(), !isTopFrame); - disableBreakpoints(); - enableBreakpoints(); + if (updateBreakpoints) { + disableBreakpoints(); + enableBreakpoints(); + } } + public void showExecutionPoint() { if (mySuspendContext != null) { XExecutionStack executionStack = mySuspendContext.getActiveExecutionStack(); @@ -396,7 +408,9 @@ public class XDebugSessionImpl implements XDebugSession { } } - public void updateBreakpointPresentation(@NotNull final XLineBreakpoint breakpoint, @Nullable final Icon icon, @Nullable final String errorMessage) { + public void updateBreakpointPresentation(@NotNull final XLineBreakpoint breakpoint, + @Nullable final Icon icon, + @Nullable final String errorMessage) { CustomizedBreakpointPresentation presentation; synchronized (myRegisteredBreakpoints) { presentation = myRegisteredBreakpoints.get(breakpoint); @@ -420,8 +434,8 @@ public class XDebugSessionImpl implements XDebugSession { String condition = breakpoint.getCondition(); if (condition != null && evaluator != null) { LOG.debug("evaluating condition: " + condition); - boolean result = evaluator.evaluateCondition(condition); - LOG.debug("condition evaluates to " + result); + boolean result = evaluator.evaluateCondition(condition); + LOG.debug("condition evaluates to " + result); if (!result) { return false; } @@ -430,7 +444,8 @@ public class XDebugSessionImpl implements XDebugSession { if (breakpoint.isLogMessage()) { String text = StringUtil.decapitalize(XBreakpointUtil.getDisplayText(breakpoint)); final XSourcePosition position = breakpoint.getSourcePosition(); - final OpenFileHyperlinkInfo hyperlinkInfo = position != null ? new OpenFileHyperlinkInfo(myProject, position.getFile(), position.getLine()) : null; + final OpenFileHyperlinkInfo hyperlinkInfo = + position != null ? new OpenFileHyperlinkInfo(myProject, position.getFile(), position.getLine()) : null; printMessage(XDebuggerBundle.message("xbreakpoint.reached.text") + " ", text, hyperlinkInfo); } @@ -553,7 +568,7 @@ public class XDebugSessionImpl implements XDebugSession { public void stop() { ProcessHandler processHandler = myDebugProcess.getProcessHandler(); - if (processHandler.isProcessTerminated() || processHandler.isProcessTerminating()) return; + if (processHandler.isProcessTerminated() || processHandler.isProcessTerminating()) return; if (processHandler.detachIsDefault()) { processHandler.detachProcess(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java index 699fe826fc82..15726fdebcb6 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/SimplifiableAnnotationInspection.java @@ -101,17 +101,17 @@ public class SimplifiableAnnotationInspection extends BaseInspection { return; } final PsiNameValuePair[] attributes = parameterList.getAttributes(); - final PsiElement[] annotationChildren = annotation.getChildren(); if (annotationChildren.length >= 2) { final PsiElement child = annotationChildren[1]; if (child instanceof PsiWhiteSpace) { + final String annotationName = nameReferenceElement.getText(); final String replacementText; if (attributes.length > 0) { - replacementText = '@' + nameReferenceElement.getText() + + replacementText = '@' + annotationName + parameterList.getText(); } else { - replacementText = '@' + nameReferenceElement.getText(); + replacementText = '@' + annotationName; } registerError(annotation, replacementText); return; @@ -122,15 +122,23 @@ public class SimplifiableAnnotationInspection extends BaseInspection { if (children.length <= 0) { return; } - registerError(annotation, '@' + nameReferenceElement.getText()); + final String annotationName = nameReferenceElement.getText(); + registerError(annotation, '@' + annotationName); } else if (attributes.length == 1) { final PsiNameValuePair attribute = attributes[0]; @NonNls final String name = attribute.getName(); if (!"value".equals(name)) { return; } - registerError(annotation, '@' + nameReferenceElement.getText() + - '(' + attribute.getValue().getText() + ')'); + final PsiAnnotationMemberValue attributeValue = + attribute.getValue(); + if (attributeValue == null) { + return; + } + final String annotationName = nameReferenceElement.getText(); + final String replacementText = '@' + annotationName + + '(' + attributeValue.getText() + ')'; + registerError(annotation, replacementText); } } } diff --git a/plugins/android/resources/fileTemplates/j2ee/layoutResourceFile.xml.ft b/plugins/android/resources/fileTemplates/j2ee/layoutResourceFile.xml.ft new file mode 100644 index 000000000000..e82645c452d7 --- /dev/null +++ b/plugins/android/resources/fileTemplates/j2ee/layoutResourceFile.xml.ft @@ -0,0 +1,7 @@ + + +<${ROOT_TAG} xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + \ No newline at end of file diff --git a/plugins/android/resources/fileTemplates/j2ee/layoutResourceFile.xml.html b/plugins/android/resources/fileTemplates/j2ee/layoutResourceFile.xml.html new file mode 100644 index 000000000000..9de2a16808c1 --- /dev/null +++ b/plugins/android/resources/fileTemplates/j2ee/layoutResourceFile.xml.html @@ -0,0 +1,5 @@ + + +

This is a built-in file template used to create layout xml files in Android applications.

+ + \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/AndroidCompletionContributor.java b/plugins/android/src/org/jetbrains/android/AndroidCompletionContributor.java index d668822e65e2..c215d9993146 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidCompletionContributor.java +++ b/plugins/android/src/org/jetbrains/android/AndroidCompletionContributor.java @@ -15,19 +15,13 @@ */ package org.jetbrains.android; -import com.android.sdklib.SdkConstants; import com.intellij.codeInsight.completion.CompletionContributor; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import org.jetbrains.android.dom.AndroidDomExtender; @@ -38,7 +32,6 @@ import org.jetbrains.android.dom.manifest.ManifestDomFileDescription; import org.jetbrains.android.dom.xml.AndroidXmlResourcesUtil; import org.jetbrains.android.dom.xml.XmlResourceDomFileDescription; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.facet.AndroidRootUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; @@ -56,24 +49,6 @@ public class AndroidCompletionContributor extends CompletionContributor { } } - private static boolean containsNamespace(@NotNull XmlTag tag, @NotNull String namespace) { - for (XmlAttribute attribute : tag.getAttributes()) { - if ("xmlns:android".equals(attribute.getName()) && namespace.equals(attribute.getValue())) { - return true; - } - } - return false; - } - - private static boolean isXmlResource(@NotNull AndroidFacet facet, @NotNull VirtualFile file) { - String extension = FileUtil.getExtension(file.getName()); - if (!extension.equals("xml")) return false; - VirtualFile parent = file.getParent(); - if (parent == null) return false; - parent = parent.getParent(); - return parent != null && facet.getLocalResourceManager().isResourceDir(parent); - } - private static boolean complete(@NotNull AndroidFacet facet, PsiElement position, CompletionResultSet resultSet) { PsiElement parent = position.getParent(); if (parent instanceof XmlTag) { @@ -90,18 +65,10 @@ public class AndroidCompletionContributor extends CompletionContributor { resultSet.addElement(LookupElementBuilder.create("view")); resultSet.addElement(LookupElementBuilder.create("merge")); Map viewClassMap = AndroidDomExtender.getViewClassMap(facet); - final PsiClass viewGroupClass = viewClassMap.get("ViewGroup"); for (String tagName : viewClassMap.keySet()) { final PsiClass viewClass = viewClassMap.get(tagName); if (!AndroidUtils.isAbstract(viewClass)) { - boolean inheritsViewGroup = ApplicationManager.getApplication().runReadAction(new Computable() { - public Boolean compute() { - return viewClass.isInheritor(viewGroupClass, true); - } - }); - if (inheritsViewGroup) { - resultSet.addElement(LookupElementBuilder.create(tagName)); - } + resultSet.addElement(LookupElementBuilder.create(tagName)); } } return false; @@ -117,27 +84,6 @@ public class AndroidCompletionContributor extends CompletionContributor { } } } - VirtualFile containingFile = parent.getContainingFile().getOriginalFile().getVirtualFile(); - if (containingFile != null && - (isXmlResource(facet, containingFile) || AndroidRootUtil.getManifestFile(facet.getModule()) == containingFile)) { - if (parent instanceof XmlAttribute) { - XmlAttribute attribute = (XmlAttribute)parent; - XmlTag tag = attribute.getParent(); - if (!containsNamespace(tag, SdkConstants.NS_RESOURCES)) { - String prefix = attribute.getNamespacePrefix(); - String s = null; - if (prefix.length() == 0) { - s = "xmlns:android"; - } - else if (prefix.equals("xmlns")) { - s = "android"; - } - if (s != null) { - resultSet.addElement(LookupElementBuilder.create(s)); - } - } - } - } return true; } diff --git a/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java b/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java index 4bdf95c686c4..660aa42babc8 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidFileTemplateProvider.java @@ -40,6 +40,7 @@ public class AndroidFileTemplateProvider implements FileTemplateGroupDescriptorF @NonNls public static final String ANDROID_MANIFEST_TEMPLATE = SdkConstants.FN_ANDROID_MANIFEST_XML; @NonNls public static final String VALUE_RESOURCE_FILE_TEMPLATE = "valueResourceFile.xml"; @NonNls public static final String RESOURCE_FILE_TEMPLATE = "resourceFile.xml"; + @NonNls public static final String LAYOUT_RESOURCE_FILE_TEMPLATE = "layoutResourceFile.xml"; @NonNls public static final String ACTIVITY = "Activity.java"; @NonNls public static final String SERVICE = "Service.java"; @NonNls public static final String BROADCAST_RECEIVER = "Broadcast Receiver.java"; @@ -49,6 +50,7 @@ public class AndroidFileTemplateProvider implements FileTemplateGroupDescriptorF group.addTemplate(new FileTemplateDescriptor(ANDROID_MANIFEST_TEMPLATE, StdFileTypes.XML.getIcon())); group.addTemplate(new FileTemplateDescriptor(VALUE_RESOURCE_FILE_TEMPLATE, StdFileTypes.XML.getIcon())); group.addTemplate(new FileTemplateDescriptor(RESOURCE_FILE_TEMPLATE, StdFileTypes.XML.getIcon())); + group.addTemplate(new FileTemplateDescriptor(LAYOUT_RESOURCE_FILE_TEMPLATE, StdFileTypes.XML.getIcon())); group.addTemplate(new FileTemplateDescriptor(ACTIVITY, StdFileTypes.JAVA.getIcon())); group.addTemplate(new FileTemplateDescriptor(SERVICE, StdFileTypes.JAVA.getIcon())); group.addTemplate(new FileTemplateDescriptor(BROADCAST_RECEIVER, StdFileTypes.JAVA.getIcon())); diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java b/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java index e14b17d24be5..13b2f2aa9d07 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java @@ -102,7 +102,7 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase { @Override protected PsiElement[] create(String newName, PsiDirectory directory) throws Exception { FileTemplateManager manager = FileTemplateManager.getInstance(); - String templateName = myValuesResourceFile ? AndroidFileTemplateProvider.VALUE_RESOURCE_FILE_TEMPLATE : AndroidFileTemplateProvider.RESOURCE_FILE_TEMPLATE; + String templateName = getTemplateName(); FileTemplate template = manager.getJ2eeTemplate(templateName); Properties properties = new Properties(); if (!myValuesResourceFile) { @@ -135,35 +135,45 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase { return new PsiElement[]{createdElement}; } - /* private void invokeCompletion(Project project, final Editor editor, XmlFile file) { - new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(project, editor, file, 1); - CompletionProgressIndicator indicator = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); - if (indicator != null) { - final LookupImpl lookup = indicator.getLookup(); - lookup.setAdditionalPrefix(myDefaultRootTag); - lookup.addLookupListener(new LookupAdapter() { - boolean prefixCanceled; - - @Override - public void itemSelected(LookupEvent event) { - TemplateManagerImpl.getTemplateState(editor).gotoEnd(); - } - - @Override - public void currentItemChanged(LookupEvent event) { - if (!prefixCanceled) { - prefixCanceled = true; - lookup.setAdditionalPrefix(""); - } - } - - @Override - public void lookupCanceled(LookupEvent event) { - } - }); + private String getTemplateName() { + if (myValuesResourceFile) { + return AndroidFileTemplateProvider.VALUE_RESOURCE_FILE_TEMPLATE; } + if ("layout".equals(myResourceType)) { + return AndroidFileTemplateProvider.LAYOUT_RESOURCE_FILE_TEMPLATE; + } + return AndroidFileTemplateProvider.RESOURCE_FILE_TEMPLATE; } -*/ + + /* private void invokeCompletion(Project project, final Editor editor, XmlFile file) { + new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(project, editor, file, 1); + CompletionProgressIndicator indicator = CompletionServiceImpl.getCompletionService().getCurrentCompletion(); + if (indicator != null) { + final LookupImpl lookup = indicator.getLookup(); + lookup.setAdditionalPrefix(myDefaultRootTag); + lookup.addLookupListener(new LookupAdapter() { + boolean prefixCanceled; + + @Override + public void itemSelected(LookupEvent event) { + TemplateManagerImpl.getTemplateState(editor).gotoEnd(); + } + + @Override + public void currentItemChanged(LookupEvent event) { + if (!prefixCanceled) { + prefixCanceled = true; + lookup.setAdditionalPrefix(""); + } + } + + @Override + public void lookupCanceled(LookupEvent event) { + } + }); + } + } + */ @Override protected boolean isAvailable(DataContext context) { if (!super.isAvailable(context)) return false; diff --git a/plugins/android/testData/dom/layout/textViewRootTag.xml b/plugins/android/testData/dom/layout/textViewRootTag.xml new file mode 100644 index 000000000000..c443e312343b --- /dev/null +++ b/plugins/android/testData/dom/layout/textViewRootTag.xml @@ -0,0 +1,3 @@ + + + diff --git a/plugins/android/testData/dom/layout/textViewRootTag_after.xml b/plugins/android/testData/dom/layout/textViewRootTag_after.xml new file mode 100644 index 000000000000..eccb65c92634 --- /dev/null +++ b/plugins/android/testData/dom/layout/textViewRootTag_after.xml @@ -0,0 +1,3 @@ + + + infos = new ArrayList(myUnusedImports.size()); for (GrImportStatement unusedImport : myUnusedImports) { Annotation annotation = annotationHolder.createWarningAnnotation(unusedImport, GroovyInspectionBundle.message("unused.import")); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index 6d8ef44a8573..67f34354b175 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -20,6 +20,7 @@ import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.event.DocumentAdapter; @@ -369,6 +370,10 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { final String exceptionText = writer.toString(); LOG.info(exceptionText); + if (!ApplicationManagerEx.getApplicationEx().isInternal() && !ProjectRootManager.getInstance(project).getFileIndex().isInContent(vfile)) { + return; + } + ApplicationManager.getApplication().getMessageBus().syncPublisher(Notifications.TOPIC).notify( new Notification("Groovy DSL parsing", "DSL script execution error", "

" + e.getMessage() + "

Click here to investigate.

", NotificationType.ERROR, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java index 52287d65beeb..d6257eb572f2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java @@ -33,16 +33,22 @@ import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.reference.SoftReference; import com.intellij.util.PathUtil; +import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.lang.UrlClassLoader; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import java.net.URL; import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * @author ilyas, peter @@ -51,7 +57,7 @@ public class AntTasksProvider { private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.gant.AntTasksProvider"); public static final boolean antAvailable; private static final Key>> GANT_METHODS = Key.create("gantMethods"); - private static final Key>> ANT_OBJECTS = Key.create("antObjects"); + private static final Object ourLock = new Object(); private AntTasksProvider() { } @@ -96,68 +102,94 @@ public class AntTasksProvider { } private static Map getAntObjects(final GroovyFile groovyFile) { - return CachedValuesManager - .getManager(groovyFile.getProject()).getCachedValue(groovyFile, ANT_OBJECTS, new CachedValueProvider>() { + final Project project = groovyFile.getProject(); + + final Module module = ModuleUtil.findModuleForPsiElement(groovyFile); + Set jars = new HashSet(); + if (module != null) { + ContainerUtil.addAll(jars, OrderEnumerator.orderEntries(module).getAllLibrariesAndSdkClassesRoots()); + } + + if (groovyFile.isScript() && GroovyScriptTypeDetector.getScriptType(groovyFile) instanceof GantScriptType) { + jars.addAll(GantScriptType.additionalScopeFiles(groovyFile)); + } + + final ArrayList urls = new ArrayList(); + for (VirtualFile jar : jars) { + urls.add(VfsUtil.convertToURL(PathUtil.getLocalFile(jar).getUrl())); + } + + AntClassLoader loader; + synchronized (ourLock) { + final Map, SoftReference> map = CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider, SoftReference>>() { @Override - public Result> compute() { - final Module module = ModuleUtil.findModuleForPsiElement(groovyFile); - Set jars = new HashSet(); - if (module != null) { - ContainerUtil.addAll(jars, OrderEnumerator.orderEntries(module).getAllLibrariesAndSdkClassesRoots()); - } - - if (groovyFile.isScript() && GroovyScriptTypeDetector.getScriptType(groovyFile) instanceof GantScriptType) { - jars.addAll(GantScriptType.additionalScopeFiles(groovyFile)); - } - - final ArrayList urls = new ArrayList(); - for (VirtualFile jar : jars) { - urls.add(VfsUtil.convertToURL(PathUtil.getLocalFile(jar).getUrl())); - } - final ClassLoader loader = new UrlClassLoader(urls, null, false, false, true); - Future future = ApplicationManager.getApplication().executeOnPooledThread(new Callable() { - @Override - public ReflectedProject call() throws Exception { - try { - return ReflectedProject.getProject(loader); - } - catch (Exception e) { - LOG.error(e); - return null; - } - } - }); - - ReflectedProject antProject = null; - while (true) { - try { - antProject = future.get(100, TimeUnit.MILLISECONDS); - break; - } - catch (TimeoutException ignore) { - } - catch (Exception e) { - LOG.error(e); - break; - } - ProgressManager.checkCanceled(); - } - - final Map result = new HashMap(); - if (antProject != null) { - final Map taskDefinitions = antProject.getTaskDefinitions(); - if (taskDefinitions != null) { - result.putAll(taskDefinitions); - } - final Map dataTypeDefinitions = antProject.getDataTypeDefinitions(); - if (dataTypeDefinitions != null) { - result.putAll(dataTypeDefinitions); - } - } - return Result.create(result, ProjectRootManager.getInstance(groovyFile.getProject())); + public Result, SoftReference>> compute() { + final Map, SoftReference> map = CollectionFactory.hashMap(); + final Result, SoftReference>> result = Result.create(map, ProjectRootManager.getInstance(project)); + result.setLockValue(true); + return result; } + }); - }, false); + final SoftReference reference = map.get(urls); + loader = reference != null ? reference.get() : null; + if (loader == null) { + map.put(urls, new SoftReference(loader = new AntClassLoader(urls))); + } + } + + return loader.getAntObjects(); } + private static class AntClassLoader extends UrlClassLoader { + private final Future> myFuture; + + public AntClassLoader(ArrayList urls) { + super(urls, null, false, false, true); + myFuture = ApplicationManager.getApplication().executeOnPooledThread(new Callable>() { + @Override + public Map call() throws Exception { + try { + final ReflectedProject antProject = ReflectedProject.getProject(AntClassLoader.this); + final Map result = new HashMap(); + if (antProject != null) { + final Map taskDefinitions = antProject.getTaskDefinitions(); + if (taskDefinitions != null) { + result.putAll(taskDefinitions); + } + final Map dataTypeDefinitions = antProject.getDataTypeDefinitions(); + if (dataTypeDefinitions != null) { + result.putAll(dataTypeDefinitions); + } + } + return result; + } + catch (Exception e) { + LOG.error(e); + return null; + } + } + }); + } + + @NotNull + public Map getAntObjects() { + while (true) { + try { + final Map map = myFuture.get(100, TimeUnit.MILLISECONDS); + if (map != null) { + return map; + } + } + catch (TimeoutException ignore) { + } + catch (Exception e) { + LOG.error(e); + break; + } + ProgressManager.checkCanceled(); + } + return Collections.emptyMap(); + } + } } diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/util/MyPsiUtil.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/util/MyPsiUtil.java index 8011f4da163d..227a73c11d5f 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/util/MyPsiUtil.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/util/MyPsiUtil.java @@ -15,6 +15,7 @@ */ package org.intellij.plugins.xpathView.util; +import com.intellij.lang.annotation.AnnotationSession; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; @@ -138,7 +139,7 @@ public class MyPsiUtil { return false; } - public static String checkFile(PsiFile file) { + public static String checkFile(final PsiFile file) { final String[] error = new String[1]; file.accept(new PsiRecursiveElementVisitor() { public void visitErrorElement(PsiErrorElement element) { @@ -150,7 +151,7 @@ public class MyPsiUtil { final Annotator annotator = LanguageAnnotators.INSTANCE.forLanguage(file.getLanguage()); file.accept(new PsiRecursiveElementVisitor() { public void visitElement(PsiElement element) { - annotator.annotate(element, new AnnotationHolderImpl() { + annotator.annotate(element, new AnnotationHolderImpl(new AnnotationSession(file)) { public Annotation createErrorAnnotation(@NotNull ASTNode astNode, String string) { error[0] = string; return super.createErrorAnnotation(astNode, string); diff --git a/resources-en/src/intentionDescriptions/ColorChooserIntentionAction/before.java.template b/resources-en/src/intentionDescriptions/ColorChooserIntentionAction/before.java.template index e1af3cccc4b7..5648c0c0d891 100644 --- a/resources-en/src/intentionDescriptions/ColorChooserIntentionAction/before.java.template +++ b/resources-en/src/intentionDescriptions/ColorChooserIntentionAction/before.java.template @@ -1,3 +1,3 @@ class UiControl { - public static final Color COLOR = new Color(100, 120, 140); + public static final Color COLOR = new Color(100, 120, 140); } \ No newline at end of file diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 50db67284370..b564a995b7c7 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -853,10 +853,6 @@ implementationClass="com.intellij.openapi.roots.ui.configuration.libraryEditor.ClassesOrderRootTypeUIFactory"/> - @@ -939,8 +935,6 @@ - - diff --git a/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementsHighlightingUtil.java b/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementsHighlightingUtil.java index 21fe65029dec..8c2e60b7d67c 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementsHighlightingUtil.java +++ b/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementsHighlightingUtil.java @@ -16,8 +16,6 @@ package com.intellij.util.xml.highlighting; -import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl; -import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.LocalQuickFix; @@ -26,31 +24,23 @@ import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.editor.colors.CodeInsightColors; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.util.Function; +import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.Nullable; /** * User: Sergey.Vasiliev */ public class DomElementsHighlightingUtil { - - private static final AnnotationHolderImpl EMPTY_ANNOTATION_HOLDER = new AnnotationHolderImpl() { - public boolean add(final Annotation annotation) { - return false; - } - }; - private DomElementsHighlightingUtil() { } @Nullable - public static ProblemDescriptor createProblemDescriptors(final InspectionManager manager, - final DomElementProblemDescriptor problemDescriptor) { + public static ProblemDescriptor createProblemDescriptors(final InspectionManager manager, final DomElementProblemDescriptor problemDescriptor) { final ProblemHighlightType type = getProblemHighlightType(problemDescriptor); return createProblemDescriptors(problemDescriptor, new Function, ProblemDescriptor>() { public ProblemDescriptor fun(final Pair s) { @@ -82,12 +72,11 @@ public class DomElementsHighlightingUtil { String text = problemDescriptor.getDescriptionTemplate(); if (StringUtil.isEmpty(text)) text = null; final HighlightSeverity severity = problemDescriptor.getHighlightSeverity(); - final AnnotationHolderImpl holder = EMPTY_ANNOTATION_HOLDER; TextRange range = s.first; if (text == null) range = TextRange.from(range.getStartOffset(), 0); range = range.shiftRight(s.second.getTextRange().getStartOffset()); - final Annotation annotation = createAnnotation(severity, holder, range, text, s.second.getProject()); + final Annotation annotation = createAnnotation(severity, range, text); if (problemDescriptor instanceof DomElementResolveProblemDescriptor) { annotation.setTextAttributes(CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES); @@ -102,13 +91,10 @@ public class DomElementsHighlightingUtil { } private static Annotation createAnnotation(final HighlightSeverity severity, - final AnnotationHolderImpl holder, final TextRange range, - final String text, final Project project) { - if (SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.ERROR) >= 0) return holder.createErrorAnnotation(range, text); - if (SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.WARNING) >= 0) return holder.createWarningAnnotation(range, text); - if (SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.INFO) >= 0) return holder.createInformationAnnotation(range, text); - return holder.createInfoAnnotation(range, text); + final String text) { + String tooltip = text == null ? null : "" + XmlStringUtil.escapeString(text) + ""; + return new Annotation(range.getStartOffset(), range.getEndOffset(), severity, text, tooltip); } @Nullable diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java index 6781c1c22dd1..392bea39e0c0 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlSmartCompletionProvider.java @@ -15,7 +15,6 @@ */ package com.intellij.codeInsight.completion; -import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.PsiElement; @@ -64,13 +63,14 @@ public class XmlSmartCompletionProvider { } private static void addElementToResult(@NotNull XmlElementDescriptor descriptor, CompletionResultSet result) { - LookupElementBuilder builder = createLookupElement(descriptor); - result.addElement(builder.setInsertHandler(new InsertHandler() { - @Override - public void handleInsert(InsertionContext context, LookupElement item) { - XmlTagInsertHandler.INSTANCE.handleInsert(context, item); + XmlTagInsertHandler insertHandler = XmlTagInsertHandler.INSTANCE; + if (descriptor instanceof XmlElementDescriptorImpl) { + String name = descriptor.getName(); + if (name != null) { + insertHandler = new ExtendedTagInsertHandler(name, ((XmlElementDescriptorImpl)descriptor).getNamespace(), null); } - })); + } + result.addElement(createLookupElement(descriptor).setInsertHandler(insertHandler)); } public static LookupElementBuilder createLookupElement(@NotNull XmlElementDescriptor descriptor) { diff --git a/xml/impl/src/com/intellij/xml/util/AnchorReference.java b/xml/impl/src/com/intellij/xml/util/AnchorReference.java index 3b6ea0f67fa7..0b7d24be0a11 100644 --- a/xml/impl/src/com/intellij/xml/util/AnchorReference.java +++ b/xml/impl/src/com/intellij/xml/util/AnchorReference.java @@ -16,6 +16,8 @@ package com.intellij.xml.util; import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.psi.ElementManipulators; @@ -202,7 +204,12 @@ class AnchorReference implements PsiReference, EmptyResolveMessageProvider { final Map idMap = getIdMap(); if (idMap == null) return ArrayUtil.EMPTY_OBJECT_ARRAY; - return idMap.keySet().toArray(new Object[idMap.size()]); + String[] variants = idMap.keySet().toArray(new String[idMap.size()]); + LookupElement[] elements = new LookupElement[variants.length]; + for (int i = 0, variantsLength = variants.length; i < variantsLength; i++) { + elements[i] = LookupElementBuilder.create(variants[i]).setCaseSensitive(true); + } + return elements; } @Nullable