Drop external annotations from type stubs

This commit is contained in:
Roman Shevchenko
2013-03-13 10:23:19 +01:00
parent c4b34d3f26
commit bb11ce13c7
8 changed files with 64 additions and 128 deletions
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.cache;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaTokenType;
@@ -25,21 +24,22 @@ import com.intellij.psi.PsiNameHelper;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
import com.intellij.psi.impl.java.stubs.PsiClassStub;
import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.stubs.StubBase;
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.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.StringRef;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.intellij.util.BitUtil.isSet;
@@ -48,66 +48,58 @@ import static com.intellij.util.BitUtil.isSet;
* @author max
*/
public class TypeInfo {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.TypeInfo");
private static final String[] ourIndexFrequentType;
private static final TObjectIntHashMap<String> ourFrequentTypeIndex;
private static final String[] ourIndexFrequentType = new String[16];
private static final TObjectIntHashMap<String> ourFrequentTypeIndex = new TObjectIntHashMap<String>();
static {
ourIndexFrequentType = new String[]{
"",
"boolean", "byte", "char", "double", "float", "int", "long", "null", "short", "void",
"Object", CommonClassNames.JAVA_LANG_OBJECT,
"String", CommonClassNames.JAVA_LANG_STRING
};
private static void registerFrequentType(@NotNull String... typeText) {
for (int i = 0; i < typeText.length; i++) {
String type = typeText[i];
ourIndexFrequentType[i] = type;
ourFrequentTypeIndex = new TObjectIntHashMap<String>();
for (int i = 0; i < ourIndexFrequentType.length; i++) {
String type = ourIndexFrequentType[i];
ourFrequentTypeIndex.put(type, i);
}
}
static {
registerFrequentType(""
,"boolean"
,"byte"
,"char"
,"double"
,"float"
,"int"
,"long"
,"null"
,"short"
,"void"
,"Object"
,CommonClassNames.JAVA_LANG_OBJECT
,"String"
,CommonClassNames.JAVA_LANG_STRING);
}
private static final int FREQUENT_INDEX_MASK = 0x03F;
private static final int HAS_ARRAY_COUNT = 0x40;
private static final int HAS_ELLIPSIS = 0x80;
private static final int NULL_FLAGS = 0x0F;
private static final int FREQUENT_INDEX_MASK = 0x0F;
private static final int HAS_ANNOTATIONS = 0x10;
private static final int HAS_ARRAY_COUNT = 0x20;
private static final int HAS_ELLIPSIS = 0x40;
private static final TypeInfo NULL = new TypeInfo(null, (byte)0, false, Collections.<PsiAnnotationStub>emptyList());
private static final TypeInfo NULL = new TypeInfo(null, (byte)0, false, ContainerUtil.<PsiAnnotationStub>emptyList());
public final StringRef text;
public final byte arrayCount;
public final boolean isEllipsis;
private final List<PsiAnnotationStub> myAnnotationStubs;
public TypeInfo(StringRef _text, byte _arrayCount, boolean ellipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
text = _text;
arrayCount = _arrayCount;
isEllipsis = ellipsis;
myAnnotationStubs = annotationStubs;
public TypeInfo(StringRef text, byte arrayCount, boolean isEllipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
this.text = text;
this.arrayCount = arrayCount;
this.isEllipsis = isEllipsis;
this.myAnnotationStubs = annotationStubs;
}
public TypeInfo(@NotNull TypeInfo typeInfo) {
text = typeInfo.text;
arrayCount = typeInfo.arrayCount;
isEllipsis = typeInfo.isEllipsis;
myAnnotationStubs = new SmartList<PsiAnnotationStub>(typeInfo.myAnnotationStubs);
}
@NotNull
public TypeInfo applyAnnotations(@NotNull StubBase<?> owner) {
PsiModifierListStub modifierList = (PsiModifierListStub)owner.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
if (modifierList == null) return this;
public void addAnnotation(PsiAnnotationStub annotation) {
myAnnotationStubs.add(annotation);
List<PsiAnnotationStub> annotationStubs = ContainerUtil.newArrayList();
for (StubElement child : modifierList.getChildrenStubs()) {
if (!(child instanceof PsiAnnotationStub)) continue;
PsiAnnotationStub annotationStub = (PsiAnnotationStub)child;
PsiAnnotationImpl annotation = (PsiAnnotationImpl)annotationStub.getPsiElement();
if (PsiAnnotationImpl.isAnnotationApplicableTo(annotation, true, "TYPE_USE")) {
annotationStubs.add(annotationStub);
}
}
return new TypeInfo(this.text, this.arrayCount, this.isEllipsis, annotationStubs);
}
@NotNull
@@ -167,7 +159,7 @@ public class TypeInfo {
assert typeElement != null : element + " in " + parentStub;
isEllipsis = LightTreeUtil.firstChildOfType(tree, typeElement, JavaTokenType.ELLIPSIS) != null;
isEllipsis = (LightTreeUtil.firstChildOfType(tree, typeElement, JavaTokenType.ELLIPSIS) != null);
while (true) {
LighterASTNode nested = LightTreeUtil.firstChildOfType(tree, typeElement, JavaElementType.TYPE);
@@ -179,9 +171,7 @@ public class TypeInfo {
text = LightTreeUtil.toFilteredString(tree, typeElement, null);
}
List<PsiAnnotationStub> annotations = Collections.emptyList(); // todo[r.sh] JDK 8 type annotations
return new TypeInfo(StringRef.fromString(text), (byte)arrayCount, isEllipsis, annotations);
return new TypeInfo(StringRef.fromString(text), (byte)arrayCount, isEllipsis, ContainerUtil.<PsiAnnotationStub>emptyList());
}
@NotNull
@@ -196,7 +186,7 @@ public class TypeInfo {
StringRef text = StringRef.fromString(typeText);
return new TypeInfo(text, arrayCount, isEllipsis, Collections.<PsiAnnotationStub>emptyList());
return new TypeInfo(text, arrayCount, isEllipsis, ContainerUtil.<PsiAnnotationStub>emptyList());
}
@NotNull
@@ -211,66 +201,40 @@ public class TypeInfo {
}
@NotNull
public static TypeInfo readTYPE(@NotNull StubInputStream record, StubElement parentStub) throws IOException {
public static TypeInfo readTYPE(@NotNull StubInputStream record) throws IOException {
int flags = 0xFF & record.readByte();
if (flags == NULL_FLAGS) {
if (flags == FREQUENT_INDEX_MASK) {
return NULL;
}
int frequentIndex = FREQUENT_INDEX_MASK & flags;
boolean hasAnnotations = isSet(flags, HAS_ANNOTATIONS);
byte arrayCount = isSet(flags, HAS_ARRAY_COUNT) ? record.readByte() : 0;
boolean hasEllipsis = isSet(flags, HAS_ELLIPSIS);
StringRef text = frequentIndex == 0 ? record.readName() : StringRef.fromString(ourIndexFrequentType[frequentIndex]);
List<PsiAnnotationStub> annotationStubs;
if (hasAnnotations) {
int size = 0xFF & record.readByte();
annotationStubs = new ArrayList<PsiAnnotationStub>(size);
for (int i = 0; i < size; i++) {
PsiAnnotationStub annotationStub = JavaStubElementTypes.ANNOTATION.deserialize(record, parentStub);
annotationStubs.add(annotationStub);
}
}
else {
annotationStubs = Collections.emptyList();
}
return new TypeInfo(text, arrayCount, hasEllipsis, annotationStubs);
return new TypeInfo(text, arrayCount, hasEllipsis, ContainerUtil.<PsiAnnotationStub>emptyList());
}
public static void writeTYPE(@NotNull StubOutputStream dataStream, @NotNull TypeInfo typeInfo) throws IOException {
if (typeInfo == NULL) {
dataStream.writeByte(NULL_FLAGS);
dataStream.writeByte(FREQUENT_INDEX_MASK);
return;
}
boolean hasEllipsis = typeInfo.isEllipsis;
String text = typeInfo.text.getString();
byte arrayCount = typeInfo.arrayCount;
int frequentIndex = ourFrequentTypeIndex.get(text);
List<PsiAnnotationStub> annotations = typeInfo.myAnnotationStubs;
boolean hasAnnotations = !annotations.isEmpty();
int flags = (hasEllipsis ? HAS_ELLIPSIS : 0) |
(arrayCount != 0 ? HAS_ARRAY_COUNT : 0) |
(hasAnnotations ? HAS_ANNOTATIONS : 0) |
frequentIndex;
int flags = (typeInfo.isEllipsis ? HAS_ELLIPSIS : 0) | (arrayCount != 0 ? HAS_ARRAY_COUNT : 0) | frequentIndex;
dataStream.writeByte(flags);
if (arrayCount != 0) {
dataStream.writeByte(arrayCount);
}
if (frequentIndex == 0) {
dataStream.writeName(text);
}
if (hasAnnotations) {
LOG.assertTrue(annotations.size() < 256, annotations.size());
dataStream.writeByte(annotations.size());
for (PsiAnnotationStub annotation : annotations) {
dataStream.writeUTFFast(annotation.getText());
}
}
}
@Nullable
@@ -285,7 +249,7 @@ public class TypeInfo {
StringBuilder buf = new StringBuilder();
for (PsiAnnotationStub stub : typeInfo.myAnnotationStubs) {
buf.append(stub.getText()).append(" ");
buf.append(stub.getText()).append(' ');
}
buf.append(typeInfo.text.getString());
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* 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.
@@ -127,7 +127,7 @@ public abstract class JavaFieldStubElementType extends JavaStubElementType<PsiFi
@Override
public PsiFieldStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
final StringRef name = dataStream.readName();
final TypeInfo type = TypeInfo.readTYPE(dataStream, parentStub);
final TypeInfo type = TypeInfo.readTYPE(dataStream);
final StringRef initializerText = dataStream.readName();
final byte flags = dataStream.readByte();
return new PsiFieldStubImpl(parentStub, name, type, initializerText, flags);
@@ -129,7 +129,7 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
@Override
public PsiMethodStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
StringRef name = dataStream.readName();
final TypeInfo type = TypeInfo.readTYPE(dataStream, parentStub);
final TypeInfo type = TypeInfo.readTYPE(dataStream);
byte flags = dataStream.readByte();
final StringRef defaultMethodValue = PsiMethodStubImpl.isAnnotationMethod(flags) ? dataStream.readName() : null;
return new PsiMethodStubImpl(parentStub, name, type, flags, defaultMethodValue);
@@ -76,7 +76,7 @@ public abstract class JavaParameterElementType extends JavaStubElementType<PsiPa
@Override
public PsiParameterStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
StringRef name = dataStream.readName();
TypeInfo type = TypeInfo.readTYPE(dataStream, parentStub);
TypeInfo type = TypeInfo.readTYPE(dataStream);
boolean isEllipsis = dataStream.readBoolean();
return new PsiParameterStubImpl(parentStub, name, type, isEllipsis);
}
@@ -18,10 +18,7 @@ package com.intellij.psi.impl.java.stubs.impl;
import com.intellij.psi.PsiField;
import com.intellij.psi.impl.cache.TypeInfo;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
import com.intellij.psi.impl.java.stubs.PsiFieldStub;
import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
@@ -41,13 +38,12 @@ public class PsiFieldStubImpl extends StubBase<PsiField> implements PsiFieldStub
private static final int DEPRECATED = 0x02;
private static final int DEPRECATED_ANNOTATION = 0x04;
public PsiFieldStubImpl(final StubElement parent, final String name, @NotNull TypeInfo type, @Nullable String initializer, final byte flags) {
public PsiFieldStubImpl(StubElement parent, String name, @NotNull TypeInfo type, @Nullable String initializer, byte flags) {
this(parent, StringRef.fromString(name), type, StringRef.fromString(initializer), flags);
}
public PsiFieldStubImpl(final StubElement parent, final StringRef name, @NotNull TypeInfo type, final StringRef initializer, final byte flags) {
public PsiFieldStubImpl(StubElement parent, StringRef name, @NotNull TypeInfo type, @Nullable StringRef initializer, byte flags) {
super(parent, isEnumConst(flags) ? JavaStubElementTypes.ENUM_CONSTANT : JavaStubElementTypes.FIELD);
myName = name;
myType = type;
myInitializer = initializer;
@@ -57,22 +53,7 @@ public class PsiFieldStubImpl extends StubBase<PsiField> implements PsiFieldStub
@Override
@NotNull
public TypeInfo getType(boolean doResolve) {
return doResolve ? addApplicableTypeAnnotationsFromChildModifierList(this, myType) : myType;
}
public static TypeInfo addApplicableTypeAnnotationsFromChildModifierList(StubBase<?> aThis, TypeInfo type) {
PsiModifierListStub modifierList = (PsiModifierListStub)aThis.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
if (modifierList == null) return type;
TypeInfo typeInfo = new TypeInfo(type);
for (StubElement child: modifierList.getChildrenStubs()){
if (!(child instanceof PsiAnnotationStub)) continue;
PsiAnnotationStub annotationStub = (PsiAnnotationStub)child;
PsiAnnotationImpl annotation = (PsiAnnotationImpl)annotationStub.getPsiElement();
if (PsiAnnotationImpl.isAnnotationApplicableTo(annotation, true, "TYPE_USE")) {
typeInfo.addAnnotation(annotationStub);
}
}
return typeInfo;
return doResolve ? myType.applyAnnotations(this) : myType;
}
@Override
@@ -44,24 +44,15 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
private static final int DEPRECATED = 0x08;
private static final int DEPRECATED_ANNOTATION = 0x10;
public PsiMethodStubImpl(final StubElement parent,
final StringRef name,
final byte flags,
final StringRef defaultValueText) {
public PsiMethodStubImpl(StubElement parent, StringRef name, byte flags, StringRef defaultValueText) {
super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD);
myFlags = flags;
myName = name;
myDefaultValueText = defaultValueText;
}
public PsiMethodStubImpl(final StubElement parent,
final StringRef name,
final TypeInfo returnType,
final byte flags,
final StringRef defaultValueText) {
public PsiMethodStubImpl(StubElement parent, StringRef name, TypeInfo returnType, byte flags, StringRef defaultValueText) {
super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD);
myReturnType = returnType;
myFlags = flags;
myName = name;
@@ -99,7 +90,7 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
@Override
@NotNull
public TypeInfo getReturnTypeText(boolean doResolve) {
return doResolve ? PsiFieldStubImpl.addApplicableTypeAnnotationsFromChildModifierList(this, myReturnType) : myReturnType;
return doResolve ? myReturnType.applyAnnotations(this) : myReturnType;
}
@Override
@@ -60,7 +60,7 @@ public class PsiParameterStubImpl extends StubBase<PsiParameter> implements PsiP
@Override
@NotNull
public TypeInfo getType(boolean doResolve) {
return doResolve ? PsiFieldStubImpl.addApplicableTypeAnnotationsFromChildModifierList(this, myType) : myType;
return doResolve ? myType.applyAnnotations(this) : myType;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* 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.
@@ -37,7 +37,7 @@ import java.io.IOException;
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
public static final int STUB_VERSION = 15;
public static final int STUB_VERSION = 16;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);