[java] improves detection of JDK version by bytecode

This commit is contained in:
Roman Shevchenko
2018-01-18 12:53:49 +01:00
parent 25f1185e44
commit 9aa0db19bc
4 changed files with 29 additions and 83 deletions
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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-2018 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.codeInsight.daemon.impl;
import com.intellij.ProjectTopics;
@@ -33,6 +19,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.ui.configuration.LibrarySourceRootDetectorUtil;
@@ -47,7 +34,6 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.compiled.ClsParsingUtil;
@@ -177,9 +163,10 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
int minor = stream.readUnsignedShort();
int major = stream.readUnsignedShort();
StringBuilder info = new StringBuilder().append("bytecode version: ").append(major).append('.').append(minor);
LanguageLevel level = ClsParsingUtil.getLanguageLevelByVersion(major);
if (level != null) {
info.append(" (").append(level == LanguageLevel.JDK_1_3 ? level.getName() + " or older" : level.getName()).append(')');
JavaSdkVersion sdkVersion = ClsParsingUtil.getJdkVersionByBytecode(major);
if (sdkVersion != null) {
int feature = sdkVersion.ordinal();
info.append(" (Java ").append(feature < 5 ? "1." : "").append(feature).append(')');
}
return info.toString();
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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-2018 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.compiled;
import com.intellij.diagnostic.PluginException;
@@ -31,6 +17,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DefaultProjectFactory;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.util.Key;
@@ -636,7 +623,8 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
String className = file.getNameWithoutExtension();
String internalName = reader.getClassName();
boolean module = internalName.equals("module-info") && BitUtil.isSet(reader.getAccess(), Opcodes.ACC_MODULE);
LanguageLevel level = ClsParsingUtil.getLanguageLevelByVersion(reader.readShort(6));
JavaSdkVersion jdkVersion = ClsParsingUtil.getJdkVersionByBytecode(reader.readShort(6));
LanguageLevel level = jdkVersion != null ? jdkVersion.getMaxLanguageLevel() : null;
if (module) {
PsiJavaFileStub stub = new PsiJavaFileStubImpl(null, "", level, true);
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// Copyright 2000-2018 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.compiled;
import com.intellij.lang.PsiBuilder;
@@ -6,6 +6,7 @@ import com.intellij.lang.java.lexer.JavaLexer;
import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -15,6 +16,7 @@ import com.intellij.psi.impl.source.JavaDummyElement;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.lang.JavaVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -163,34 +165,20 @@ public class ClsParsingUtil {
}
@Nullable
public static LanguageLevel getLanguageLevelByVersion(int major) {
switch (major) {
case Opcodes.V1_1:
case 45: // other variant of 1.1
case Opcodes.V1_2:
case Opcodes.V1_3:
return LanguageLevel.JDK_1_3;
case Opcodes.V1_4:
return LanguageLevel.JDK_1_4;
case Opcodes.V1_5:
return LanguageLevel.JDK_1_5;
case Opcodes.V1_6:
return LanguageLevel.JDK_1_6;
case Opcodes.V1_7:
return LanguageLevel.JDK_1_7;
case Opcodes.V1_8:
return LanguageLevel.JDK_1_8;
case Opcodes.V9:
return LanguageLevel.JDK_1_9;
default:
return null;
public static JavaSdkVersion getJdkVersionByBytecode(int major) {
if (major == Opcodes.V1_1 || major == 45) {
return JavaSdkVersion.JDK_1_1;
}
if (major >= 46) {
JavaVersion version = JavaVersion.compose(major - 44, 0, 0, 0, false); // 46 = 1.2, 47 = 1.3 etc.
return JavaSdkVersion.fromJavaVersion(version);
}
return null;
}
/** @deprecated use {@link #getJdkVersionByBytecode(int)} (to be removed in IDEA 2019) */
public static LanguageLevel getLanguageLevelByVersion(int major) {
JavaSdkVersion sdkVersion = getJdkVersionByBytecode(major);
return sdkVersion != null ? sdkVersion.getMaxLanguageLevel() : null;
}
}
+2 -19
View File
@@ -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-2018 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 org.jetbrains.idea.devkit.projectRoots;
import com.intellij.openapi.application.ApplicationStarter;
@@ -36,7 +22,6 @@ import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.compiled.ClsParsingUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
@@ -298,9 +283,7 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
private static JavaSdkVersion getRequiredJdkVersion(Sdk ideaSdk) {
if (isFromIDEAProject(ideaSdk.getHomePath())) return JavaSdkVersion.JDK_1_8;
File apiJar = getPlatformApiJar(ideaSdk.getHomePath());
int classFileVersion = apiJar == null ? -1 : getIdeaClassFileVersion(apiJar);
LanguageLevel languageLevel = classFileVersion <= 0? null : ClsParsingUtil.getLanguageLevelByVersion(classFileVersion);
return languageLevel != null ? JavaSdkVersion.fromLanguageLevel(languageLevel) : null;
return apiJar != null ? ClsParsingUtil.getJdkVersionByBytecode(getIdeaClassFileVersion(apiJar)) : null;
}
private static int getIdeaClassFileVersion(File apiJar) {