From 1967df4d42be442cd11e1f3adbdc3d2c075f4a0e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 30 Sep 2019 18:50:56 +0200 Subject: [PATCH] Don't store references to any classes from originating plugin in SmartPsiElementPointer GitOrigin-RevId: 18c5bf846a4bcfe7f43a9c8c6e6f4339eac617e7 --- .../src/com/intellij/psi/PsiAnchor.java | 20 ++---- .../psi/impl/smartPointers/Identikit.java | 72 +++++++++---------- .../impl/smartPointers/SelfElementInfo.java | 26 +++---- .../SmartPointerElementInfo.java | 17 +---- 4 files changed, 47 insertions(+), 88 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java index d193197ba339..f76dde59f1c4 100644 --- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2016 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi; @@ -203,7 +189,9 @@ public abstract class PsiAnchor { @Override @Nullable public PsiFile getFile() { - return SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject, myInfo.getFileLanguage()); + Language language = myInfo.getFileLanguage(); + if (language == null) return null; + return SelfElementInfo.restoreFileFromVirtual(myVirtualFile, myProject, language); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java index 1ab9e91aa36c..664728c068bd 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2016 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.impl.smartPointers; import com.google.common.base.MoreObjects; @@ -33,6 +19,8 @@ import com.intellij.util.containers.WeakInterner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + /** * @author peter */ @@ -44,7 +32,7 @@ public abstract class Identikit { @Nullable public abstract PsiElement findPsiElement(@NotNull PsiFile file, int startOffset, int endOffset); - @NotNull + @Nullable public abstract Language getFileLanguage(); public abstract boolean isForPsiFile(); @@ -69,25 +57,27 @@ public abstract class Identikit { } @NotNull - static ByType fromTypes(@NotNull Class elementClass, @Nullable IElementType elementType, @NotNull Language fileLanguage) { + static ByType fromTypes(@NotNull Class elementClass, @Nullable IElementType elementType, @NotNull Language fileLanguage) { return ourPlainInterner.intern(new ByType(elementClass, elementType, fileLanguage)); } public static class ByType extends Identikit { - private final Class myElementClass; - private final IElementType myElementType; - private final Language myFileLanguage; + private final String myElementClassName; + private final short myElementTypeId; + private final String myFileLanguageId; - private ByType(@NotNull Class elementClass, @Nullable IElementType elementType, @NotNull Language fileLanguage) { - myElementClass = elementClass; - myElementType = elementType; - myFileLanguage = fileLanguage; + private ByType(@NotNull Class elementClass, @Nullable IElementType elementType, @NotNull Language fileLanguage) { + myElementClassName = elementClass.getName(); + myElementTypeId = elementType != null ? elementType.getIndex() : -1; + myFileLanguageId = fileLanguage.getID(); } @Nullable @Override public PsiElement findPsiElement(@NotNull PsiFile file, int startOffset, int endOffset) { - Language actualLanguage = myFileLanguage != Language.ANY ? myFileLanguage : file.getViewProvider().getBaseLanguage(); + Language fileLanguage = Language.findLanguageByID(myFileLanguageId); + if (fileLanguage == null) return null; // plugin has been unloaded + Language actualLanguage = fileLanguage != Language.ANY ? fileLanguage : file.getViewProvider().getBaseLanguage(); PsiFile actualLanguagePsi = file.getViewProvider().getPsi(actualLanguage); if (actualLanguagePsi == null) { return null; // the file has changed its language or dialect, so we can't restore @@ -143,41 +133,43 @@ public abstract class Identikit { @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof ByType)) return false; - - ByType info = (ByType)o; - return myElementType == info.myElementType && myElementClass == info.myElementClass && myFileLanguage == info.myFileLanguage; + if (o == null || getClass() != o.getClass()) return false; + ByType type = (ByType)o; + return myElementTypeId == type.myElementTypeId && + Objects.equals(myElementClassName, type.myElementClassName) && + Objects.equals(myFileLanguageId, type.myFileLanguageId); } @Override public int hashCode() { - return (myElementType == null ? 0 : myElementType.hashCode() * 31 * 31) + - 31 * myElementClass.getName().hashCode() + - myFileLanguage.hashCode(); + return Objects.hash(myElementClassName, myElementTypeId, myFileLanguageId); } @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("class", myElementClass) - .add("elementType", myElementType) - .add("fileLanguage", myFileLanguage) + .add("class", myElementClassName) + .add("elementType", myElementTypeId) + .add("fileLanguage", myFileLanguageId) .toString(); } @Override - @NotNull + @Nullable public Language getFileLanguage() { - return myFileLanguage; + return Language.findLanguageByID(myFileLanguageId); } @Override public boolean isForPsiFile() { - return myElementType instanceof IFileElementType; + if (myElementTypeId < 0) return false; + IElementType elementType = IElementType.find(myElementTypeId); + return elementType instanceof IFileElementType; } private boolean isAcceptable(@NotNull PsiElement element) { - return myElementClass == element.getClass() && myElementType == PsiUtilCore.getElementType(element); + return myElementClassName.equals(element.getClass().getName()) && + myElementTypeId == PsiUtilCore.getElementType(element).getIndex(); } } @@ -219,7 +211,7 @@ public abstract class Identikit { return element != null && myElementInfo.isAcceptable(element) ? element : null; } - @NotNull + @Nullable @Override public Language getFileLanguage() { return myAnchorInfo.getFileLanguage(); diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 3084eb0850ac..4d4f07f52664 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -1,18 +1,4 @@ -/* - * 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.impl.smartPointers; import com.intellij.lang.Language; @@ -54,8 +40,11 @@ public class SelfElementInfo extends SmartPointerElementInfo { switchTo(element, findAnchor(element)); } + @Nullable private Pair findAnchor(@NotNull PsiElement element) { - return Identikit.withAnchor(element, myIdentikit.getFileLanguage()); + Language language = myIdentikit.getFileLanguage(); + if (language == null) return null; + return Identikit.withAnchor(element, language); } private void switchTo(@NotNull PsiElement element, @Nullable Pair pair) { @@ -139,8 +128,11 @@ public class SelfElementInfo extends SmartPointerElementInfo { } @Override + @Nullable PsiFile restoreFile(@NotNull SmartPointerManagerImpl manager) { - return restoreFileFromVirtual(getVirtualFile(), manager.getProject(), myIdentikit.getFileLanguage()); + Language language = myIdentikit.getFileLanguage(); + if (language == null) return null; + return restoreFileFromVirtual(getVirtualFile(), manager.getProject(), language); } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java index f076eff8b633..b5952fda3034 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerElementInfo.java @@ -1,18 +1,4 @@ -/* - * 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.impl.smartPointers; @@ -36,6 +22,7 @@ abstract class SmartPointerElementInfo { @Nullable abstract PsiElement restoreElement(@NotNull SmartPointerManagerImpl manager); + @Nullable abstract PsiFile restoreFile(@NotNull SmartPointerManagerImpl manager); abstract int elementHashCode(); // must be immutable