diff --git a/build-tools/framework-stubs/.gitignore b/build-tools/framework-stubs/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/build-tools/framework-stubs/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/build-tools/framework-stubs/build.gradle b/build-tools/framework-stubs/build.gradle new file mode 100644 index 000000000..756235ed3 --- /dev/null +++ b/build-tools/framework-stubs/build.gradle @@ -0,0 +1,29 @@ +/* + * 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 . + */ + +plugins { + id 'java-library' +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + compileOnlyApi files('libs/android.jar') +} \ No newline at end of file diff --git a/build-tools/framework-stubs/libs/android.jar b/build-tools/framework-stubs/libs/android.jar new file mode 100644 index 000000000..34f5d75c4 Binary files /dev/null and b/build-tools/framework-stubs/libs/android.jar differ diff --git a/build-tools/logger/.gitignore b/build-tools/logger/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/build-tools/logger/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/build-tools/logger/build.gradle b/build-tools/logger/build.gradle new file mode 100644 index 000000000..b98f0d4d8 --- /dev/null +++ b/build-tools/logger/build.gradle @@ -0,0 +1,29 @@ +/* + * 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 . + */ + +plugins { + id 'java-library' +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + compileOnly project(path: ':build-tools:framework-stubs') +} \ No newline at end of file diff --git a/build-tools/logger/src/main/java/com/itsaky/androidide/utils/LogUtils.java b/build-tools/logger/src/main/java/com/itsaky/androidide/utils/LogUtils.java new file mode 100644 index 000000000..8835042c5 --- /dev/null +++ b/build-tools/logger/src/main/java/com/itsaky/androidide/utils/LogUtils.java @@ -0,0 +1,101 @@ +/* + * 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 . + */ + +package com.itsaky.androidide.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * Utility class for {@link Logger}. + * + * @author Akash Yadav + */ +class LogUtils { + private static final String LINE_SEP = System.getProperty("line.separator"); + + public static String getFullStackTrace(Throwable throwable) { + final List throwableList = new ArrayList<>(); + while (throwable != null && !throwableList.contains(throwable)) { + throwableList.add(throwable); + throwable = throwable.getCause(); + } + final int size = throwableList.size(); + final List frames = new ArrayList<>(); + List nextTrace = getStackFrameList(throwableList.get(size - 1)); + for (int i = size; --i >= 0; ) { + final List trace = nextTrace; + if (i != 0) { + nextTrace = getStackFrameList(throwableList.get(i - 1)); + removeCommonFrames(trace, nextTrace); + } + if (i == size - 1) { + frames.add(throwableList.get(i).toString()); + } else { + frames.add(" Caused by: " + throwableList.get(i).toString()); + } + frames.addAll(trace); + } + StringBuilder sb = new StringBuilder(); + for (final String element : frames) { + sb.append(element).append(LINE_SEP); + } + return sb.toString(); + } + + private static List getStackFrameList(final Throwable throwable) { + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw, true); + throwable.printStackTrace(pw); + final String stackTrace = sw.toString(); + final StringTokenizer frames = new StringTokenizer(stackTrace, LINE_SEP); + final List list = new ArrayList<>(); + boolean traceStarted = false; + while (frames.hasMoreTokens()) { + final String token = frames.nextToken(); + // Determine if the line starts with at + final int at = token.indexOf("at"); + if (at != -1 && token.substring(0, at).trim().isEmpty()) { + traceStarted = true; + list.add(token); + } else if (traceStarted) { + break; + } + } + return list; + } + + private static void removeCommonFrames( + final List causeFrames, final List wrapperFrames) { + int causeFrameIndex = causeFrames.size() - 1; + int wrapperFrameIndex = wrapperFrames.size() - 1; + while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) { + // Remove the frame from the cause trace if it is the same + // as in the wrapper trace + final String causeFrame = causeFrames.get(causeFrameIndex); + final String wrapperFrame = wrapperFrames.get(wrapperFrameIndex); + if (causeFrame.equals(wrapperFrame)) { + causeFrames.remove(causeFrameIndex); + } + causeFrameIndex--; + wrapperFrameIndex--; + } + } +} diff --git a/common/src/main/java/com/itsaky/androidide/utils/Logger.java b/build-tools/logger/src/main/java/com/itsaky/androidide/utils/Logger.java old mode 100755 new mode 100644 similarity index 87% rename from common/src/main/java/com/itsaky/androidide/utils/Logger.java rename to build-tools/logger/src/main/java/com/itsaky/androidide/utils/Logger.java index 9ba5676a8..7f456aff4 --- a/common/src/main/java/com/itsaky/androidide/utils/Logger.java +++ b/build-tools/logger/src/main/java/com/itsaky/androidide/utils/Logger.java @@ -1,3 +1,20 @@ +/* + * 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 . + */ + /* * This file is part of AndroidIDE. * @@ -19,12 +36,6 @@ package com.itsaky.androidide.utils; import android.util.Log; -import androidx.annotation.NonNull; - -import com.blankj.utilcode.util.ThrowableUtils; - -import org.jetbrains.annotations.Contract; - import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -57,8 +68,6 @@ public class Logger { return instance == null ? instance = createInstance("AndroidIDE") : instance; } - @NonNull - @Contract("_ -> new") private static Logger createInstance(String tag) { return new Logger(tag); } @@ -71,14 +80,10 @@ public class Logger { logListeners.remove(Objects.requireNonNull(listener)); } - @NonNull - @Contract("_ -> new") public static Logger newInstance(String tag) { return createInstance(tag); } - @NonNull - @Contract(pure = true) public static String priorityText(int priority) { switch (priority) { case DEBUG: @@ -96,8 +101,6 @@ public class Logger { } } - @NonNull - @Contract(pure = true) public static String priorityChar(int priority) { switch (priority) { case INFO: @@ -120,7 +123,6 @@ public class Logger { return this; } - @NonNull protected String generateMessage(Object... messages) { StringBuilder sb = new StringBuilder(); if (messages == null) { @@ -130,9 +132,7 @@ public class Logger { for (Object msg : messages) { sb.append(msg instanceof Throwable ? "\n" : MSG_SEPARATOR); sb.append( - msg instanceof Throwable - ? ThrowableUtils.getFullStackTrace(((Throwable) msg)) - : msg); + msg instanceof Throwable ? LogUtils.getFullStackTrace(((Throwable) msg)) : msg); sb.append(msg instanceof Throwable ? "\n" : MSG_SEPARATOR); } diff --git a/common/build.gradle b/common/build.gradle index bfcdc99ac..2dfffc1dc 100755 --- a/common/build.gradle +++ b/common/build.gradle @@ -39,4 +39,6 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" api androidx.multidex + + api project (path: ':build-tools:logger') } diff --git a/settings.gradle b/settings.gradle index 4f8056e50..91e2c59f6 100755 --- a/settings.gradle +++ b/settings.gradle @@ -16,7 +16,9 @@ include ':lsp:xml' include ':lsp:testing' include ':build-tools' -include ':build-tools:javac' +include ':build-tools:framework-stubs' include ':build-tools:google-java-format' +include ':build-tools:javac' +include ':build-tools:logger' include ':build-tools:tooling-api' include ':build-tools:tooling-api-iml'