From c196467e54e2498271462389e6d4ef01f0ebd76b Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Thu, 19 Feb 2015 11:32:12 +0300 Subject: [PATCH] support psi-pointers for stub elements in platform --- .../smartPointers/JavaAnchorProvider.java | 61 +++++++++++++++++++ .../impl/smartPointers/AnchorElementInfo.java | 22 ++----- .../AnchorElementInfoFactory.java | 37 +++-------- .../SmartPointerAnchorProvider.java | 33 ++++++++++ .../src/META-INF/LangExtensionPoints.xml | 1 + .../src/META-INF/LangExtensions.xml | 1 + .../src/META-INF/XmlPlugin.xml | 1 + resources/src/META-INF/IdeaPlugin.xml | 2 +- .../impl/smartPointers/XmlAnchorProvider.java | 47 ++++++++++++++ 9 files changed, 158 insertions(+), 47 deletions(-) create mode 100644 java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java rename {java/java-impl => platform/core-impl}/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java (87%) rename {java/java-impl => platform/core-impl}/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java (68%) create mode 100644 platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerAnchorProvider.java create mode 100644 xml/impl/src/com/intellij/psi/impl/smartPointers/XmlAnchorProvider.java diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java new file mode 100644 index 000000000000..99cf1e82073b --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/JavaAnchorProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2015 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.psi.impl.smartPointers; + +import com.intellij.lang.java.JavaLanguage; +import com.intellij.psi.*; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dennis.Ushakov + */ +public class JavaAnchorProvider implements SmartPointerAnchorProvider { + @Override + public PsiElement getAnchor(PsiElement element) { + if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { + return null; + } + + if (element instanceof PsiClass) { + if (element instanceof PsiAnonymousClass) { + return ((PsiAnonymousClass)element).getBaseClassReference().getReferenceNameElement(); + } else { + return ((PsiClass)element).getNameIdentifier(); + } + } else if (element instanceof PsiMethod) { + return ((PsiMethod)element).getNameIdentifier(); + } else if (element instanceof PsiVariable) { + return ((PsiVariable)element).getNameIdentifier(); + } + return null; + } + + @Nullable + @Override + public PsiElement getElement(PsiElement anchor) { + if (anchor instanceof PsiIdentifier) { + PsiElement parent = anchor.getParent(); + if (parent instanceof PsiJavaCodeReferenceElement) { // anonymous class, type + parent = parent.getParent(); + } + + if (!anchor.equals(AnchorElementInfoFactory.getAnchor(parent))) return null; + + return parent; + } + return null; + } +} diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java similarity index 87% rename from java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java rename to platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java index aae94191f942..e0558afcf0c5 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java @@ -19,14 +19,14 @@ import com.intellij.lang.LanguageUtil; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.psi.PsiAnchor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.PsiFileWithStubSupport; import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IStubFileElementType; -import com.intellij.psi.xml.XmlToken; -import com.intellij.psi.xml.XmlTokenType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -72,19 +72,9 @@ class AnchorElementInfo extends SelfElementInfo { TextRange range = anchor.getTextRange(); if (range.getStartOffset() != getSyncStartOffset() || range.getEndOffset() != getSyncEndOffset()) return null; - if (anchor instanceof PsiIdentifier) { - PsiElement parent = anchor.getParent(); - if (parent instanceof PsiJavaCodeReferenceElement) { // anonymous class, type - parent = parent.getParent(); - } - - if (!anchor.equals(AnchorElementInfoFactory.getAnchor(parent))) return null; - - return parent; - } - if (anchor instanceof XmlToken) { - XmlToken token = (XmlToken)anchor; - return token.getTokenType() == XmlTokenType.XML_NAME ? token.getParent() : null; + for (SmartPointerAnchorProvider provider : SmartPointerAnchorProvider.EP_NAME.getExtensions()) { + final PsiElement element = provider.getElement(anchor); + if (element != null) return element; } return null; } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java similarity index 68% rename from java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java rename to platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java index 173a7e070258..d14e4869b0e4 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfoFactory.java @@ -15,15 +15,14 @@ */ package com.intellij.psi.impl.smartPointers; -import com.intellij.lang.java.JavaLanguage; -import com.intellij.psi.*; +import com.intellij.psi.PsiAnchor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.StubBasedPsiElement; import com.intellij.psi.impl.source.PsiFileWithStubSupport; import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.stubs.StubTree; import com.intellij.psi.util.PsiUtilCore; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlToken; -import com.intellij.xml.util.XmlTagUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,33 +54,11 @@ public class AnchorElementInfoFactory implements SmartPointerElementInfoFactory @Nullable static PsiElement getAnchor(PsiElement element) { - //a hack - if (element instanceof XmlTag) { - XmlToken tagNameElement = XmlTagUtil.getStartTagNameElement((XmlTag)element); - if (tagNameElement != null && tagNameElement.isPhysical()) { - return tagNameElement; - } - } - - if (!element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { - return null; - } - PsiUtilCore.ensureValid(element); PsiElement anchor = null; - if (element instanceof PsiClass) { - if (element instanceof PsiAnonymousClass) { - anchor = ((PsiAnonymousClass)element).getBaseClassReference().getReferenceNameElement(); - } - else { - anchor = ((PsiClass)element).getNameIdentifier(); - } - } - else if (element instanceof PsiMethod) { - anchor = ((PsiMethod)element).getNameIdentifier(); - } - else if (element instanceof PsiVariable) { - anchor = ((PsiVariable)element).getNameIdentifier(); + for (SmartPointerAnchorProvider provider : SmartPointerAnchorProvider.EP_NAME.getExtensions()) { + anchor = provider.getAnchor(element); + if (anchor != null) break; } if (anchor != null && (!anchor.isPhysical() /*|| anchor.getTextRange()==null*/)) return null; return anchor; diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerAnchorProvider.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerAnchorProvider.java new file mode 100644 index 000000000000..d32aaa44fe9f --- /dev/null +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerAnchorProvider.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2015 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.psi.impl.smartPointers; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dennis.Ushakov + */ +public interface SmartPointerAnchorProvider { + ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.smartPointer.anchorProvider"); + + @Nullable + PsiElement getAnchor(PsiElement element); + + @Nullable + PsiElement getElement(PsiElement anchor); +} diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 4d09a93eb3d7..17f7ca8c11d0 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -276,6 +276,7 @@ + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 7636d5828b2e..fe22999979e2 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -905,6 +905,7 @@ + diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index 0e3d00aec614..d1d768adbddf 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -537,6 +537,7 @@ + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index e5f09680c832..333d87167237 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1162,7 +1162,7 @@ - + diff --git a/xml/impl/src/com/intellij/psi/impl/smartPointers/XmlAnchorProvider.java b/xml/impl/src/com/intellij/psi/impl/smartPointers/XmlAnchorProvider.java new file mode 100644 index 000000000000..ed05e1dd47ab --- /dev/null +++ b/xml/impl/src/com/intellij/psi/impl/smartPointers/XmlAnchorProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2015 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.psi.impl.smartPointers; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlToken; +import com.intellij.psi.xml.XmlTokenType; +import com.intellij.xml.util.XmlTagUtil; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dennis.Ushakov + */ +public class XmlAnchorProvider implements SmartPointerAnchorProvider { + @Nullable + @Override + public PsiElement getAnchor(PsiElement element) { + if (element instanceof XmlTag) { + return XmlTagUtil.getStartTagNameElement((XmlTag)element); + } + return null; + } + + @Nullable + @Override + public PsiElement getElement(PsiElement anchor) { + if (anchor instanceof XmlToken) { + XmlToken token = (XmlToken)anchor; + return token.getTokenType() == XmlTokenType.XML_NAME ? token.getParent() : null; + } + return null; + } +}