| /* |
| * Copyright 2000-2013 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.cache; |
| |
| import com.intellij.lang.LighterAST; |
| import com.intellij.lang.LighterASTNode; |
| import com.intellij.lang.LighterASTTokenNode; |
| import com.intellij.psi.JavaTokenType; |
| import com.intellij.psi.PsiModifier; |
| import com.intellij.psi.PsiModifierList; |
| import com.intellij.psi.impl.java.stubs.*; |
| import com.intellij.psi.impl.source.tree.JavaElementType; |
| import com.intellij.psi.impl.source.tree.LightTreeUtil; |
| import com.intellij.psi.stubs.PsiFileStub; |
| import com.intellij.psi.stubs.StubElement; |
| import com.intellij.util.CharTable; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.List; |
| |
| /** |
| * @author max |
| */ |
| public class RecordUtil { |
| @NonNls private static final String DEPRECATED_ANNOTATION_NAME = "Deprecated"; |
| @NonNls private static final String DEPRECATED_TAG = "@deprecated"; |
| |
| private RecordUtil() { } |
| |
| public static boolean isDeprecatedByAnnotation(@NotNull LighterAST tree, @NotNull LighterASTNode modList) { |
| for (final LighterASTNode child : tree.getChildren(modList)) { |
| if (child.getTokenType() == JavaElementType.ANNOTATION) { |
| final LighterASTNode ref = LightTreeUtil.firstChildOfType(tree, child, JavaElementType.JAVA_CODE_REFERENCE); |
| if (ref != null) { |
| final LighterASTNode id = LightTreeUtil.firstChildOfType(tree, ref, JavaTokenType.IDENTIFIER); |
| if (id != null) { |
| final String name = intern(tree.getCharTable(), id); |
| if (DEPRECATED_ANNOTATION_NAME.equals(name)) return true; |
| } |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| public static boolean isDeprecatedByDocComment(@NotNull LighterAST tree, @NotNull LighterASTNode comment) { |
| // todo[r.sh] parse doc comments, implement tree lookup |
| String text = LightTreeUtil.toFilteredString(tree, comment, null); |
| return text.contains(DEPRECATED_TAG); |
| } |
| |
| public static int packModifierList(@NotNull LighterAST tree, @NotNull LighterASTNode modList, @NotNull StubElement parent) { |
| int packed = 0; |
| |
| final LighterASTNode modListOwner = tree.getParent(modList); |
| if (modListOwner != null && modListOwner.getTokenType() == parent.getStubType()) { |
| final StubElement grandParent = parent.getParentStub(); |
| if (parent instanceof PsiClassStub) { |
| if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) { |
| packed |= ModifierFlags.PUBLIC_MASK; |
| packed |= ModifierFlags.STATIC_MASK; |
| } |
| if (((PsiClassStub)parent).isInterface()) { |
| packed |= ModifierFlags.ABSTRACT_MASK; |
| if (grandParent instanceof PsiClassStub) { |
| packed |= ModifierFlags.STATIC_MASK; |
| } |
| } |
| else if (((PsiClassStub)parent).isEnum()) { |
| if (!(grandParent instanceof PsiFileStub)) { |
| packed |= ModifierFlags.STATIC_MASK; |
| } |
| |
| boolean isFinal = true; |
| final List<LighterASTNode> enumConstants = LightTreeUtil.getChildrenOfType(tree, modListOwner, JavaElementType.ENUM_CONSTANT); |
| for (final LighterASTNode constant : enumConstants) { |
| if (LightTreeUtil.firstChildOfType(tree, constant, JavaElementType.ENUM_CONSTANT_INITIALIZER) != null) { |
| isFinal = false; |
| break; |
| } |
| } |
| if (isFinal) { |
| packed |= ModifierFlags.FINAL_MASK; |
| } |
| |
| final List<LighterASTNode> methods = LightTreeUtil.getChildrenOfType(tree, modListOwner, JavaElementType.METHOD); |
| for (final LighterASTNode method : methods) { |
| final LighterASTNode mods = LightTreeUtil.requiredChildOfType(tree, method, JavaElementType.MODIFIER_LIST); |
| if (LightTreeUtil.firstChildOfType(tree, mods, JavaTokenType.ABSTRACT_KEYWORD) != null) { |
| packed |= ModifierFlags.ABSTRACT_MASK; |
| break; |
| } |
| } |
| } |
| } |
| else if (parent instanceof PsiMethodStub) { |
| if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) { |
| packed |= ModifierFlags.PUBLIC_MASK; |
| packed |= ModifierFlags.ABSTRACT_MASK; |
| } |
| } |
| else if (parent instanceof PsiFieldStub) { |
| if (parent.getStubType() == JavaElementType.ENUM_CONSTANT || |
| grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) { |
| packed |= ModifierFlags.PUBLIC_MASK; |
| packed |= ModifierFlags.STATIC_MASK; |
| packed |= ModifierFlags.FINAL_MASK; |
| } |
| } |
| } |
| |
| for (final LighterASTNode child : tree.getChildren(modList)) { |
| final int flag = ModifierFlags.KEYWORD_TO_MODIFIER_FLAG_MAP.get(child.getTokenType()); |
| if (flag != 0) { |
| packed |= flag; |
| } |
| } |
| |
| if ((packed & ModifierFlags.DEFENDER_MASK) != 0) { |
| packed &= ~ModifierFlags.ABSTRACT_MASK; |
| } |
| |
| if ((packed & (ModifierFlags.PRIVATE_MASK | ModifierFlags.PROTECTED_MASK | ModifierFlags.PUBLIC_MASK)) == 0) { |
| packed |= ModifierFlags.PACKAGE_LOCAL_MASK; |
| } |
| |
| return packed; |
| } |
| |
| @NotNull |
| public static String intern(@NotNull CharTable table, @NotNull LighterASTNode node) { |
| assert node instanceof LighterASTTokenNode : node; |
| return table.intern(((LighterASTTokenNode)node).getText()).toString(); |
| } |
| |
| public static boolean isStaticNonPrivateMember(@NotNull StubElement<?> stub) { |
| StubElement<PsiModifierList> type = stub.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST); |
| if (!(type instanceof PsiModifierListStub)) { |
| return false; |
| } |
| |
| int mask = ((PsiModifierListStub)type).getModifiersMask(); |
| return ModifierFlags.hasModifierProperty(PsiModifier.STATIC, mask) && !ModifierFlags.hasModifierProperty(PsiModifier.PRIVATE, mask); |
| } |
| } |