support psi-pointers for stub elements in platform

This commit is contained in:
Dennis Ushakov
2015-02-19 11:39:51 +03:00
parent 27ac327089
commit c196467e54
9 changed files with 158 additions and 47 deletions
@@ -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;
}
}
@@ -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;
}
@@ -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;
@@ -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<SmartPointerAnchorProvider> EP_NAME = ExtensionPointName.create("com.intellij.smartPointer.anchorProvider");
@Nullable
PsiElement getAnchor(PsiElement element);
@Nullable
PsiElement getElement(PsiElement anchor);
}
@@ -276,6 +276,7 @@
<extensionPoint name="librarySettingsProvider" interface="com.intellij.openapi.roots.ui.configuration.LibrarySettingsProvider"/>
<extensionPoint name="smartPointerElementInfoFactory" interface="com.intellij.psi.impl.smartPointers.SmartPointerElementInfoFactory"/>
<extensionPoint name="smartPointer.anchorProvider" interface="com.intellij.psi.impl.smartPointers.SmartPointerAnchorProvider"/>
<extensionPoint name="elementSignatureProvider" interface="com.intellij.codeInsight.folding.impl.ElementSignatureProvider"/>
<extensionPoint name="preFormatProcessor" interface="com.intellij.psi.impl.source.codeStyle.PreFormatProcessor"/>
<extensionPoint name="postFormatProcessor" interface="com.intellij.psi.impl.source.codeStyle.PostFormatProcessor"/>
@@ -905,6 +905,7 @@
<fileIndentOptionsProvider implementation="com.intellij.psi.codeStyle.autodetect.DetectableIndentOptionsProvider" order="last"/>
<editorNotificationProvider implementation="com.intellij.psi.codeStyle.autodetect.DetectedIndentOptionsNotificationProvider"/>
<smartPointerElementInfoFactory implementation="com.intellij.psi.impl.smartPointers.AnchorElementInfoFactory"/>
</extensions>
</idea-plugin>
@@ -537,6 +537,7 @@
<applicationConfigurable groupId="tools" groupWeight="160" instance="com.intellij.ide.browsers.BrowserSettings" id="reference.settings.ide.settings.web.browsers"
key="browsers.settings" bundle="messages.IdeBundle"/>
<lang.inspectionSuppressor language="XML" implementationClass="com.intellij.codeInspection.XmlInspectionSuppressor"/>
<smartPointer.anchorProvider implementation="com.intellij.psi.impl.smartPointers.XmlAnchorProvider"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains">
<urlOpener implementation="com.intellij.ide.browsers.impl.DefaultUrlOpener" order="last"/>
+1 -1
View File
@@ -1162,7 +1162,7 @@
<smartPointerElementInfoFactory implementation="com.intellij.psi.impl.smartPointers.ImplicitVariableElementInfoFactory"/>
<smartPointerElementInfoFactory implementation="com.intellij.psi.impl.smartPointers.ImportListElementInfoFactory"/>
<smartPointerElementInfoFactory implementation="com.intellij.psi.impl.smartPointers.AnchorElementInfoFactory"/>
<smartPointer.anchorProvider implementation="com.intellij.psi.impl.smartPointers.JavaAnchorProvider"/>
<elementSignatureProvider implementation="com.intellij.codeInsight.folding.impl.JavaElementSignatureProvider"/>
@@ -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;
}
}