From 7b0cfd3eb8198e899f848a7f54d506c4103ba82e Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 5 Jan 2012 18:48:34 +0100 Subject: [PATCH] don't leak psi from CreateNSDeclarationIntentionFix --- .../src/com/intellij/psi/PsiAnchor.java | 2 - .../xslt/context/XsltNamespaceContext.java | 2 +- .../xslt/impl/XsltReferenceContributor.java | 3 +- .../CreateNSDeclarationIntentionFix.java | 76 +++++++++++-------- .../XmlUnboundNsPrefixInspection.java | 6 +- 5 files changed, 47 insertions(+), 42 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java index 838febb2b410..c3a4289e08e9 100644 --- a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java @@ -19,7 +19,6 @@ package com.intellij.psi; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.NullableComputable; @@ -46,7 +45,6 @@ import java.util.Set; * @author db */ public abstract class PsiAnchor { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiAnchor"); @Nullable public abstract PsiElement retrieve(); public abstract PsiFile getFile(); diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltNamespaceContext.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltNamespaceContext.java index a30b4f54aa67..38a20b6b2013 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltNamespaceContext.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/context/XsltNamespaceContext.java @@ -161,7 +161,7 @@ public class XsltNamespaceContext implements NamespaceContext { // TODO: verify API public MyCreateNSDeclarationAction(XmlElement xmlElement, String prefix, XmlFile xmlFile) { - super(xmlElement, prefix, xmlFile); + super(xmlElement, prefix); myXmlFile = xmlFile; } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java index cbb64033724d..85057da43b88 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java @@ -26,7 +26,6 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.SchemaReferencesProvider; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlFile; import com.intellij.util.ProcessingContext; import org.intellij.lang.xpath.psi.XPath2TypeElement; import org.intellij.lang.xpath.xslt.XsltSupport; @@ -97,7 +96,7 @@ public class XsltReferenceContributor { public void registerQuickfix(HighlightInfo info, PsiReference reference) { final XmlAttributeValue valueElement = myAttribute.getValueElement(); if (valueElement != null) { - QuickFixAction.registerQuickFixAction(info, new CreateNSDeclarationIntentionFix(valueElement, getCanonicalText(), (XmlFile)myAttribute.getContainingFile()) { + QuickFixAction.registerQuickFixAction(info, new CreateNSDeclarationIntentionFix(valueElement, getCanonicalText()) { @Override public boolean showHint(Editor editor) { return false; diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java index 073e4236cd69..00338d3219e2 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/CreateNSDeclarationIntentionFix.java @@ -38,6 +38,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiAnchor; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -50,6 +51,7 @@ import com.intellij.psi.xml.XmlToken; import com.intellij.ui.components.JBList; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.XmlExtension; import com.intellij.xml.impl.schema.AnyXmlElementDescriptor; @@ -73,38 +75,43 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.analysis.CreateNSDeclarationIntentionFix"); private final String myNamespacePrefix; - private final PsiElement myElement; - private final XmlFile myFile; - private final XmlToken myToken; + private final PsiAnchor myElement; + private final PsiAnchor myToken; + + @NotNull + private XmlFile getFile() { + return (XmlFile)myElement.getFile(); + } @Nullable public static CreateNSDeclarationIntentionFix createFix(@NotNull final PsiElement element, @NotNull final String namespacePrefix) { PsiFile file = element.getContainingFile(); - return file instanceof XmlFile ? new CreateNSDeclarationIntentionFix(element, namespacePrefix, (XmlFile)file) : null; + return file instanceof XmlFile ? new CreateNSDeclarationIntentionFix(element, namespacePrefix) : null; } protected CreateNSDeclarationIntentionFix(@NotNull final PsiElement element, - @NotNull final String namespacePrefix, - @NotNull XmlFile containingFile) { - this(element, namespacePrefix, null, containingFile); + @NotNull final String namespacePrefix) { + this(element, namespacePrefix, null); } - public CreateNSDeclarationIntentionFix(final PsiElement element, + public CreateNSDeclarationIntentionFix(@NotNull final PsiElement element, final String namespacePrefix, - @Nullable final XmlToken token, - @NotNull XmlFile containingFile) { + @Nullable final XmlToken token) { myNamespacePrefix = namespacePrefix; - myElement = element; - myFile = containingFile; - myToken = token; + myElement = PsiAnchor.create(element); + myToken = token == null ? null : PsiAnchor.create(token); } @NotNull public String getText() { - final String alias = StringUtil.capitalize(XmlExtension.getExtension(myFile).getNamespaceAlias(myFile)); + final String alias = StringUtil.capitalize(getXmlExtension().getNamespaceAlias(getFile())); return XmlErrorMessages.message("create.namespace.declaration.quickfix", alias); } + private XmlExtension getXmlExtension() { + return XmlExtension.getExtension(getFile()); + } + @NotNull public String getName() { return getFamilyName(); @@ -127,13 +134,15 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi } public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return myElement.isValid(); + PsiElement element = myElement.retrieve(); + return element != null && element.isValid(); } public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { - if (!myElement.isValid() || !CodeInsightUtilBase.prepareFileForWrite(file)) return; + if (!CodeInsightUtilBase.prepareFileForWrite(file)) return; - final Set set = XmlExtension.getExtension(myFile).guessUnboundNamespaces(myElement, myFile); + final PsiElement element = ObjectUtils.assertNotNull(myElement.retrieve()); + final Set set = getXmlExtension().guessUnboundNamespaces(element, getFile()); final String[] namespaces = ArrayUtil.toStringArray(set); Arrays.sort(namespaces); @@ -144,18 +153,18 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi public void doSomethingWithGivenStringToProduceXmlAttributeNowPlease(@NotNull final String namespace) throws IncorrectOperationException { String prefix = myNamespacePrefix; if (StringUtil.isEmpty(prefix)) { - final XmlExtension extension = XmlExtension.getExtension(myFile); - final XmlFile xmlFile = extension.getContainingFile(myElement); + final XmlExtension extension = getXmlExtension(); + final XmlFile xmlFile = extension.getContainingFile(element); prefix = ExtendedTagInsertHandler.getPrefixByNamespace(xmlFile, namespace); if (StringUtil.isNotEmpty(prefix)) { // namespace already declared - ExtendedTagInsertHandler.qualifyWithPrefix(prefix, myElement); + ExtendedTagInsertHandler.qualifyWithPrefix(prefix, element); return; } else { prefix = ExtendedTagInsertHandler.suggestPrefix(xmlFile, namespace); if (!StringUtil.isEmpty(prefix)) { - ExtendedTagInsertHandler.qualifyWithPrefix(prefix, myElement); + ExtendedTagInsertHandler.qualifyWithPrefix(prefix, element); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); } } @@ -177,7 +186,7 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi } private String getTitle() { - return XmlErrorMessages.message("select.namespace.title", StringUtil.capitalize(XmlExtension.getExtension(myFile).getNamespaceAlias(myFile))); + return XmlErrorMessages.message("select.namespace.title", StringUtil.capitalize(getXmlExtension().getNamespaceAlias(getFile()))); } public boolean startInWriteAction() { @@ -185,27 +194,28 @@ public class CreateNSDeclarationIntentionFix implements HintAction, LocalQuickFi } public boolean showHint(final Editor editor) { - - if (myToken == null || !myToken.isValid()) return false; - if (!XmlSettings.getInstance().SHOW_XML_ADD_IMPORT_HINTS || !myElement.isValid() || myNamespacePrefix.length() == 0) { + XmlToken token = (XmlToken)myToken.retrieve(); + if (token == null) return false; + if (!XmlSettings.getInstance().SHOW_XML_ADD_IMPORT_HINTS || myNamespacePrefix.length() == 0) { return false; } - final Set namespaces = XmlExtension.getExtension(myFile).guessUnboundNamespaces(myElement, myFile); + PsiElement element = ObjectUtils.assertNotNull(myElement.retrieve()); + final Set namespaces = getXmlExtension().guessUnboundNamespaces(element, getFile()); if (!namespaces.isEmpty()) { final String message = ShowAutoImportPass.getMessage(namespaces.size() > 1, namespaces.iterator().next()); final String title = getTitle(); - final ImportNSAction action = new ImportNSAction(namespaces, myFile, myElement, editor, title); - if (myElement instanceof XmlTag) { - if (VisibleHighlightingPassFactory.calculateVisibleRange(editor).contains(myToken.getTextRange())) { + final ImportNSAction action = new ImportNSAction(namespaces, getFile(), element, editor, title); + if (element instanceof XmlTag) { + if (VisibleHighlightingPassFactory.calculateVisibleRange(editor).contains(token.getTextRange())) { HintManager.getInstance().showQuestionHint(editor, message, - myToken.getTextOffset(), - myToken.getTextOffset() + myNamespacePrefix.length(), action); + token.getTextOffset(), + token.getTextOffset() + myNamespacePrefix.length(), action); return true; } } else { HintManager.getInstance().showQuestionHint(editor, message, - myElement.getTextOffset(), - myElement.getTextRange().getEndOffset(), action); + element.getTextOffset(), + element.getTextRange().getEndOffset(), action); return true; } } diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnboundNsPrefixInspection.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnboundNsPrefixInspection.java index 0c8ef2b2fd48..777c3acefef9 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnboundNsPrefixInspection.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlUnboundNsPrefixInspection.java @@ -141,8 +141,7 @@ public class XmlUnboundNsPrefixInspection extends XmlSuppressableInspectionTool final XmlTag tag = (XmlTag)element; if (!XmlUtil.JSP_URI.equals(tag.getNamespace())) { reportTagProblem(tag, localizedMessage, null, ProblemHighlightType.INFORMATION, - isOnTheFly ? new CreateNSDeclarationIntentionFix(context, namespacePrefix, token, - (XmlFile)context.getContainingFile()):null, + isOnTheFly ? new CreateNSDeclarationIntentionFix(context, namespacePrefix, token) : null, holder); } return; @@ -153,8 +152,7 @@ public class XmlUnboundNsPrefixInspection extends XmlSuppressableInspectionTool final HighlightInfoType infoType = extension.getHighlightInfoType(containingFile); final ProblemHighlightType highlightType = infoType == HighlightInfoType.ERROR ? ProblemHighlightType.ERROR : ProblemHighlightType.LIKE_UNKNOWN_SYMBOL; if (element instanceof XmlTag) { - final CreateNSDeclarationIntentionFix fix = isOnTheFly ? new CreateNSDeclarationIntentionFix(context, namespacePrefix, token, - (XmlFile)context.getContainingFile()):null; + final CreateNSDeclarationIntentionFix fix = isOnTheFly ? new CreateNSDeclarationIntentionFix(context, namespacePrefix, token) : null; reportTagProblem(element, localizedMessage, range, highlightType, fix, holder); } else { holder.registerProblem(element, localizedMessage, highlightType, range);