AbiVersionIndex added
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
public class AbiVersionUtil {
|
||||
public static final WritableSlice<PsiClass, Integer> ABI_VERSION_ERRORS =
|
||||
new BasicWritableSlice<PsiClass, Integer>(Slices.ONLY_REWRITE_TO_EQUAL, true);
|
||||
public static final int INVALID_VERSION = -1;
|
||||
|
||||
public static boolean isAbiVersionCompatible(int abiVersion) {
|
||||
return abiVersion == JvmAbi.VERSION;
|
||||
|
||||
@@ -215,6 +215,8 @@
|
||||
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetAnnotationsIndex" />
|
||||
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetTopLevelShortObjectNameIndex" />
|
||||
|
||||
<fileBasedIndex implementation="org.jetbrains.jet.plugin.versions.KotlinAbiVersionIndex"/>
|
||||
|
||||
<contentBasedClassFileProcessor implementation="org.jetbrains.jet.plugin.libraries.JetContentBasedFileSubstitutor" />
|
||||
<psi.clsCustomNavigationPolicy implementation="org.jetbrains.jet.plugin.libraries.JetClsNavigationPolicy" />
|
||||
<psi.clsDecompiledFileProvider implementation="org.jetbrains.jet.plugin.libraries.JetClsFileDecompiledPsiFileProvider" />
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2010-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 org.jetbrains.jet.plugin.versions;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.ExternalIntegerKeyDescriptor;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.asm4.AnnotationVisitor;
|
||||
import org.jetbrains.asm4.ClassReader;
|
||||
import org.jetbrains.asm4.ClassVisitor;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Important! This is not a stub-based index. And it has its own version
|
||||
*/
|
||||
public class KotlinAbiVersionIndex extends ScalarIndexExtension<Integer> {
|
||||
|
||||
public static final KotlinAbiVersionIndex INSTANCE = new KotlinAbiVersionIndex();
|
||||
|
||||
private static final int VERSION = 0;
|
||||
|
||||
private static final ID<Integer, Void> NAME = ID.create(KotlinAbiVersionIndex.class.getCanonicalName());
|
||||
private static final ExternalIntegerKeyDescriptor KEY_DESCRIPTOR = new ExternalIntegerKeyDescriptor();
|
||||
|
||||
private static final FileBasedIndex.InputFilter INPUT_FILTER = new FileBasedIndex.InputFilter() {
|
||||
@Override
|
||||
public boolean acceptInput(VirtualFile file) {
|
||||
return file.getFileType() == StdFileTypes.CLASS;
|
||||
}
|
||||
};
|
||||
private static final DataIndexer<Integer, Void, FileContent> INDEXER = new DataIndexer<Integer, Void, FileContent>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<Integer, Void> map(FileContent inputData) {
|
||||
final Map<Integer, Void> result = Maps.newHashMap();
|
||||
final Ref<Boolean> annotationPresent = new Ref<Boolean>(false);
|
||||
|
||||
ClassReader classReader = new ClassReader(inputData.getContent());
|
||||
classReader.accept(new ClassVisitor(Opcodes.ASM4) {
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
if (!JvmStdlibNames.JET_CLASS.getDescriptor().equals(desc) &&
|
||||
!JvmStdlibNames.JET_PACKAGE_CLASS.getDescriptor().equals(desc)) {
|
||||
return null;
|
||||
}
|
||||
annotationPresent.set(true);
|
||||
return new AnnotationVisitor(Opcodes.ASM4) {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
if (JvmStdlibNames.ABI_VERSION_NAME.equals(name)) {
|
||||
if (value instanceof Integer) {
|
||||
Integer abiVersion = (Integer) value;
|
||||
result.put(abiVersion, null);
|
||||
}
|
||||
else {
|
||||
// Version is set to something weird
|
||||
result.put(AbiVersionUtil.INVALID_VERSION, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
|
||||
if (annotationPresent.get() && result.isEmpty()) {
|
||||
// No version at all: the class is too old
|
||||
result.put(AbiVersionUtil.INVALID_VERSION, null);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
private KotlinAbiVersionIndex() {}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ID<Integer, Void> getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<Integer, Void, FileContent> getIndexer() {
|
||||
return INDEXER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDescriptor<Integer> getKeyDescriptor() {
|
||||
return KEY_DESCRIPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileBasedIndex.InputFilter getInputFilter() {
|
||||
return INPUT_FILTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dependsOnFileContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user