| /* |
| * 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.java.stubs; |
| |
| import com.intellij.lang.ASTNode; |
| import com.intellij.lang.LighterAST; |
| import com.intellij.lang.LighterASTNode; |
| import com.intellij.psi.JavaTokenType; |
| import com.intellij.psi.PsiField; |
| import com.intellij.psi.impl.cache.RecordUtil; |
| import com.intellij.psi.impl.cache.TypeInfo; |
| import com.intellij.psi.impl.java.stubs.impl.PsiFieldStubImpl; |
| import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys; |
| import com.intellij.psi.impl.source.PsiEnumConstantImpl; |
| import com.intellij.psi.impl.source.PsiFieldImpl; |
| import com.intellij.psi.impl.source.tree.ElementType; |
| import com.intellij.psi.impl.source.tree.JavaDocElementType; |
| import com.intellij.psi.impl.source.tree.JavaElementType; |
| import com.intellij.psi.impl.source.tree.LightTreeUtil; |
| import com.intellij.psi.impl.source.tree.java.EnumConstantElement; |
| import com.intellij.psi.stubs.IndexSink; |
| import com.intellij.psi.stubs.StubElement; |
| import com.intellij.psi.stubs.StubInputStream; |
| import com.intellij.psi.stubs.StubOutputStream; |
| import com.intellij.psi.tree.IElementType; |
| import com.intellij.util.io.StringRef; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.io.IOException; |
| |
| /** |
| * @author max |
| */ |
| public abstract class JavaFieldStubElementType extends JavaStubElementType<PsiFieldStub, PsiField> { |
| private static final int INITIALIZER_LENGTH_LIMIT = 1000; |
| |
| public JavaFieldStubElementType(@NotNull @NonNls final String id) { |
| super(id); |
| } |
| |
| @Override |
| public PsiField createPsi(@NotNull final PsiFieldStub stub) { |
| return getPsiFactory(stub).createField(stub); |
| } |
| |
| @Override |
| public PsiField createPsi(@NotNull final ASTNode node) { |
| if (node instanceof EnumConstantElement) { |
| return new PsiEnumConstantImpl(node); |
| } |
| else { |
| return new PsiFieldImpl(node); |
| } |
| } |
| |
| @Override |
| public PsiFieldStub createStub(final LighterAST tree, final LighterASTNode node, final StubElement parentStub) { |
| final TypeInfo typeInfo = TypeInfo.create(tree, node, parentStub); |
| |
| boolean isDeprecatedByComment = false; |
| boolean hasDeprecatedAnnotation = false; |
| String name = null; |
| String initializer = null; |
| |
| boolean expectingInit = false; |
| for (final LighterASTNode child : tree.getChildren(node)) { |
| final IElementType type = child.getTokenType(); |
| if (type == JavaDocElementType.DOC_COMMENT) { |
| isDeprecatedByComment = RecordUtil.isDeprecatedByDocComment(tree, child); |
| } |
| else if (type == JavaElementType.MODIFIER_LIST) { |
| hasDeprecatedAnnotation = RecordUtil.isDeprecatedByAnnotation(tree, child); |
| } |
| else if (type == JavaTokenType.IDENTIFIER) { |
| name = RecordUtil.intern(tree.getCharTable(), child); |
| } |
| else if (type == JavaTokenType.EQ) { |
| expectingInit = true; |
| } |
| else if (expectingInit && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(type) && type != JavaTokenType.SEMICOLON) { |
| initializer = encodeInitializer(tree, child); |
| break; |
| } |
| } |
| |
| final boolean isEnumConst = node.getTokenType() == JavaElementType.ENUM_CONSTANT; |
| final byte flags = PsiFieldStubImpl.packFlags(isEnumConst, isDeprecatedByComment, hasDeprecatedAnnotation); |
| |
| return new PsiFieldStubImpl(parentStub, name, typeInfo, initializer, flags); |
| } |
| |
| private static String encodeInitializer(final LighterAST tree, final LighterASTNode initializer) { |
| final IElementType type = initializer.getTokenType(); |
| if (type == JavaElementType.NEW_EXPRESSION || type == JavaElementType.METHOD_CALL_EXPRESSION) { |
| return PsiFieldStub.INITIALIZER_NOT_STORED; |
| } |
| |
| if (initializer.getEndOffset() - initializer.getStartOffset() > INITIALIZER_LENGTH_LIMIT) { |
| return PsiFieldStub.INITIALIZER_TOO_LONG; |
| } |
| |
| return LightTreeUtil.toFilteredString(tree, initializer, null); |
| } |
| |
| @Override |
| public void serialize(@NotNull final PsiFieldStub stub, @NotNull final StubOutputStream dataStream) throws IOException { |
| dataStream.writeName(stub.getName()); |
| TypeInfo.writeTYPE(dataStream, stub.getType(false)); |
| dataStream.writeName(stub.getInitializerText()); |
| dataStream.writeByte(((PsiFieldStubImpl)stub).getFlags()); |
| } |
| |
| @NotNull |
| @Override |
| public PsiFieldStub deserialize(@NotNull final StubInputStream dataStream, final StubElement parentStub) throws IOException { |
| final StringRef name = dataStream.readName(); |
| final TypeInfo type = TypeInfo.readTYPE(dataStream); |
| final StringRef initializerText = dataStream.readName(); |
| final byte flags = dataStream.readByte(); |
| return new PsiFieldStubImpl(parentStub, name, type, initializerText, flags); |
| } |
| |
| @Override |
| public void indexStub(@NotNull final PsiFieldStub stub, @NotNull final IndexSink sink) { |
| final String name = stub.getName(); |
| if (name != null) { |
| sink.occurrence(JavaStubIndexKeys.FIELDS, name); |
| if (RecordUtil.isStaticNonPrivateMember(stub)) { |
| sink.occurrence(JavaStubIndexKeys.JVM_STATIC_MEMBERS_NAMES, name); |
| sink.occurrence(JavaStubIndexKeys.JVM_STATIC_MEMBERS_TYPES, stub.getType(false).getShortTypeText()); |
| } |
| } |
| } |
| |
| @Override |
| public String getId(final PsiFieldStub stub) { |
| final String name = stub.getName(); |
| if (name != null) return name; |
| |
| return super.getId(stub); |
| } |
| } |