package com.jetbrains.lang.dart.sdk; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.lang.dart.DartProjectComponent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class DartSdk { public static final String DART_SDK_LIB_NAME = "Dart SDK"; private static final String UNKNOWN_VERSION = "unknown"; private static final Key<CachedValue<DartSdk>> CACHED_DART_SDK_KEY = Key.create("CACHED_DART_SDK_KEY"); private final @NotNull String myHomePath; private final @NotNull String myVersion; private DartSdk(@NotNull final String homePath, @NotNull final String version) { myHomePath = homePath; myVersion = version; } @NotNull public String getHomePath() { return myHomePath; } /** * @return presentable version with revision, like "1.9.1_r44672" or "1.9.0-dev.10.9_r44532" or "1.10.0-edge.44829" */ @NotNull public String getVersion() { return myVersion; } @Nullable public static DartSdk getDartSdk(@NotNull final Project project) { CachedValue<DartSdk> cachedValue = project.getUserData(CACHED_DART_SDK_KEY); if (cachedValue == null) { cachedValue = CachedValuesManager.getManager(project).createCachedValue(() -> { final DartSdk sdk = findDartSdkAmongLibraries(ProjectLibraryTable.getInstance(project).getLibraries()); if (sdk == null) { return new CachedValueProvider.Result<>(null, DartProjectComponent.getProjectRootsModificationTracker(project)); } List<Object> dependencies = new ArrayList<>(3); dependencies.add(DartProjectComponent.getProjectRootsModificationTracker(project)); ContainerUtil.addIfNotNull(dependencies, LocalFileSystem.getInstance().findFileByPath(sdk.getHomePath() + "/version")); ContainerUtil.addIfNotNull(dependencies, LocalFileSystem.getInstance().findFileByPath(sdk.getHomePath() + "/lib/core/core.dart")); return new CachedValueProvider.Result<>(sdk, ArrayUtil.toObjectArray(dependencies)); }, false); project.putUserData(CACHED_DART_SDK_KEY, cachedValue); } return cachedValue.getValue(); } @Nullable private static DartSdk findDartSdkAmongLibraries(final Library[] libs) { for (final Library library : libs) { if (DART_SDK_LIB_NAME.equals(library.getName())) { return getSdkByLibrary(library); } } return null; } @Nullable public static DartSdk getSdkByLibrary(@NotNull final Library library) { final VirtualFile[] roots = library.getFiles(OrderRootType.CLASSES); final VirtualFile dartCoreRoot = DartSdkLibraryPresentationProvider.findDartCoreRoot(Arrays.asList(roots)); if (dartCoreRoot != null) { final String homePath = dartCoreRoot.getParent().getParent().getPath(); final String version = StringUtil.notNullize(DartSdkUtil.getSdkVersion(homePath), UNKNOWN_VERSION); return new DartSdk(homePath, version); } return null; } }