mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Created compiler-module for java completion
The compiler module contains classes from android.jar (API 32)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.itsaky.androidide">
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -20,6 +20,7 @@
|
||||
package com.itsaky.androidide;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Rect;
|
||||
@@ -51,10 +52,14 @@ import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.transition.Slide;
|
||||
import androidx.transition.TransitionManager;
|
||||
|
||||
import com.blankj.utilcode.util.ClipboardUtils;
|
||||
import com.blankj.utilcode.util.FileUtils;
|
||||
import com.blankj.utilcode.util.IntentUtils;
|
||||
import com.blankj.utilcode.util.KeyboardUtils;
|
||||
import com.blankj.utilcode.util.ResourceUtils;
|
||||
import com.blankj.utilcode.util.SizeUtils;
|
||||
import com.blankj.utilcode.util.ThrowableUtils;
|
||||
import com.blankj.utilcode.util.ZipUtils;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
@@ -80,6 +85,7 @@ import com.itsaky.androidide.interfaces.DiagnosticClickListener;
|
||||
import com.itsaky.androidide.interfaces.EditorActivityProvider;
|
||||
import com.itsaky.androidide.lsp.IDELanguageClientImpl;
|
||||
import com.itsaky.androidide.managers.PreferenceManager;
|
||||
import com.itsaky.androidide.managers.ToolsManager;
|
||||
import com.itsaky.androidide.models.DiagnosticGroup;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import com.itsaky.androidide.models.SaveResult;
|
||||
@@ -93,6 +99,7 @@ import com.itsaky.androidide.shell.ShellServer;
|
||||
import com.itsaky.androidide.tasks.TaskExecutor;
|
||||
import com.itsaky.androidide.utils.DialogUtils;
|
||||
import com.itsaky.androidide.utils.EditorBottomSheetBehavior;
|
||||
import com.itsaky.androidide.utils.Environment;
|
||||
import com.itsaky.androidide.utils.LSPUtils;
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.androidide.utils.RecursiveFileSearcher;
|
||||
@@ -114,6 +121,7 @@ import com.unnamed.b.atv.model.TreeNode;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -123,6 +131,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -330,6 +339,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
super.onResume ();
|
||||
|
||||
try {
|
||||
checkForCompilerModule();
|
||||
dispatchOnResumeToEditors ();
|
||||
mFileTreeFragment.listProjectFiles ();
|
||||
} catch (Throwable th) {
|
||||
@@ -1036,6 +1046,70 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
|
||||
////////////// PRIVATE APIS /////////////////////
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings ("deprecation")
|
||||
private void checkForCompilerModule () {
|
||||
if (!Environment.isCompilerModuleInstalled ()) {
|
||||
final var pd = ProgressDialog.show (this,
|
||||
getString(R.string.title_compiler_module_install),
|
||||
getString(R.string.msg_compiler_module_install),
|
||||
true,
|
||||
false);
|
||||
|
||||
final CompletableFuture<Boolean> future = CompletableFuture.supplyAsync (() -> {
|
||||
|
||||
final var tmpModule = new File (Environment.TMP_DIR, "compiler-module.zip");
|
||||
if (!ResourceUtils.copyFileFromAssets (
|
||||
ToolsManager.getCommonAsset ("compiler-module.zip"),
|
||||
tmpModule.getAbsolutePath ())) {
|
||||
throw new CompletionException (new RuntimeException ("Unable to copy compiler-module.zip"));
|
||||
}
|
||||
|
||||
try {
|
||||
ZipUtils.unzipFile (tmpModule, Environment.COMPILER_MODULE);
|
||||
} catch (Throwable e) {
|
||||
throw new CompletionException (e);
|
||||
}
|
||||
|
||||
if (!Environment.isCompilerModuleInstalled ()) {
|
||||
throw new CompletionException (new RuntimeException ("Unknown error"));
|
||||
}
|
||||
|
||||
try {
|
||||
FileUtils.delete (tmpModule);
|
||||
} catch (Exception e) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
future.whenComplete ((result, error) -> {
|
||||
pd.dismiss ();
|
||||
|
||||
if (error != null) {
|
||||
showCompilerModuleInstallError (error);
|
||||
return;
|
||||
}
|
||||
|
||||
getApp ().toast (getString(R.string.msg_compiler_module_installed), Toaster.Type.SUCCESS);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void showCompilerModuleInstallError (Throwable error) {
|
||||
final var stacktrace = ThrowableUtils.getFullStackTrace (error);
|
||||
final var builder = DialogUtils.newMaterialDialogBuilder (this);
|
||||
builder.setTitle (R.string.title_installation_failed);
|
||||
builder.setMessage (getString(R.string.msg_compiler_module_install_failed, stacktrace));
|
||||
builder.setCancelable (false);
|
||||
builder.setPositiveButton (android.R.string.ok, (dialog, which) -> dialog.dismiss ());
|
||||
builder.setNegativeButton (R.string.copy, (dialog, which) -> {
|
||||
ClipboardUtils.copyText (stacktrace);
|
||||
dialog.dismiss ();
|
||||
});
|
||||
builder.show ();
|
||||
}
|
||||
|
||||
private void dispatchOnPauseToEditors () {
|
||||
CompletableFuture.runAsync (() -> {
|
||||
for (int i = 0; i < mViewModel.getOpenedFileCount (); i++) {
|
||||
|
||||
@@ -21,13 +21,10 @@ package com.itsaky.androidide;
|
||||
|
||||
import static com.itsaky.androidide.utils.Environment.*;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.blankj.utilcode.util.ClipboardUtils;
|
||||
@@ -41,7 +38,6 @@ import com.itsaky.androidide.fragments.sheets.ProgressSheet;
|
||||
import com.itsaky.androidide.managers.PreferenceManager;
|
||||
import com.itsaky.androidide.models.ConstantsBridge;
|
||||
import com.itsaky.androidide.utils.BootstrapInstaller;
|
||||
import com.itsaky.androidide.utils.DialogUtils;
|
||||
import com.itsaky.androidide.utils.Logger;
|
||||
import com.itsaky.androidide.utils.TypefaceUtils;
|
||||
import com.itsaky.androidide.views.virtualkeys.SpecialButton;
|
||||
@@ -62,10 +58,8 @@ import java.util.Map;
|
||||
import org.json.JSONException;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
public class TerminalActivity extends StudioActivity {
|
||||
|
||||
@@ -213,7 +207,7 @@ public class TerminalActivity extends StudioActivity {
|
||||
}
|
||||
|
||||
private TerminalSession createSession (final String workingDirectory) {
|
||||
final Map<String, String> envs = getEnvironment (true);
|
||||
final Map<String, String> envs = getEnvironment ();
|
||||
final String[] env = new String[envs.size ()];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> entry : envs.entrySet ()) {
|
||||
|
||||
@@ -350,5 +350,9 @@
|
||||
<string name="msg_reading_bootstrap">Reading bootstrap archive…</string>
|
||||
<string name="msg_bootstrap_installation_error">Bootstrap installation failed with the following exception.</string>
|
||||
<string name="title_translations">Translations</string>
|
||||
<string name="title_compiler_module_install">Installing compiler module</string>
|
||||
<string name="msg_compiler_module_install">Compiler module is being installed, please wait…</string>
|
||||
<string name="msg_compiler_module_install_failed">Compiler module installation failed. The error was:\n%s</string>
|
||||
<string name="msg_compiler_module_installed">Compiler module installed successfully!</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -116,7 +116,7 @@ public abstract class BaseApplication extends MultiDexApplication {
|
||||
ShellServer shellServer = new ShellServer(callback,
|
||||
"sh",
|
||||
Environment.mkdirIfNotExits(getRootDir()).getAbsolutePath(),
|
||||
Environment.getEnvironment(true),
|
||||
Environment.getEnvironment(),
|
||||
redirectErrors);
|
||||
shellServer.start();
|
||||
return shellServer;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ToolsManager {
|
||||
}
|
||||
|
||||
private static void extractGradlePlugin () {
|
||||
final var repoDir = new File (Environment.HOME, ".androidide");
|
||||
final var repoDir = new File (Environment.ANDROIDIDE_HOME, "repo");
|
||||
FileUtils.createOrExistsDir (repoDir);
|
||||
|
||||
final var zip = new File (Environment.TMP_DIR, "gradle-plugin.zip");
|
||||
@@ -118,7 +118,7 @@ public class ToolsManager {
|
||||
try {
|
||||
final boolean isOld = LOG_SENDER_VERSION > prefs.getInt(KEY_LOG_SENDER_VERSION, 0);
|
||||
if(isOld) {
|
||||
final File logsenderZip = new File(Environment.JLS_HOME, "logsender.zip");
|
||||
final File logsenderZip = new File(Environment.TMP_DIR, "logsender.zip");
|
||||
ResourceUtils.copyFileFromAssets(getCommonAsset("logsender.zip"), logsenderZip.getAbsolutePath());
|
||||
ZipUtils.unzipFile(logsenderZip, Environment.HOME);
|
||||
prefs.putInt(KEY_LOG_SENDER_VERSION, LOG_SENDER_VERSION);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
**************************************************************************************/
|
||||
package com.itsaky.androidide.shell;
|
||||
|
||||
import com.itsaky.androidide.utils.Environment;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -78,34 +80,14 @@ public class CommonProcessExecutor implements IProcessExecutor {
|
||||
}
|
||||
|
||||
private static File getHome() {
|
||||
try {
|
||||
final Class<?> env = CommonProcessExecutor.class.getClassLoader().loadClass("com.itsaky.androidide.utils.Environment");
|
||||
final Field home = env.getDeclaredField("HOME");
|
||||
home.setAccessible(true);
|
||||
return (File) home.get(null);
|
||||
} catch (Throwable th) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Return this if we cannot get it from Environment class
|
||||
return new File("/data/data/com.itsaky.androidide/files/framework");
|
||||
return Environment.HOME;
|
||||
}
|
||||
|
||||
private static Map<String, String> getEnv() {
|
||||
try {
|
||||
final Class<?> env = CommonProcessExecutor.class.getClassLoader().loadClass("com.itsaky.androidide.utils.Environment");
|
||||
final Method method = env.getDeclaredMethod("getEnvironment", boolean.class);
|
||||
method.setAccessible(true);
|
||||
return (Map<String, String>) method.invoke(null, true);
|
||||
} catch (Throwable th) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Return this if we cannot get it from Environment class
|
||||
return new HashMap<String, String>();
|
||||
return Environment.getEnvironment ();
|
||||
}
|
||||
|
||||
private class ExitListenerRunnable implements Runnable {
|
||||
private static class ExitListenerRunnable implements Runnable {
|
||||
|
||||
private final Process proc;
|
||||
private final IProcessExitListener listener;
|
||||
|
||||
@@ -41,9 +41,9 @@ public final class Environment {
|
||||
public static File ROOT;
|
||||
public static File SYSROOT;
|
||||
public static File HOME;
|
||||
public static File ANDROIDIDE_HOME;
|
||||
public static File JAVA_HOME;
|
||||
public static File ANDROID_HOME;
|
||||
public static File JLS_HOME;
|
||||
public static File TMP_DIR;
|
||||
public static File BIN_DIR;
|
||||
public static File LIB_DIR;
|
||||
@@ -52,9 +52,15 @@ public final class Environment {
|
||||
public static File LIB_HOOK;
|
||||
public static File LIB_HOOK2;
|
||||
|
||||
/**
|
||||
* JDK modules used by the java language server for completions.
|
||||
* This version of JDK modules contains only the classes included in
|
||||
* android.jar
|
||||
*/
|
||||
public static File COMPILER_MODULE;
|
||||
|
||||
public static File INIT_SCRIPT;
|
||||
public static File PROJECT_DATA_FILE;
|
||||
public static File JLS_JAR;
|
||||
|
||||
public static File GRADLE_PROPS;
|
||||
public static File GRADLE_USER_HOME;
|
||||
@@ -82,17 +88,17 @@ public final class Environment {
|
||||
ROOT = app.getIDEDataDir();
|
||||
SYSROOT = mkdirIfNotExits(new File(app.getIDEDataDir(), "sysroot"));
|
||||
HOME = mkdirIfNotExits(app.getRootDir());
|
||||
JLS_HOME = mkdirIfNotExits(new File(app.getIDEDataDir(), "jls"));
|
||||
ANDROIDIDE_HOME = mkdirIfNotExits (new File (HOME, ".androidide"));
|
||||
TMP_DIR = mkdirIfNotExits(new File(SYSROOT, "tmp"));
|
||||
BIN_DIR = mkdirIfNotExits(new File(SYSROOT, "bin"));
|
||||
LIB_DIR = mkdirIfNotExits(new File(SYSROOT, "lib"));
|
||||
PROJECTS_DIR = mkdirIfNotExits(new File(FileUtil.getExternalStorageDir(), PROJECTS_FOLDER));
|
||||
COMPILER_MODULE = mkdirIfNotExits (new File (ANDROIDIDE_HOME, "compiler-module"));
|
||||
|
||||
IDE_PROPS_FILE = new File(SYSROOT, "etc/ide-environment.properties");
|
||||
LIB_HOOK = new File(LIB_DIR, "libhook.so");
|
||||
LIB_HOOK2 = new File(LIB_DIR, "libhook2.so");
|
||||
PROJECT_DATA_FILE = new File(TMP_DIR, "ide_project");
|
||||
JLS_JAR = new File(JLS_HOME, "jls.jar");
|
||||
|
||||
INIT_SCRIPT = new File(mkdirIfNotExits(new File(app.getIDEDataDir(), "init")), "data/common/androidide.init.gradle");
|
||||
BOOTCLASSPATH = new File("");
|
||||
@@ -156,7 +162,7 @@ public final class Environment {
|
||||
BOOTCLASSPATH = new File(file.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static Map<String, String> getEnvironment(boolean publicUse) {
|
||||
public static Map<String, String> getEnvironment () {
|
||||
|
||||
if(!ENV_VARS.isEmpty()) {
|
||||
return ENV_VARS;
|
||||
@@ -171,11 +177,6 @@ public final class Environment {
|
||||
ENV_VARS.put("LANG", "en_US.UTF-8");
|
||||
ENV_VARS.put("LC_ALL", "en_US.UTF-8");
|
||||
|
||||
if(!publicUse) {
|
||||
// These environment variables are not supposed to be accessed by users
|
||||
ENV_VARS.put("JLS_HOME", JLS_HOME.getAbsolutePath());
|
||||
}
|
||||
|
||||
ENV_VARS.put("SYSROOT", SYSROOT.getAbsolutePath());
|
||||
|
||||
ENV_VARS.put("BUSYBOX", BUSYBOX.getAbsolutePath());
|
||||
@@ -266,6 +267,13 @@ public final class Environment {
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
public static boolean isCompilerModuleInstalled () {
|
||||
final var modules = new File (COMPILER_MODULE, "lib/modules");
|
||||
final var release = new File (COMPILER_MODULE, "release");
|
||||
return modules.exists () && modules.isFile ()
|
||||
&& release.exists () && release.isFile ();
|
||||
}
|
||||
|
||||
private static final List<String> blacklist = new ArrayList<>();
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.itsaky.javac11;
|
||||
|
||||
import com.itsaky.androidide.utils.Environment;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Javac classes read some important locations from this class file.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
public class LocationsProvider {
|
||||
|
||||
/**
|
||||
* Path of the JDK installation directory. Use by :
|
||||
* <br>
|
||||
* 1. {@link com.sun.tools.javac.file.Locations Locations} <br>
|
||||
* 2. {@link jdk.internal.jrtfs.SystemImage SystemImage}
|
||||
*/
|
||||
public static Path javaHome;
|
||||
public static Path javaLibDir;
|
||||
public static Path javaLibModules;
|
||||
|
||||
public static void init () {
|
||||
|
||||
if (Environment.JAVA_HOME == null)
|
||||
Environment.init ();
|
||||
|
||||
javaHome = Environment.JAVA_HOME.toPath ();
|
||||
javaLibDir = javaHome.resolve ("lib");
|
||||
javaLibModules = javaLibDir.resolve ("modules");
|
||||
}
|
||||
|
||||
public static Path getJavaHome () {
|
||||
return javaHome;
|
||||
}
|
||||
|
||||
public static Path getJavaLibDir () {
|
||||
return javaLibDir;
|
||||
}
|
||||
|
||||
public static Path getJavaLibModules () {
|
||||
return javaLibModules;
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public class CompileBatch implements AutoCloseable {
|
||||
|
||||
Collections.addAll (list, "-classpath", joinPath (classPath));
|
||||
Collections.addAll (list, "-source", "11", "-target", "11");
|
||||
Collections.addAll (list, "--system", Environment.JAVA_HOME.getAbsolutePath ());
|
||||
Collections.addAll (list, "--system", Environment.COMPILER_MODULE.getAbsolutePath ());
|
||||
Collections.addAll (list, "-proc:none");
|
||||
Collections.addAll (list, "-g");
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
package jdk.internal.jrtfs;
|
||||
|
||||
import com.itsaky.androidide.utils.Environment;
|
||||
import com.itsaky.javac11.LocationsProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
@@ -111,6 +110,6 @@ abstract class SystemImage {
|
||||
* otherwise the JDK home is located relative to jrt-fs.jar.
|
||||
*/
|
||||
private static String findHome() {
|
||||
return Environment.JAVA_HOME.getAbsolutePath ();
|
||||
return Environment.COMPILER_MODULE.getAbsolutePath ();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user